public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/11] Another set of nested svm fixes and optimizations
@ 2010-02-24 17:59 Joerg Roedel
  2010-02-24 17:59 ` [PATCH 01/11] KVM: SVM: Coding style cleanup Joerg Roedel
                   ` (11 more replies)
  0 siblings, 12 replies; 20+ messages in thread
From: Joerg Roedel @ 2010-02-24 17:59 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: Alexander Graf, kvm, linux-kernel

Hi,

here is another set of patches I collected in the last days while trying
to get Hyper-V running with nested svm. I was not successful yet but the
patches in this set make sense anyway :-)
The patches fix coding style issues which annoyed me for some time
because my vim shows all c-space-errors with red color. Other patches in
this set make nested svm more complete (nmi and selective cr0 related).
The vm_cr and hwcr.ignne patches are related to Hyper-V tests. This
hypervisor expects to write to those msrs.
The most interesting thing is patch 11 which reduces the amount of
memory which is touched in the vmrun emulation for merging the msrpms
from 24kb to 48 bytes.  Please review and comment (or apply if
perfect ;-) ) these patches.

Thanks,

	Joerg

diffstat:

 arch/x86/include/asm/svm.h |    4 +
 arch/x86/kvm/svm.c         |  282 +++++++++++++++++++++++++++++++-------------
 arch/x86/kvm/trace.h       |   22 ++++
 arch/x86/kvm/x86.c         |    3 +-
 4 files changed, 226 insertions(+), 85 deletions(-)

shortlog:

Joerg Roedel (11):
      KVM: SVM: Coding style cleanup
      KVM: SVM: Reset MMU on nested_svm_vmrun for NPT too
      KVM: SVM: Check for nested intercepts on NMI injection
      KVM: SVM: Restore tracing of nested vmcb address
      KVM: SVM: Add kvm_nested_intercepts tracepoint
      KVM: SVM: Implement emulation of vm_cr msr
      KVM: SVM: Ignore write of hwcr.ignne
      KVM: x86: Don't set arch.cr0 in kvm_set_cr0
      KVM: SVM: Handle nested selective_cr0 intercept correctly
      KVM: SVM: Clear exit_info for injected INTR exits
      KVM: SVM: Optimize nested svm msrpm merging

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 01/11] KVM: SVM: Coding style cleanup
  2010-02-24 17:59 [PATCH 0/11] Another set of nested svm fixes and optimizations Joerg Roedel
@ 2010-02-24 17:59 ` Joerg Roedel
  2010-02-24 18:02   ` Joerg Roedel
  2010-02-24 17:59 ` [PATCH 02/11] KVM: SVM: Reset MMU on nested_svm_vmrun for NPT too Joerg Roedel
                   ` (10 subsequent siblings)
  11 siblings, 1 reply; 20+ messages in thread
From: Joerg Roedel @ 2010-02-24 17:59 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti
  Cc: Alexander Graf, kvm, linux-kernel, Joerg Roedel

This patch removes whitespace errors, fixes comment formats
and most of checkpatch warnings. Now vim does not show
c-space-errors anymore.

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
 arch/x86/kvm/svm.c |  148 ++++++++++++++++++++++++++++-----------------------
 1 files changed, 81 insertions(+), 67 deletions(-)

diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index d11ff46..217b8b0 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -119,7 +119,7 @@ struct vcpu_svm {
 #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
 static bool npt_enabled = true;
 #else
-static bool npt_enabled = false;
+static bool npt_enabled;
 #endif
 static int npt = 1;
 
@@ -167,8 +167,8 @@ static unsigned long iopm_base;
 struct kvm_ldttss_desc {
 	u16 limit0;
 	u16 base0;
-	unsigned base1 : 8, type : 5, dpl : 2, p : 1;
-	unsigned limit1 : 4, zero0 : 3, g : 1, base2 : 8;
+	unsigned base1:8, type:5, dpl:2, p:1;
+	unsigned limit1:4, zero0:3, g:1, base2:8;
 	u32 base3;
 	u32 zero1;
 } __attribute__((packed));
@@ -217,7 +217,7 @@ static inline void stgi(void)
 
 static inline void invlpga(unsigned long addr, u32 asid)
 {
-	asm volatile (__ex(SVM_INVLPGA) :: "a"(addr), "c"(asid));
+	asm volatile (__ex(SVM_INVLPGA) : : "a"(addr), "c"(asid));
 }
 
 static inline void force_new_asid(struct kvm_vcpu *vcpu)
@@ -289,8 +289,10 @@ static void svm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
 
-	/* If we are within a nested VM we'd better #VMEXIT and let the
-	   guest handle the exception */
+	/*
+	 * If we are within a nested VM we'd better #VMEXIT and let the guest
+	 * handle the exception
+	 */
 	if (nested_svm_check_exception(svm, nr, has_error_code, error_code))
 		return;
 
@@ -543,7 +545,7 @@ static void init_seg(struct vmcb_seg *seg)
 {
 	seg->selector = 0;
 	seg->attrib = SVM_SELECTOR_P_MASK | SVM_SELECTOR_S_MASK |
-		SVM_SELECTOR_WRITE_MASK; /* Read/Write Data Segment */
+		      SVM_SELECTOR_WRITE_MASK; /* Read/Write Data Segment */
 	seg->limit = 0xffff;
 	seg->base = 0;
 }
@@ -563,16 +565,16 @@ static void init_vmcb(struct vcpu_svm *svm)
 
 	svm->vcpu.fpu_active = 1;
 
-	control->intercept_cr_read = 	INTERCEPT_CR0_MASK |
+	control->intercept_cr_read =	INTERCEPT_CR0_MASK |
 					INTERCEPT_CR3_MASK |
 					INTERCEPT_CR4_MASK;
 
-	control->intercept_cr_write = 	INTERCEPT_CR0_MASK |
+	control->intercept_cr_write =	INTERCEPT_CR0_MASK |
 					INTERCEPT_CR3_MASK |
 					INTERCEPT_CR4_MASK |
 					INTERCEPT_CR8_MASK;
 
-	control->intercept_dr_read = 	INTERCEPT_DR0_MASK |
+	control->intercept_dr_read =	INTERCEPT_DR0_MASK |
 					INTERCEPT_DR1_MASK |
 					INTERCEPT_DR2_MASK |
 					INTERCEPT_DR3_MASK |
@@ -581,7 +583,7 @@ static void init_vmcb(struct vcpu_svm *svm)
 					INTERCEPT_DR6_MASK |
 					INTERCEPT_DR7_MASK;
 
-	control->intercept_dr_write = 	INTERCEPT_DR0_MASK |
+	control->intercept_dr_write =	INTERCEPT_DR0_MASK |
 					INTERCEPT_DR1_MASK |
 					INTERCEPT_DR2_MASK |
 					INTERCEPT_DR3_MASK |
@@ -595,7 +597,7 @@ static void init_vmcb(struct vcpu_svm *svm)
 					(1 << MC_VECTOR);
 
 
-	control->intercept = 	(1ULL << INTERCEPT_INTR) |
+	control->intercept =	(1ULL << INTERCEPT_INTR) |
 				(1ULL << INTERCEPT_NMI) |
 				(1ULL << INTERCEPT_SMI) |
 				(1ULL << INTERCEPT_SELECTIVE_CR0) |
@@ -656,7 +658,8 @@ static void init_vmcb(struct vcpu_svm *svm)
 	save->rip = 0x0000fff0;
 	svm->vcpu.arch.regs[VCPU_REGS_RIP] = save->rip;
 
-	/* This is the guest-visible cr0 value.
+	/*
+	 * This is the guest-visible cr0 value.
 	 * svm_set_cr0() sets PG and WP and clears NW and CD on save->cr0.
 	 */
 	svm->vcpu.arch.cr0 = X86_CR0_NW | X86_CR0_CD | X86_CR0_ET;
@@ -897,7 +900,8 @@ static void svm_get_segment(struct kvm_vcpu *vcpu,
 	var->db = (s->attrib >> SVM_SELECTOR_DB_SHIFT) & 1;
 	var->g = (s->attrib >> SVM_SELECTOR_G_SHIFT) & 1;
 
-	/* AMD's VMCB does not have an explicit unusable field, so emulate it
+	/*
+	 * AMD's VMCB does not have an explicit unusable field, so emulate it
 	 * for cross vendor migration purposes by "not present"
 	 */
 	var->unusable = !var->present || (var->type == 0);
@@ -933,7 +937,8 @@ static void svm_get_segment(struct kvm_vcpu *vcpu,
 			var->type |= 0x1;
 		break;
 	case VCPU_SREG_SS:
-		/* On AMD CPUs sometimes the DB bit in the segment
+		/*
+		 * On AMD CPUs sometimes the DB bit in the segment
 		 * descriptor is left as 1, although the whole segment has
 		 * been made unusable. Clear it here to pass an Intel VMX
 		 * entry check when cross vendor migrating.
@@ -1264,7 +1269,7 @@ static int db_interception(struct vcpu_svm *svm)
 	}
 
 	if (svm->vcpu.guest_debug &
-	    (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP)){
+	    (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP)) {
 		kvm_run->exit_reason = KVM_EXIT_DEBUG;
 		kvm_run->debug.arch.pc =
 			svm->vmcb->save.cs.base + svm->vmcb->save.rip;
@@ -1309,7 +1314,7 @@ static void svm_fpu_activate(struct kvm_vcpu *vcpu)
 		excp    = h_excp | n_excp;
 	} else {
 		excp  = svm->vmcb->control.intercept_exceptions;
-	        excp &= ~(1 << NM_VECTOR);
+		excp &= ~(1 << NM_VECTOR);
 	}
 
 	svm->vmcb->control.intercept_exceptions = excp;
@@ -1548,13 +1553,13 @@ static int nested_svm_exit_special(struct vcpu_svm *svm)
 	case SVM_EXIT_INTR:
 	case SVM_EXIT_NMI:
 		return NESTED_EXIT_HOST;
-		/* For now we are always handling NPFs when using them */
 	case SVM_EXIT_NPF:
+		/* For now we are always handling NPFs when using them */
 		if (npt_enabled)
 			return NESTED_EXIT_HOST;
 		break;
-	/* When we're shadowing, trap PFs */
 	case SVM_EXIT_EXCP_BASE + PF_VECTOR:
+		/* When we're shadowing, trap PFs */
 		if (!npt_enabled)
 			return NESTED_EXIT_HOST;
 		break;
@@ -1789,7 +1794,7 @@ static bool nested_svm_vmrun_msrpm(struct vcpu_svm *svm)
 	if (!nested_msrpm)
 		return false;
 
-	for (i=0; i< PAGE_SIZE * (1 << MSRPM_ALLOC_ORDER) / 4; i++)
+	for (i = 0; i < PAGE_SIZE * (1 << MSRPM_ALLOC_ORDER) / 4; i++)
 		svm->nested.msrpm[i] = svm->msrpm[i] | nested_msrpm[i];
 
 	svm->vmcb->control.msrpm_base_pa = __pa(svm->nested.msrpm);
@@ -1823,8 +1828,10 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm)
 	kvm_clear_exception_queue(&svm->vcpu);
 	kvm_clear_interrupt_queue(&svm->vcpu);
 
-	/* Save the old vmcb, so we don't need to pick what we save, but
-	   can restore everything when a VMEXIT occurs */
+	/*
+	 * Save the old vmcb, so we don't need to pick what we save, but can
+	 * restore everything when a VMEXIT occurs
+	 */
 	hsave->save.es     = vmcb->save.es;
 	hsave->save.cs     = vmcb->save.cs;
 	hsave->save.ss     = vmcb->save.ss;
@@ -1872,6 +1879,7 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm)
 	kvm_register_write(&svm->vcpu, VCPU_REGS_RAX, nested_vmcb->save.rax);
 	kvm_register_write(&svm->vcpu, VCPU_REGS_RSP, nested_vmcb->save.rsp);
 	kvm_register_write(&svm->vcpu, VCPU_REGS_RIP, nested_vmcb->save.rip);
+
 	/* In case we don't even reach vcpu_run, the fields are not updated */
 	svm->vmcb->save.rax = nested_vmcb->save.rax;
 	svm->vmcb->save.rsp = nested_vmcb->save.rsp;
@@ -1903,8 +1911,10 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm)
 		svm->vmcb->control.intercept_cr_write &= ~INTERCEPT_CR8_MASK;
 	}
 
-	/* We don't want a nested guest to be more powerful than the guest,
-	   so all intercepts are ORed */
+	/*
+	 * We don't want a nested guest to be more powerful than the guest, so
+	 * all intercepts are ORed
+	 */
 	svm->vmcb->control.intercept_cr_read |=
 		nested_vmcb->control.intercept_cr_read;
 	svm->vmcb->control.intercept_cr_write |=
@@ -2218,9 +2228,11 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data)
 	case MSR_IA32_SYSENTER_ESP:
 		*data = svm->sysenter_esp;
 		break;
-	/* Nobody will change the following 5 values in the VMCB so
-	   we can safely return them on rdmsr. They will always be 0
-	   until LBRV is implemented. */
+	/*
+	 * Nobody will change the following 5 values in the VMCB so we can
+	 * safely return them on rdmsr. They will always be 0 until LBRV is
+	 * implemented.
+	 */
 	case MSR_IA32_DEBUGCTLMSR:
 		*data = svm->vmcb->save.dbgctl;
 		break;
@@ -2399,16 +2411,16 @@ static int pause_interception(struct vcpu_svm *svm)
 }
 
 static int (*svm_exit_handlers[])(struct vcpu_svm *svm) = {
-	[SVM_EXIT_READ_CR0]           		= emulate_on_interception,
-	[SVM_EXIT_READ_CR3]           		= emulate_on_interception,
-	[SVM_EXIT_READ_CR4]           		= emulate_on_interception,
-	[SVM_EXIT_READ_CR8]           		= emulate_on_interception,
+	[SVM_EXIT_READ_CR0]			= emulate_on_interception,
+	[SVM_EXIT_READ_CR3]			= emulate_on_interception,
+	[SVM_EXIT_READ_CR4]			= emulate_on_interception,
+	[SVM_EXIT_READ_CR8]			= emulate_on_interception,
 	[SVM_EXIT_CR0_SEL_WRITE]		= emulate_on_interception,
-	[SVM_EXIT_WRITE_CR0]          		= emulate_on_interception,
-	[SVM_EXIT_WRITE_CR3]          		= emulate_on_interception,
-	[SVM_EXIT_WRITE_CR4]          		= emulate_on_interception,
-	[SVM_EXIT_WRITE_CR8]          		= cr8_write_interception,
-	[SVM_EXIT_READ_DR0] 			= emulate_on_interception,
+	[SVM_EXIT_WRITE_CR0]			= emulate_on_interception,
+	[SVM_EXIT_WRITE_CR3]			= emulate_on_interception,
+	[SVM_EXIT_WRITE_CR4]			= emulate_on_interception,
+	[SVM_EXIT_WRITE_CR8]			= cr8_write_interception,
+	[SVM_EXIT_READ_DR0]			= emulate_on_interception,
 	[SVM_EXIT_READ_DR1]			= emulate_on_interception,
 	[SVM_EXIT_READ_DR2]			= emulate_on_interception,
 	[SVM_EXIT_READ_DR3]			= emulate_on_interception,
@@ -2427,15 +2439,14 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm) = {
 	[SVM_EXIT_EXCP_BASE + DB_VECTOR]	= db_interception,
 	[SVM_EXIT_EXCP_BASE + BP_VECTOR]	= bp_interception,
 	[SVM_EXIT_EXCP_BASE + UD_VECTOR]	= ud_interception,
-	[SVM_EXIT_EXCP_BASE + PF_VECTOR] 	= pf_interception,
-	[SVM_EXIT_EXCP_BASE + NM_VECTOR] 	= nm_interception,
-	[SVM_EXIT_EXCP_BASE + MC_VECTOR] 	= mc_interception,
-	[SVM_EXIT_INTR] 			= intr_interception,
+	[SVM_EXIT_EXCP_BASE + PF_VECTOR]	= pf_interception,
+	[SVM_EXIT_EXCP_BASE + NM_VECTOR]	= nm_interception,
+	[SVM_EXIT_EXCP_BASE + MC_VECTOR]	= mc_interception,
+	[SVM_EXIT_INTR]				= intr_interception,
 	[SVM_EXIT_NMI]				= nmi_interception,
 	[SVM_EXIT_SMI]				= nop_on_interception,
 	[SVM_EXIT_INIT]				= nop_on_interception,
 	[SVM_EXIT_VINTR]			= interrupt_window_interception,
-	/* [SVM_EXIT_CR0_SEL_WRITE]		= emulate_on_interception, */
 	[SVM_EXIT_CPUID]			= cpuid_interception,
 	[SVM_EXIT_IRET]                         = iret_interception,
 	[SVM_EXIT_INVD]                         = emulate_on_interception,
@@ -2443,7 +2454,7 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm) = {
 	[SVM_EXIT_HLT]				= halt_interception,
 	[SVM_EXIT_INVLPG]			= invlpg_interception,
 	[SVM_EXIT_INVLPGA]			= invlpga_interception,
-	[SVM_EXIT_IOIO] 		  	= io_interception,
+	[SVM_EXIT_IOIO]				= io_interception,
 	[SVM_EXIT_MSR]				= msr_interception,
 	[SVM_EXIT_TASK_SWITCH]			= task_switch_interception,
 	[SVM_EXIT_SHUTDOWN]			= shutdown_interception,
@@ -2644,10 +2655,12 @@ static void enable_irq_window(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
 
-	/* In case GIF=0 we can't rely on the CPU to tell us when
-	 * GIF becomes 1, because that's a separate STGI/VMRUN intercept.
-	 * The next time we get that intercept, this function will be
-	 * called again though and we'll get the vintr intercept. */
+	/*
+	 * In case GIF=0 we can't rely on the CPU to tell us when GIF becomes
+	 * 1, because that's a separate STGI/VMRUN intercept.  The next time we
+	 * get that intercept, this function will be called again though and
+	 * we'll get the vintr intercept.
+	 */
 	if (gif_set(svm) && nested_svm_intr(svm)) {
 		svm_set_vintr(svm);
 		svm_inject_irq(svm, 0x0);
@@ -2662,9 +2675,10 @@ static void enable_nmi_window(struct kvm_vcpu *vcpu)
 	    == HF_NMI_MASK)
 		return; /* IRET will cause a vm exit */
 
-	/* Something prevents NMI from been injected. Single step over
-	   possible problem (IRET or exception injection or interrupt
-	   shadow) */
+	/*
+	 * Something prevents NMI from been injected. Single step over possible
+	 * problem (IRET or exception injection or interrupt shadow)
+	 */
 	svm->nmi_singlestep = true;
 	svm->vmcb->save.rflags |= (X86_EFLAGS_TF | X86_EFLAGS_RF);
 	update_db_intercept(vcpu);
@@ -2972,24 +2986,24 @@ static void svm_cpuid_update(struct kvm_vcpu *vcpu)
 }
 
 static const struct trace_print_flags svm_exit_reasons_str[] = {
-	{ SVM_EXIT_READ_CR0,           		"read_cr0" },
-	{ SVM_EXIT_READ_CR3,	      		"read_cr3" },
-	{ SVM_EXIT_READ_CR4,	      		"read_cr4" },
-	{ SVM_EXIT_READ_CR8,  	      		"read_cr8" },
-	{ SVM_EXIT_WRITE_CR0,          		"write_cr0" },
-	{ SVM_EXIT_WRITE_CR3,	      		"write_cr3" },
-	{ SVM_EXIT_WRITE_CR4,          		"write_cr4" },
-	{ SVM_EXIT_WRITE_CR8, 	      		"write_cr8" },
-	{ SVM_EXIT_READ_DR0, 	      		"read_dr0" },
-	{ SVM_EXIT_READ_DR1,	      		"read_dr1" },
-	{ SVM_EXIT_READ_DR2,	      		"read_dr2" },
-	{ SVM_EXIT_READ_DR3,	      		"read_dr3" },
-	{ SVM_EXIT_WRITE_DR0,	      		"write_dr0" },
-	{ SVM_EXIT_WRITE_DR1,	      		"write_dr1" },
-	{ SVM_EXIT_WRITE_DR2,	      		"write_dr2" },
-	{ SVM_EXIT_WRITE_DR3,	      		"write_dr3" },
-	{ SVM_EXIT_WRITE_DR5,	      		"write_dr5" },
-	{ SVM_EXIT_WRITE_DR7,	      		"write_dr7" },
+	{ SVM_EXIT_READ_CR0,			"read_cr0" },
+	{ SVM_EXIT_READ_CR3,			"read_cr3" },
+	{ SVM_EXIT_READ_CR4,			"read_cr4" },
+	{ SVM_EXIT_READ_CR8,			"read_cr8" },
+	{ SVM_EXIT_WRITE_CR0,			"write_cr0" },
+	{ SVM_EXIT_WRITE_CR3,			"write_cr3" },
+	{ SVM_EXIT_WRITE_CR4,			"write_cr4" },
+	{ SVM_EXIT_WRITE_CR8,			"write_cr8" },
+	{ SVM_EXIT_READ_DR0,			"read_dr0" },
+	{ SVM_EXIT_READ_DR1,			"read_dr1" },
+	{ SVM_EXIT_READ_DR2,			"read_dr2" },
+	{ SVM_EXIT_READ_DR3,			"read_dr3" },
+	{ SVM_EXIT_WRITE_DR0,			"write_dr0" },
+	{ SVM_EXIT_WRITE_DR1,			"write_dr1" },
+	{ SVM_EXIT_WRITE_DR2,			"write_dr2" },
+	{ SVM_EXIT_WRITE_DR3,			"write_dr3" },
+	{ SVM_EXIT_WRITE_DR5,			"write_dr5" },
+	{ SVM_EXIT_WRITE_DR7,			"write_dr7" },
 	{ SVM_EXIT_EXCP_BASE + DB_VECTOR,	"DB excp" },
 	{ SVM_EXIT_EXCP_BASE + BP_VECTOR,	"BP excp" },
 	{ SVM_EXIT_EXCP_BASE + UD_VECTOR,	"UD excp" },
-- 
1.7.0



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 02/11] KVM: SVM: Reset MMU on nested_svm_vmrun for NPT too
  2010-02-24 17:59 [PATCH 0/11] Another set of nested svm fixes and optimizations Joerg Roedel
  2010-02-24 17:59 ` [PATCH 01/11] KVM: SVM: Coding style cleanup Joerg Roedel
@ 2010-02-24 17:59 ` Joerg Roedel
  2010-02-24 17:59 ` [PATCH 03/11] KVM: SVM: Check for nested intercepts on NMI injection Joerg Roedel
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Joerg Roedel @ 2010-02-24 17:59 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti
  Cc: Alexander Graf, kvm, linux-kernel, Joerg Roedel

Without resetting the MMU the gva_to_pga function will not
work reliably when the vcpu is running in nested context.

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
 arch/x86/kvm/svm.c |    8 +++++---
 1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 217b8b0..b821b2f 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -1871,10 +1871,12 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm)
 	if (npt_enabled) {
 		svm->vmcb->save.cr3 = nested_vmcb->save.cr3;
 		svm->vcpu.arch.cr3 = nested_vmcb->save.cr3;
-	} else {
+	} else
 		kvm_set_cr3(&svm->vcpu, nested_vmcb->save.cr3);
-		kvm_mmu_reset_context(&svm->vcpu);
-	}
+
+	/* Guest paging mode is active - reset mmu */
+	kvm_mmu_reset_context(&svm->vcpu);
+
 	svm->vmcb->save.cr2 = svm->vcpu.arch.cr2 = nested_vmcb->save.cr2;
 	kvm_register_write(&svm->vcpu, VCPU_REGS_RAX, nested_vmcb->save.rax);
 	kvm_register_write(&svm->vcpu, VCPU_REGS_RSP, nested_vmcb->save.rsp);
-- 
1.7.0

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 03/11] KVM: SVM: Check for nested intercepts on NMI injection
  2010-02-24 17:59 [PATCH 0/11] Another set of nested svm fixes and optimizations Joerg Roedel
  2010-02-24 17:59 ` [PATCH 01/11] KVM: SVM: Coding style cleanup Joerg Roedel
  2010-02-24 17:59 ` [PATCH 02/11] KVM: SVM: Reset MMU on nested_svm_vmrun for NPT too Joerg Roedel
@ 2010-02-24 17:59 ` Joerg Roedel
  2010-02-24 17:59 ` [PATCH 04/11] KVM: SVM: Restore tracing of nested vmcb address Joerg Roedel
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Joerg Roedel @ 2010-02-24 17:59 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti
  Cc: Alexander Graf, kvm, linux-kernel, Joerg Roedel

This patch implements the NMI intercept checking for nested
svm.

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
 arch/x86/kvm/svm.c |   22 +++++++++++++++++++---
 1 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index b821b2f..9759d9f 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -1480,6 +1480,20 @@ static inline bool nested_svm_intr(struct vcpu_svm *svm)
 	return true;
 }
 
+/* This function returns true if it is save to enable the nmi window */
+static inline bool nested_svm_nmi(struct vcpu_svm *svm)
+{
+	if (!is_nested(svm))
+		return true;
+
+	if (!(svm->nested.intercept & (1ULL << INTERCEPT_NMI)))
+		return true;
+
+	svm->vmcb->control.exit_code = SVM_EXIT_NMI;
+	svm->nested.exit_required = true;
+
+	return false;
+}
 static void *nested_svm_map(struct vcpu_svm *svm, u64 gpa, struct page **_page)
 {
 	struct page *page;
@@ -2681,9 +2695,11 @@ static void enable_nmi_window(struct kvm_vcpu *vcpu)
 	 * Something prevents NMI from been injected. Single step over possible
 	 * problem (IRET or exception injection or interrupt shadow)
 	 */
-	svm->nmi_singlestep = true;
-	svm->vmcb->save.rflags |= (X86_EFLAGS_TF | X86_EFLAGS_RF);
-	update_db_intercept(vcpu);
+	if (gif_set(svm) && nested_svm_nmi(svm)) {
+		svm->nmi_singlestep = true;
+		svm->vmcb->save.rflags |= (X86_EFLAGS_TF | X86_EFLAGS_RF);
+		update_db_intercept(vcpu);
+	}
 }
 
 static int svm_set_tss_addr(struct kvm *kvm, unsigned int addr)
-- 
1.7.0



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 04/11] KVM: SVM: Restore tracing of nested vmcb address
  2010-02-24 17:59 [PATCH 0/11] Another set of nested svm fixes and optimizations Joerg Roedel
                   ` (2 preceding siblings ...)
  2010-02-24 17:59 ` [PATCH 03/11] KVM: SVM: Check for nested intercepts on NMI injection Joerg Roedel
@ 2010-02-24 17:59 ` Joerg Roedel
  2010-02-24 17:59 ` [PATCH 05/11] KVM: SVM: Add kvm_nested_intercepts tracepoint Joerg Roedel
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Joerg Roedel @ 2010-02-24 17:59 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti
  Cc: Alexander Graf, kvm, linux-kernel, Joerg Roedel

A recent change broke tracing of the nested vmcb address. It
was reported as 0 all the time. This patch fixes it.

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
 arch/x86/kvm/svm.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 9759d9f..b048c2b 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -1832,7 +1832,7 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm)
 	if (!nested_vmcb)
 		return false;
 
-	trace_kvm_nested_vmrun(svm->vmcb->save.rip - 3, svm->nested.vmcb,
+	trace_kvm_nested_vmrun(svm->vmcb->save.rip - 3, vmcb_gpa,
 			       nested_vmcb->save.rip,
 			       nested_vmcb->control.int_ctl,
 			       nested_vmcb->control.event_inj,
-- 
1.7.0



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 05/11] KVM: SVM: Add kvm_nested_intercepts tracepoint
  2010-02-24 17:59 [PATCH 0/11] Another set of nested svm fixes and optimizations Joerg Roedel
                   ` (3 preceding siblings ...)
  2010-02-24 17:59 ` [PATCH 04/11] KVM: SVM: Restore tracing of nested vmcb address Joerg Roedel
@ 2010-02-24 17:59 ` Joerg Roedel
  2010-02-24 17:59 ` [PATCH 06/11] KVM: SVM: Implement emulation of vm_cr msr Joerg Roedel
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Joerg Roedel @ 2010-02-24 17:59 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti
  Cc: Alexander Graf, kvm, linux-kernel, Joerg Roedel

This patch adds a tracepoint to get information about the
most important intercept bitmasks from the nested vmcb.

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
 arch/x86/kvm/svm.c   |    5 +++++
 arch/x86/kvm/trace.h |   22 ++++++++++++++++++++++
 arch/x86/kvm/x86.c   |    1 +
 3 files changed, 28 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index b048c2b..6b7590a 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -1838,6 +1838,11 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm)
 			       nested_vmcb->control.event_inj,
 			       nested_vmcb->control.nested_ctl);
 
+	trace_kvm_nested_intercepts(nested_vmcb->control.intercept_cr_read,
+				    nested_vmcb->control.intercept_cr_write,
+				    nested_vmcb->control.intercept_exceptions,
+				    nested_vmcb->control.intercept);
+
 	/* Clear internal status */
 	kvm_clear_exception_queue(&svm->vcpu);
 	kvm_clear_interrupt_queue(&svm->vcpu);
diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h
index 12f8d2d..17b52cc 100644
--- a/arch/x86/kvm/trace.h
+++ b/arch/x86/kvm/trace.h
@@ -419,6 +419,28 @@ TRACE_EVENT(kvm_nested_vmrun,
 		__entry->npt ? "on" : "off")
 );
 
+TRACE_EVENT(kvm_nested_intercepts,
+	    TP_PROTO(__u16 cr_read, __u16 cr_write, __u32 exceptions, __u64 intercept),
+	    TP_ARGS(cr_read, cr_write, exceptions, intercept),
+
+	TP_STRUCT__entry(
+		__field(	__u16,		cr_read		)
+		__field(	__u16,		cr_write	)
+		__field(	__u32,		exceptions	)
+		__field(	__u64,		intercept	)
+	),
+
+	TP_fast_assign(
+		__entry->cr_read	= cr_read;
+		__entry->cr_write	= cr_write;
+		__entry->exceptions	= exceptions;
+		__entry->intercept	= intercept;
+	),
+
+	TP_printk("cr_read: %04x cr_write: %04x excp: %08x intercept: %016llx",
+		__entry->cr_read, __entry->cr_write, __entry->exceptions,
+		__entry->intercept)
+);
 /*
  * Tracepoint for #VMEXIT while nested
  */
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 7b436c8..2c24cb5 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -5924,3 +5924,4 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_nested_vmexit_inject);
 EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_nested_intr_vmexit);
 EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_invlpga);
 EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_skinit);
+EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_nested_intercepts);
-- 
1.7.0

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 06/11] KVM: SVM: Implement emulation of vm_cr msr
  2010-02-24 17:59 [PATCH 0/11] Another set of nested svm fixes and optimizations Joerg Roedel
                   ` (4 preceding siblings ...)
  2010-02-24 17:59 ` [PATCH 05/11] KVM: SVM: Add kvm_nested_intercepts tracepoint Joerg Roedel
@ 2010-02-24 17:59 ` Joerg Roedel
  2010-02-25 10:28   ` Avi Kivity
  2010-02-24 17:59 ` [PATCH 07/11] KVM: SVM: Ignore write of hwcr.ignne Joerg Roedel
                   ` (5 subsequent siblings)
  11 siblings, 1 reply; 20+ messages in thread
From: Joerg Roedel @ 2010-02-24 17:59 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti
  Cc: Alexander Graf, kvm, linux-kernel, Joerg Roedel

This patch implements the emulation of the vm_cr msr for
nested svm.

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
 arch/x86/include/asm/svm.h |    4 ++++
 arch/x86/kvm/svm.c         |   29 ++++++++++++++++++++++++++++-
 2 files changed, 32 insertions(+), 1 deletions(-)

diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h
index 38638cd..b26a38d 100644
--- a/arch/x86/include/asm/svm.h
+++ b/arch/x86/include/asm/svm.h
@@ -115,6 +115,10 @@ struct __attribute__ ((__packed__)) vmcb_control_area {
 #define SVM_IOIO_SIZE_MASK (7 << SVM_IOIO_SIZE_SHIFT)
 #define SVM_IOIO_ASIZE_MASK (7 << SVM_IOIO_ASIZE_SHIFT)
 
+#define SVM_VM_CR_VALID_MASK	0x001fULL
+#define SVM_VM_CR_SVM_LOCK_MASK 0x0008ULL
+#define SVM_VM_CR_SVM_DIS_MASK  0x0010ULL
+
 struct __attribute__ ((__packed__)) vmcb_seg {
 	u16 selector;
 	u16 attrib;
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 6b7590a..2450a7c 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -70,6 +70,7 @@ struct kvm_vcpu;
 struct nested_state {
 	struct vmcb *hsave;
 	u64 hsave_msr;
+	u64 vm_cr_msr;
 	u64 vmcb;
 
 	/* These are the merged vectors */
@@ -2273,7 +2274,7 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data)
 		*data = svm->nested.hsave_msr;
 		break;
 	case MSR_VM_CR:
-		*data = 0;
+		*data = svm->nested.vm_cr_msr;
 		break;
 	case MSR_IA32_UCODE_REV:
 		*data = 0x01000065;
@@ -2303,6 +2304,31 @@ static int rdmsr_interception(struct vcpu_svm *svm)
 	return 1;
 }
 
+static int svm_set_vm_cr(struct kvm_vcpu *vcpu, u64 data)
+{
+	struct vcpu_svm *svm = to_svm(vcpu);
+	int svm_dis, chg_mask;
+
+	if (data & ~SVM_VM_CR_VALID_MASK)
+		return 1;
+
+	chg_mask = SVM_VM_CR_VALID_MASK;
+
+	if (svm->nested.vm_cr_msr & SVM_VM_CR_SVM_DIS_MASK)
+		chg_mask &= ~(SVM_VM_CR_SVM_LOCK_MASK | SVM_VM_CR_SVM_DIS_MASK);
+
+	svm->nested.vm_cr_msr &= ~chg_mask;
+	svm->nested.vm_cr_msr |= (data & chg_mask);
+
+	svm_dis = svm->nested.vm_cr_msr & SVM_VM_CR_SVM_DIS_MASK;
+
+	/* check for svm_disable while efer.svme is set */
+	if (svm_dis && (vcpu->arch.efer & EFER_SVME))
+		return 1;
+
+	return 0;
+}
+
 static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data)
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
@@ -2369,6 +2395,7 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data)
 		svm->nested.hsave_msr = data;
 		break;
 	case MSR_VM_CR:
+		return svm_set_vm_cr(vcpu, data);
 	case MSR_VM_IGNNE:
 		pr_unimpl(vcpu, "unimplemented wrmsr: 0x%x data 0x%llx\n", ecx, data);
 		break;
-- 
1.7.0



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 07/11] KVM: SVM: Ignore write of hwcr.ignne
  2010-02-24 17:59 [PATCH 0/11] Another set of nested svm fixes and optimizations Joerg Roedel
                   ` (5 preceding siblings ...)
  2010-02-24 17:59 ` [PATCH 06/11] KVM: SVM: Implement emulation of vm_cr msr Joerg Roedel
@ 2010-02-24 17:59 ` Joerg Roedel
  2010-02-24 17:59 ` [PATCH 08/11] KVM: x86: Don't set arch.cr0 in kvm_set_cr0 Joerg Roedel
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Joerg Roedel @ 2010-02-24 17:59 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti
  Cc: Alexander Graf, kvm, linux-kernel, Joerg Roedel

Hyper-V as a guest wants to write this bit. This patch
ignores it.

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
 arch/x86/kvm/x86.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 2c24cb5..31d44c1 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1112,6 +1112,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
 		break;
 	case MSR_K7_HWCR:
 		data &= ~(u64)0x40;	/* ignore flush filter disable */
+		data &= ~(u64)0x100;	/* ignore ignne emulation enable */
 		if (data != 0) {
 			pr_unimpl(vcpu, "unimplemented HWCR wrmsr: 0x%llx\n",
 				data);
-- 
1.7.0

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 08/11] KVM: x86: Don't set arch.cr0 in kvm_set_cr0
  2010-02-24 17:59 [PATCH 0/11] Another set of nested svm fixes and optimizations Joerg Roedel
                   ` (6 preceding siblings ...)
  2010-02-24 17:59 ` [PATCH 07/11] KVM: SVM: Ignore write of hwcr.ignne Joerg Roedel
@ 2010-02-24 17:59 ` Joerg Roedel
  2010-02-24 17:59 ` [PATCH 09/11] KVM: SVM: Handle nested selective_cr0 intercept correctly Joerg Roedel
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Joerg Roedel @ 2010-02-24 17:59 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti
  Cc: Alexander Graf, kvm, linux-kernel, Joerg Roedel

The vcpu->arch.cr0 variable is already set in the
architecture specific set_cr0 callbacks. There is no need to
set it in the common code.
This allows the architecture code to keep the old arch.cr0
value if it wants. This is required for nested svm to decide
if a selective_cr0 exit needs to be injected.

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
 arch/x86/kvm/x86.c |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 31d44c1..a81046b 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -485,7 +485,6 @@ void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
 	}
 
 	kvm_x86_ops->set_cr0(vcpu, cr0);
-	vcpu->arch.cr0 = cr0;
 
 	kvm_mmu_reset_context(vcpu);
 	return;
-- 
1.7.0

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 09/11] KVM: SVM: Handle nested selective_cr0 intercept correctly
  2010-02-24 17:59 [PATCH 0/11] Another set of nested svm fixes and optimizations Joerg Roedel
                   ` (7 preceding siblings ...)
  2010-02-24 17:59 ` [PATCH 08/11] KVM: x86: Don't set arch.cr0 in kvm_set_cr0 Joerg Roedel
@ 2010-02-24 17:59 ` Joerg Roedel
  2010-02-24 17:59 ` [PATCH 10/11] KVM: SVM: Clear exit_info for injected INTR exits Joerg Roedel
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Joerg Roedel @ 2010-02-24 17:59 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti
  Cc: Alexander Graf, kvm, linux-kernel, Joerg Roedel

If we have the following situation with nested svm:

1. Host KVM intercepts cr0 writes
2. Guest hypervisor intercepts only selective cr0 writes

Then we get an cr0 write intercept which is handled on the
host. But that intercepts may actually be a selective cr0
intercept for the guest. This patch checks for this
condition and injects a selective cr0 intercept if needed.

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
 arch/x86/kvm/svm.c |   21 +++++++++++++++++++++
 1 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 2450a7c..22654de 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -1037,6 +1037,27 @@ static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
 
+	if (is_nested(svm)) {
+		/*
+		 * We are here because we run in nested mode, the host kvm
+		 * intercepts cr0 writes but the l1 hypervisor does not.
+		 * But the L1 hypervisor may intercept selective cr0 writes.
+		 * This needs to be checked here.
+		 */
+		unsigned long old, new;
+
+		/* Remove bits that would trigger a real cr0 write intercept */
+		old = vcpu->arch.cr0 & SVM_CR0_SELECTIVE_MASK;
+		new = cr0 & SVM_CR0_SELECTIVE_MASK;
+
+		if (old == new) {
+			/* cr0 write with ts and mp unchanged */
+			svm->vmcb->control.exit_code = SVM_EXIT_CR0_SEL_WRITE;
+			if (nested_svm_exit_handled(svm) == NESTED_EXIT_DONE)
+				return;
+		}
+	}
+
 #ifdef CONFIG_X86_64
 	if (vcpu->arch.efer & EFER_LME) {
 		if (!is_paging(vcpu) && (cr0 & X86_CR0_PG)) {
-- 
1.7.0



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 10/11] KVM: SVM: Clear exit_info for injected INTR exits
  2010-02-24 17:59 [PATCH 0/11] Another set of nested svm fixes and optimizations Joerg Roedel
                   ` (8 preceding siblings ...)
  2010-02-24 17:59 ` [PATCH 09/11] KVM: SVM: Handle nested selective_cr0 intercept correctly Joerg Roedel
@ 2010-02-24 17:59 ` Joerg Roedel
  2010-02-24 17:59 ` [PATCH 11/11] KVM: SVM: Optimize nested svm msrpm merging Joerg Roedel
  2010-02-25 10:32 ` [PATCH 0/11] Another set of nested svm fixes and optimizations Avi Kivity
  11 siblings, 0 replies; 20+ messages in thread
From: Joerg Roedel @ 2010-02-24 17:59 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti
  Cc: Alexander Graf, kvm, linux-kernel, Joerg Roedel

When injecting an vmexit.intr into the nested hypervisor
there might be leftover values in the exit_info fields.
Clear them to not confuse nested hypervisors.

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
 arch/x86/kvm/svm.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 22654de..ae2f211 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -1485,7 +1485,9 @@ static inline bool nested_svm_intr(struct vcpu_svm *svm)
 	if (!(svm->vcpu.arch.hflags & HF_HIF_MASK))
 		return false;
 
-	svm->vmcb->control.exit_code = SVM_EXIT_INTR;
+	svm->vmcb->control.exit_code   = SVM_EXIT_INTR;
+	svm->vmcb->control.exit_info_1 = 0;
+	svm->vmcb->control.exit_info_2 = 0;
 
 	if (svm->nested.intercept & 1ULL) {
 		/*
-- 
1.7.0



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 11/11] KVM: SVM: Optimize nested svm msrpm merging
  2010-02-24 17:59 [PATCH 0/11] Another set of nested svm fixes and optimizations Joerg Roedel
                   ` (9 preceding siblings ...)
  2010-02-24 17:59 ` [PATCH 10/11] KVM: SVM: Clear exit_info for injected INTR exits Joerg Roedel
@ 2010-02-24 17:59 ` Joerg Roedel
  2010-02-24 19:27   ` Alexander Graf
  2010-02-25 10:32 ` [PATCH 0/11] Another set of nested svm fixes and optimizations Avi Kivity
  11 siblings, 1 reply; 20+ messages in thread
From: Joerg Roedel @ 2010-02-24 17:59 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti
  Cc: Alexander Graf, kvm, linux-kernel, Joerg Roedel

This patch optimizes the way the msrpm of the host and the
guest are merged. The old code merged the 2 msrpm pages
completly. This code needed to touch 24kb of memory for that
operation. The optimized variant this patch introduces
merges only the parts where the host msrpm may contain zero
bits. This reduces the amount of memory which is touched to
48 bytes.

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
 arch/x86/kvm/svm.c |   45 ++++++++++++++++++++++++++++++++++++---------
 1 files changed, 36 insertions(+), 9 deletions(-)

diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index ae2f211..eb25fea 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -754,6 +754,7 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id)
 	svm->nested.hsave = page_address(hsave_page);
 
 	svm->nested.msrpm = page_address(nested_msrpm_pages);
+	svm_vcpu_init_msrpm(svm->nested.msrpm);
 
 	svm->vmcb = page_address(page);
 	clear_page(svm->vmcb);
@@ -1824,20 +1825,46 @@ static int nested_svm_vmexit(struct vcpu_svm *svm)
 
 static bool nested_svm_vmrun_msrpm(struct vcpu_svm *svm)
 {
-	u32 *nested_msrpm;
-	struct page *page;
+	/*
+	 * This function merges the msr permission bitmaps of kvm and the
+	 * nested vmcb. It is omptimized in that it only merges the parts where
+	 * the kvm msr permission bitmap may contain zero bits
+	 */
+	static const u32 msrpm_offsets[] = {
+		0x0000002c, /* SYSENTER_CS */
+
+		0x00000038, /* LASTBRANCHFROMIP
+			       LASTBRANCHTOIP
+			       LASTINTFROMIP
+			       LASTINTTOIP */
+
+		0x00000820, /* STAR
+			       LSTAR
+			       CSTAR
+			       SYSCALL_MASK */
+
+		0x00000840, /* FS_BASE
+			       GS_BASE
+			       KERNEL_GS_BASE */
+
+		0xffffffff, /* End of List */
+	};
 	int i;
 
-	nested_msrpm = nested_svm_map(svm, svm->nested.vmcb_msrpm, &page);
-	if (!nested_msrpm)
-		return false;
+	for (i = 0; msrpm_offsets[i] != 0xffffffff; i++) {
+		u32 value, p;
+		u64 offset;
 
-	for (i = 0; i < PAGE_SIZE * (1 << MSRPM_ALLOC_ORDER) / 4; i++)
-		svm->nested.msrpm[i] = svm->msrpm[i] | nested_msrpm[i];
+		offset = svm->nested.vmcb_msrpm + msrpm_offsets[i];
+		p      = msrpm_offsets[i] / 4;
 
-	svm->vmcb->control.msrpm_base_pa = __pa(svm->nested.msrpm);
+		if (kvm_read_guest(svm->vcpu.kvm, offset, &value, 4))
+			return false;
 
-	nested_svm_unmap(page);
+		svm->nested.msrpm[p] = svm->msrpm[p] | value;
+	}
+
+	svm->vmcb->control.msrpm_base_pa = __pa(svm->nested.msrpm);
 
 	return true;
 }
-- 
1.7.0



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH 01/11] KVM: SVM: Coding style cleanup
  2010-02-24 17:59 ` [PATCH 01/11] KVM: SVM: Coding style cleanup Joerg Roedel
@ 2010-02-24 18:02   ` Joerg Roedel
  0 siblings, 0 replies; 20+ messages in thread
From: Joerg Roedel @ 2010-02-24 18:02 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: Alexander Graf, kvm, linux-kernel

On Wed, Feb 24, 2010 at 06:59:10PM +0100, Joerg Roedel wrote:
> This patch removes whitespace errors, fixes comment formats
> and most of checkpatch warnings. Now vim does not show
                         ^^^^^^^^
This means actually "errors". The warnings left in this file are
completly 80-chars-per-line related. Two errors are left which don't
make sense to fix.

	Joerg

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 11/11] KVM: SVM: Optimize nested svm msrpm merging
  2010-02-24 17:59 ` [PATCH 11/11] KVM: SVM: Optimize nested svm msrpm merging Joerg Roedel
@ 2010-02-24 19:27   ` Alexander Graf
  2010-02-24 19:37     ` Joerg Roedel
  0 siblings, 1 reply; 20+ messages in thread
From: Alexander Graf @ 2010-02-24 19:27 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: Avi Kivity, Marcelo Tosatti, kvm, linux-kernel


On 24.02.2010, at 18:59, Joerg Roedel wrote:

> This patch optimizes the way the msrpm of the host and the
> guest are merged. The old code merged the 2 msrpm pages
> completly. This code needed to touch 24kb of memory for that
> operation. The optimized variant this patch introduces
> merges only the parts where the host msrpm may contain zero
> bits. This reduces the amount of memory which is touched to
> 48 bytes.

Nice catch!

> 
> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
> ---
> arch/x86/kvm/svm.c |   45 ++++++++++++++++++++++++++++++++++++---------
> 1 files changed, 36 insertions(+), 9 deletions(-)
> 
> diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
> index ae2f211..eb25fea 100644
> --- a/arch/x86/kvm/svm.c
> +++ b/arch/x86/kvm/svm.c
> @@ -754,6 +754,7 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id)
> 	svm->nested.hsave = page_address(hsave_page);
> 
> 	svm->nested.msrpm = page_address(nested_msrpm_pages);
> +	svm_vcpu_init_msrpm(svm->nested.msrpm);
> 
> 	svm->vmcb = page_address(page);
> 	clear_page(svm->vmcb);
> @@ -1824,20 +1825,46 @@ static int nested_svm_vmexit(struct vcpu_svm *svm)
> 
> static bool nested_svm_vmrun_msrpm(struct vcpu_svm *svm)
> {
> -	u32 *nested_msrpm;
> -	struct page *page;
> +	/*
> +	 * This function merges the msr permission bitmaps of kvm and the
> +	 * nested vmcb. It is omptimized in that it only merges the parts where
> +	 * the kvm msr permission bitmap may contain zero bits
> +	 */
> +	static const u32 msrpm_offsets[] = {
> +		0x0000002c, /* SYSENTER_CS */
> +
> +		0x00000038, /* LASTBRANCHFROMIP
> +			       LASTBRANCHTOIP
> +			       LASTINTFROMIP
> +			       LASTINTTOIP */
> +
> +		0x00000820, /* STAR
> +			       LSTAR
> +			       CSTAR
> +			       SYSCALL_MASK */
> +
> +		0x00000840, /* FS_BASE
> +			       GS_BASE
> +			       KERNEL_GS_BASE */
> +
> +		0xffffffff, /* End of List */

Isn't there such a list around somewhere already? We really should only keep this list once throughout the whole code. If necessary, just create the list on the fly when bits get set in the msrpm.

Alex

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 11/11] KVM: SVM: Optimize nested svm msrpm merging
  2010-02-24 19:27   ` Alexander Graf
@ 2010-02-24 19:37     ` Joerg Roedel
  2010-02-24 19:58       ` Avi Kivity
  0 siblings, 1 reply; 20+ messages in thread
From: Joerg Roedel @ 2010-02-24 19:37 UTC (permalink / raw)
  To: Alexander Graf; +Cc: Avi Kivity, Marcelo Tosatti, kvm, linux-kernel

On Wed, Feb 24, 2010 at 08:27:50PM +0100, Alexander Graf wrote:
> > +	static const u32 msrpm_offsets[] = {
> > +		0x0000002c, /* SYSENTER_CS */
> > +
> > +		0x00000038, /* LASTBRANCHFROMIP
> > +			       LASTBRANCHTOIP
> > +			       LASTINTFROMIP
> > +			       LASTINTTOIP */
> > +
> > +		0x00000820, /* STAR
> > +			       LSTAR
> > +			       CSTAR
> > +			       SYSCALL_MASK */
> > +
> > +		0x00000840, /* FS_BASE
> > +			       GS_BASE
> > +			       KERNEL_GS_BASE */
> > +
> > +		0xffffffff, /* End of List */
> 
> Isn't there such a list around somewhere already? We really should
> only keep this list once throughout the whole code. If necessary, just
> create the list on the fly when bits get set in the msrpm.

No, the list is hardcoded in 3 functions (as parameter of
set_msr_interception). I think about a variant to do this with a single
list. Probably I create a list of MSRs and check in
set_msr_interceptionm for it.

	Joerg



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 11/11] KVM: SVM: Optimize nested svm msrpm merging
  2010-02-24 19:37     ` Joerg Roedel
@ 2010-02-24 19:58       ` Avi Kivity
  2010-02-24 20:00         ` Alexander Graf
  0 siblings, 1 reply; 20+ messages in thread
From: Avi Kivity @ 2010-02-24 19:58 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: Alexander Graf, Marcelo Tosatti, kvm, linux-kernel

On 02/24/2010 09:37 PM, Joerg Roedel wrote:
>
>> Isn't there such a list around somewhere already? We really should
>> only keep this list once throughout the whole code. If necessary, just
>> create the list on the fly when bits get set in the msrpm.
>>      
> No, the list is hardcoded in 3 functions (as parameter of
> set_msr_interception). I think about a variant to do this with a single
> list. Probably I create a list of MSRs and check in
> set_msr_interceptionm for it.
>
>    

Or, have set_msr_interception() create the list of offsets.


-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 11/11] KVM: SVM: Optimize nested svm msrpm merging
  2010-02-24 19:58       ` Avi Kivity
@ 2010-02-24 20:00         ` Alexander Graf
  2010-02-24 20:09           ` Avi Kivity
  0 siblings, 1 reply; 20+ messages in thread
From: Alexander Graf @ 2010-02-24 20:00 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Joerg Roedel, Marcelo Tosatti, kvm, linux-kernel


On 24.02.2010, at 20:58, Avi Kivity wrote:

> On 02/24/2010 09:37 PM, Joerg Roedel wrote:
>> 
>>> Isn't there such a list around somewhere already? We really should
>>> only keep this list once throughout the whole code. If necessary, just
>>> create the list on the fly when bits get set in the msrpm.
>>>     
>> No, the list is hardcoded in 3 functions (as parameter of
>> set_msr_interception). I think about a variant to do this with a single
>> list. Probably I create a list of MSRs and check in
>> set_msr_interceptionm for it.
>> 
>>   
> 
> Or, have set_msr_interception() create the list of offsets.

Or even better yet put the list into BSS because it should be static anyways. From that the real MSRPM and the merging function can be fed.

Alex

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 11/11] KVM: SVM: Optimize nested svm msrpm merging
  2010-02-24 20:00         ` Alexander Graf
@ 2010-02-24 20:09           ` Avi Kivity
  0 siblings, 0 replies; 20+ messages in thread
From: Avi Kivity @ 2010-02-24 20:09 UTC (permalink / raw)
  To: Alexander Graf; +Cc: Joerg Roedel, Marcelo Tosatti, kvm, linux-kernel

On 02/24/2010 10:00 PM, Alexander Graf wrote:
> On 24.02.2010, at 20:58, Avi Kivity wrote:
>
>    
>> On 02/24/2010 09:37 PM, Joerg Roedel wrote:
>>      
>>>        
>>>> Isn't there such a list around somewhere already? We really should
>>>> only keep this list once throughout the whole code. If necessary, just
>>>> create the list on the fly when bits get set in the msrpm.
>>>>
>>>>          
>>> No, the list is hardcoded in 3 functions (as parameter of
>>> set_msr_interception). I think about a variant to do this with a single
>>> list. Probably I create a list of MSRs and check in
>>> set_msr_interceptionm for it.
>>>
>>>
>>>        
>> Or, have set_msr_interception() create the list of offsets.
>>      
> Or even better yet put the list into BSS because it should be static anyways. From that the real MSRPM and the merging function can be fed.
>    

Yup.

In fact, the real MSRPM can be generated by merging the list into an 
empty bitmap.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 06/11] KVM: SVM: Implement emulation of vm_cr msr
  2010-02-24 17:59 ` [PATCH 06/11] KVM: SVM: Implement emulation of vm_cr msr Joerg Roedel
@ 2010-02-25 10:28   ` Avi Kivity
  0 siblings, 0 replies; 20+ messages in thread
From: Avi Kivity @ 2010-02-25 10:28 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: Marcelo Tosatti, Alexander Graf, kvm, linux-kernel

On 02/24/2010 07:59 PM, Joerg Roedel wrote:
> This patch implements the emulation of the vm_cr msr for
> nested svm.
>
>    

This needs to be exposed to userspace for save/restore.

-- 
error compiling committee.c: too many arguments to function

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 0/11] Another set of nested svm fixes and optimizations
  2010-02-24 17:59 [PATCH 0/11] Another set of nested svm fixes and optimizations Joerg Roedel
                   ` (10 preceding siblings ...)
  2010-02-24 17:59 ` [PATCH 11/11] KVM: SVM: Optimize nested svm msrpm merging Joerg Roedel
@ 2010-02-25 10:32 ` Avi Kivity
  11 siblings, 0 replies; 20+ messages in thread
From: Avi Kivity @ 2010-02-25 10:32 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: Marcelo Tosatti, Alexander Graf, kvm, linux-kernel

On 02/24/2010 07:59 PM, Joerg Roedel wrote:
> Hi,
>
> here is another set of patches I collected in the last days while trying
> to get Hyper-V running with nested svm. I was not successful yet but the
> patches in this set make sense anyway :-)
> The patches fix coding style issues which annoyed me for some time
> because my vim shows all c-space-errors with red color. Other patches in
> this set make nested svm more complete (nmi and selective cr0 related).
> The vm_cr and hwcr.ignne patches are related to Hyper-V tests. This
> hypervisor expects to write to those msrs.
> The most interesting thing is patch 11 which reduces the amount of
> memory which is touched in the vmrun emulation for merging the msrpms
> from 24kb to 48 bytes.  Please review and comment (or apply if
> perfect ;-) ) these patches.
>    

1-10 applied.  11 had about 32 suggestions for improvement, please pick 
one and resubmit.

-- 
error compiling committee.c: too many arguments to function

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2010-02-25 10:32 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-02-24 17:59 [PATCH 0/11] Another set of nested svm fixes and optimizations Joerg Roedel
2010-02-24 17:59 ` [PATCH 01/11] KVM: SVM: Coding style cleanup Joerg Roedel
2010-02-24 18:02   ` Joerg Roedel
2010-02-24 17:59 ` [PATCH 02/11] KVM: SVM: Reset MMU on nested_svm_vmrun for NPT too Joerg Roedel
2010-02-24 17:59 ` [PATCH 03/11] KVM: SVM: Check for nested intercepts on NMI injection Joerg Roedel
2010-02-24 17:59 ` [PATCH 04/11] KVM: SVM: Restore tracing of nested vmcb address Joerg Roedel
2010-02-24 17:59 ` [PATCH 05/11] KVM: SVM: Add kvm_nested_intercepts tracepoint Joerg Roedel
2010-02-24 17:59 ` [PATCH 06/11] KVM: SVM: Implement emulation of vm_cr msr Joerg Roedel
2010-02-25 10:28   ` Avi Kivity
2010-02-24 17:59 ` [PATCH 07/11] KVM: SVM: Ignore write of hwcr.ignne Joerg Roedel
2010-02-24 17:59 ` [PATCH 08/11] KVM: x86: Don't set arch.cr0 in kvm_set_cr0 Joerg Roedel
2010-02-24 17:59 ` [PATCH 09/11] KVM: SVM: Handle nested selective_cr0 intercept correctly Joerg Roedel
2010-02-24 17:59 ` [PATCH 10/11] KVM: SVM: Clear exit_info for injected INTR exits Joerg Roedel
2010-02-24 17:59 ` [PATCH 11/11] KVM: SVM: Optimize nested svm msrpm merging Joerg Roedel
2010-02-24 19:27   ` Alexander Graf
2010-02-24 19:37     ` Joerg Roedel
2010-02-24 19:58       ` Avi Kivity
2010-02-24 20:00         ` Alexander Graf
2010-02-24 20:09           ` Avi Kivity
2010-02-25 10:32 ` [PATCH 0/11] Another set of nested svm fixes and optimizations Avi Kivity

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox