kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/13] KVM: Make the instruction emulator aware of Nested Virtualization v2
@ 2011-03-25  9:29 Joerg Roedel
  2011-03-25  9:29 ` [PATCH 01/13] KVM: x86 emulator: add framework for instruction Joerg Roedel
                   ` (13 more replies)
  0 siblings, 14 replies; 29+ messages in thread
From: Joerg Roedel @ 2011-03-25  9:29 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm

Hi,

this is version 2 of the patch-set to make the KVM instruction emulator
aware of intercepted instructions. Noting the differences to v1 does not
make a lot of sense this this is basically a re-implementation so that
almost everything changed :-)
The re-write was done on the basis of Avi's patches he sent after the
last discussion. With these changes the implementation in the SVM code
got a lot smaller and more generic (and easier to extend). The big
switch is now only necessary for handling special cases.

Comments and feedback is appreciated.

Regards,

	Joerg

Diffstat:

 arch/x86/include/asm/kvm_emulate.h |   67 +++++++++
 arch/x86/include/asm/kvm_host.h    |   21 +++
 arch/x86/kvm/emulate.c             |  128 ++++++++++++++----
 arch/x86/kvm/svm.c                 |  264 +++++++++++++++++++++++++++++-------
 arch/x86/kvm/x86.c                 |   30 ++++
 5 files changed, 432 insertions(+), 78 deletions(-)

Shortlog:

Avi Kivity (2):
      KVM: x86 emulator: add framework for instruction
      KVM: x86 emulator: add SVM intercepts

Joerg Roedel (11):
      KVM: X86: Don't write-back cpu-state on X86EMUL_INTERCEPTED
      KVM: X86: Add x86 callback for intercept check
      KVM: SVM: Add intercept check for emulated cr accesses
      KVM: SVM: Add intercept check for accessing dr registers
      KVM: SVM: Add intercept checks for descriptor table accesses
      KVM: SVM: Add intercept checks for SVM instructions
      KVM: SVM: Add intercept checks for remaining group7 instructions
      KVM: SVM: Add intercept checks for remaining twobyte instructions
      KVM: SVM: Add intercept checks for one-byte instructions
      KVM: SVM: Add checks for IO instructions
      KVM: SVM: Remove nested sel_cr0_write handling code



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

* [PATCH 01/13] KVM: x86 emulator: add framework for instruction
  2011-03-25  9:29 [PATCH 0/13] KVM: Make the instruction emulator aware of Nested Virtualization v2 Joerg Roedel
@ 2011-03-25  9:29 ` Joerg Roedel
  2011-03-26  9:54   ` Avi Kivity
  2011-03-27 12:56   ` Gleb Natapov
  2011-03-25  9:29 ` [PATCH 02/13] KVM: x86 emulator: add SVM intercepts Joerg Roedel
                   ` (12 subsequent siblings)
  13 siblings, 2 replies; 29+ messages in thread
From: Joerg Roedel @ 2011-03-25  9:29 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, Avi Kivity, Joerg Roedel

From: Avi Kivity <avi@redhat.com>

When running in guest mode, certain instructions can be intercepted by
hardware.  This also holds for nested guests running on emulated
virtualization hardware, in particular instructions emulated by kvm
itself.

This patch adds a framework for intercepting instructions.  If an
instruction is marked for interception, and if we're running in guest
mode, a callback is called to check whether an intercept is needed or
not.  The callback is called at three points in time: immediately after
beginning execution, after checking privilge exceptions, and after
checking memory exception.  This suits the different interception points
defined for different instructions and for the various virtualization
instruction sets.

In addition, a new X86EMUL_INTERCEPT is defined, which any callback or
memory access may define, allowing the more complicated intercepts to be
implemented in existing callbacks.

Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
 arch/x86/include/asm/kvm_emulate.h |   20 ++++++++++++++++++++
 arch/x86/kvm/emulate.c             |   26 ++++++++++++++++++++++++++
 arch/x86/kvm/x86.c                 |    9 +++++++++
 3 files changed, 55 insertions(+), 0 deletions(-)

diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index 0f52135..4b9efb7 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -14,6 +14,8 @@
 #include <asm/desc_defs.h>
 
 struct x86_emulate_ctxt;
+enum x86_intercept;
+enum x86_intercept_stage;
 
 struct x86_exception {
 	u8 vector;
@@ -62,6 +64,7 @@ struct x86_exception {
 #define X86EMUL_RETRY_INSTR     3 /* retry the instruction for some reason */
 #define X86EMUL_CMPXCHG_FAILED  4 /* cmpxchg did not see expected value */
 #define X86EMUL_IO_NEEDED       5 /* IO is needed to complete emulation */
+#define X86EMUL_INTERCEPTED     6 /* Intercepted by nested VMCB/VMCS */
 
 struct x86_emulate_ops {
 	/*
@@ -158,6 +161,9 @@ struct x86_emulate_ops {
 	int (*set_dr)(int dr, unsigned long value, struct kvm_vcpu *vcpu);
 	int (*set_msr)(struct kvm_vcpu *vcpu, u32 msr_index, u64 data);
 	int (*get_msr)(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata);
+	int (*intercept)(struct x86_emulate_ctxt *ctxt,
+			 enum x86_intercept intercept,
+			 enum x86_intercept_stage stage);
 };
 
 /* Type, address-of, and value of an instruction's operand. */
@@ -197,6 +203,7 @@ struct read_cache {
 struct decode_cache {
 	u8 twobyte;
 	u8 b;
+	u8 intercept;
 	u8 lock_prefix;
 	u8 rep_prefix;
 	u8 op_bytes;
@@ -238,6 +245,7 @@ struct x86_emulate_ctxt {
 	/* interruptibility state, as a result of execution of STI or MOV SS */
 	int interruptibility;
 
+	bool guest_mode; /* guest running a nested guest */
 	bool perm_ok; /* do not check permissions if true */
 	bool only_vendor_specific_insn;
 
@@ -259,6 +267,18 @@ struct x86_emulate_ctxt {
 #define X86EMUL_MODE_PROT32   4	/* 32-bit protected mode. */
 #define X86EMUL_MODE_PROT64   8	/* 64-bit (long) mode.    */
 
+enum x86_intercept_stage {
+	x86_icpt_pre_except,
+	x86_icpt_post_except,
+	x86_icpt_post_memaccess,
+};
+
+enum x86_intercept {
+	x86_intercept_none,
+
+	nr_x86_intercepts
+};
+
 /* Host execution mode. */
 #if defined(CONFIG_X86_32)
 #define X86EMUL_MODE_HOST X86EMUL_MODE_PROT32
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 14c5ad5..8c6af7e 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -102,6 +102,7 @@
 
 struct opcode {
 	u32 flags;
+	u8 intercept;
 	union {
 		int (*execute)(struct x86_emulate_ctxt *ctxt);
 		struct opcode *group;
@@ -2326,10 +2327,13 @@ static int em_mov(struct x86_emulate_ctxt *ctxt)
 }
 
 #define D(_y) { .flags = (_y) }
+#define DI(_y, _i) { .flags = (_y), .intercept = x86_intercept_##_i }
 #define N    D(0)
 #define G(_f, _g) { .flags = ((_f) | Group), .u.group = (_g) }
 #define GD(_f, _g) { .flags = ((_f) | Group | GroupDual), .u.gdual = (_g) }
 #define I(_f, _e) { .flags = (_f), .u.execute = (_e) }
+#define II(_f, _e, _i) \
+	{ .flags = (_f), .u.execute = (_e), .intercept = x86_intercept_##_i }
 
 #define D2bv(_f)      D((_f) | ByteOp), D(_f)
 #define I2bv(_f, _e)  I((_f) | ByteOp, _e), I(_f, _e)
@@ -2745,6 +2749,7 @@ done_prefixes:
 	}
 
 	c->execute = opcode.u.execute;
+	c->intercept = opcode.intercept;
 
 	/* Unrecognised? */
 	if (c->d == 0 || (c->d & Undefined))
@@ -2979,12 +2984,26 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
 		goto done;
 	}
 
+	if (unlikely(ctxt->guest_mode) && c->intercept) {
+		rc = ops->intercept(ctxt, c->intercept,
+				    x86_icpt_pre_except);
+		if (rc != X86EMUL_CONTINUE)
+			goto done;
+	}
+
 	/* Privileged instruction can be executed only in CPL=0 */
 	if ((c->d & Priv) && ops->cpl(ctxt->vcpu)) {
 		rc = emulate_gp(ctxt, 0);
 		goto done;
 	}
 
+	if (unlikely(ctxt->guest_mode) && c->intercept) {
+		rc = ops->intercept(ctxt, c->intercept,
+				    x86_icpt_post_except);
+		if (rc != X86EMUL_CONTINUE)
+			goto done;
+	}
+
 	if (c->rep_prefix && (c->d & String)) {
 		/* All REP prefixes have the same first termination condition */
 		if (address_mask(c, c->regs[VCPU_REGS_RCX]) == 0) {
@@ -3023,6 +3042,13 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
 
 special_insn:
 
+	if (unlikely(ctxt->guest_mode) && c->intercept) {
+		rc = ops->intercept(ctxt, c->intercept,
+				    x86_icpt_post_memaccess);
+		if (rc != X86EMUL_CONTINUE)
+			goto done;
+	}
+
 	if (c->execute) {
 		rc = c->execute(ctxt);
 		if (rc != X86EMUL_CONTINUE)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 1b8b16a..2338309 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4241,6 +4241,13 @@ static void emulator_set_segment_selector(u16 sel, int seg,
 	kvm_set_segment(vcpu, &kvm_seg, seg);
 }
 
+static int emulator_intercept(struct x86_emulate_ctxt *ctxt,
+			      enum x86_intercept intercept,
+			      enum x86_intercept_stage stage)
+{
+	return X86EMUL_CONTINUE;
+}
+
 static struct x86_emulate_ops emulate_ops = {
 	.read_std            = kvm_read_guest_virt_system,
 	.write_std           = kvm_write_guest_virt_system,
@@ -4264,6 +4271,7 @@ static struct x86_emulate_ops emulate_ops = {
 	.set_dr              = emulator_set_dr,
 	.set_msr             = kvm_set_msr,
 	.get_msr             = kvm_get_msr,
+	.intercept           = emulator_intercept,
 };
 
 static void cache_all_regs(struct kvm_vcpu *vcpu)
@@ -4318,6 +4326,7 @@ static void init_emulate_ctxt(struct kvm_vcpu *vcpu)
 		? X86EMUL_MODE_VM86 : cs_l
 		? X86EMUL_MODE_PROT64 :	cs_db
 		? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16;
+	vcpu->arch.emulate_ctxt.guest_mode = is_guest_mode(vcpu);
 	memset(c, 0, sizeof(struct decode_cache));
 	memcpy(c->regs, vcpu->arch.regs, sizeof c->regs);
 }
-- 
1.7.1



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

* [PATCH 02/13] KVM: x86 emulator: add SVM intercepts
  2011-03-25  9:29 [PATCH 0/13] KVM: Make the instruction emulator aware of Nested Virtualization v2 Joerg Roedel
  2011-03-25  9:29 ` [PATCH 01/13] KVM: x86 emulator: add framework for instruction Joerg Roedel
@ 2011-03-25  9:29 ` Joerg Roedel
  2011-03-25  9:29 ` [PATCH 03/13] KVM: X86: Don't write-back cpu-state on X86EMUL_INTERCEPTED Joerg Roedel
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 29+ messages in thread
From: Joerg Roedel @ 2011-03-25  9:29 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, Avi Kivity, Joerg Roedel

From: Avi Kivity <avi@redhat.com>

Add intercept codes for instructions defined by SVM as
interceptable.

Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
 arch/x86/include/asm/kvm_emulate.h |   35 +++++++++++++++++++++++++++++++++++
 arch/x86/kvm/emulate.c             |   24 +++++++++++++-----------
 2 files changed, 48 insertions(+), 11 deletions(-)

diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index 4b9efb7..277f189 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -275,6 +275,41 @@ enum x86_intercept_stage {
 
 enum x86_intercept {
 	x86_intercept_none,
+	x86_intercept_lmsw,
+	x86_intercept_smsw,
+	x86_intercept_lidt,
+	x86_intercept_sidt,
+	x86_intercept_lgdt,
+	x86_intercept_sgdt,
+	x86_intercept_lldt,
+	x86_intercept_sldt,
+	x86_intercept_ltr,
+	x86_intercept_str,
+	x86_intercept_rdtsc,
+	x86_intercept_rdpmc,
+	x86_intercept_pushf,
+	x86_intercept_popf,
+	x86_intercept_cpuid,
+	x86_intercept_rsm,
+	x86_intercept_iret,
+	x86_intercept_intn,
+	x86_intercept_invd,
+	x86_intercept_pause,
+	x86_intercept_hlt,
+	x86_intercept_invlpg,
+	x86_intercept_invlpga,
+	x86_intercept_vmrun,
+	x86_intercept_vmload,
+	x86_intercept_vmsave,
+	x86_intercept_vmmcall,
+	x86_intercept_stgi,
+	x86_intercept_clgi,
+	x86_intercept_skinit,
+	x86_intercept_rdtscp,
+	x86_intercept_icebp,
+	x86_intercept_wbinvd,
+	x86_intercept_monitor,
+	x86_intercept_mwait,
 
 	nr_x86_intercepts
 };
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 8c6af7e..cf5f396 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2371,15 +2371,15 @@ static struct opcode group5[] = {
 };
 
 static struct group_dual group7 = { {
-	N, N, D(ModRM | SrcMem | Priv), D(ModRM | SrcMem | Priv),
-	D(SrcNone | ModRM | DstMem | Mov), N,
-	D(SrcMem16 | ModRM | Mov | Priv),
-	D(SrcMem | ModRM | ByteOp | Priv | NoAccess),
+	N, N, DI(ModRM | SrcMem | Priv, lgdt), DI(ModRM | SrcMem | Priv, lidt),
+	DI(SrcNone | ModRM | DstMem | Mov, smsw), N,
+	DI(SrcMem16 | ModRM | Mov | Priv, lmsw),
+	DI(SrcMem | ModRM | ByteOp | Priv | NoAccess, invlpg),
 }, {
 	D(SrcNone | ModRM | Priv | VendorSpecific), N,
 	N, D(SrcNone | ModRM | Priv | VendorSpecific),
-	D(SrcNone | ModRM | DstMem | Mov), N,
-	D(SrcMem16 | ModRM | Mov | Priv), N,
+	DI(SrcNone | ModRM | DstMem | Mov, smsw), N,
+	DI(SrcMem16 | ModRM | Mov | Priv, lmsw), N,
 } };
 
 static struct opcode group8[] = {
@@ -2454,7 +2454,7 @@ static struct opcode opcode_table[256] = {
 	/* 0x98 - 0x9F */
 	D(DstAcc | SrcNone), I(ImplicitOps | SrcAcc, em_cwd),
 	I(SrcImmFAddr | No64, em_call_far), N,
-	D(ImplicitOps | Stack), D(ImplicitOps | Stack), N, N,
+	DI(ImplicitOps | Stack, pushf), DI(ImplicitOps | Stack, popf), N, N,
 	/* 0xA0 - 0xA7 */
 	I2bv(DstAcc | SrcMem | Mov | MemAbs, em_mov),
 	I2bv(DstMem | SrcAcc | Mov | MemAbs, em_mov),
@@ -2477,7 +2477,8 @@ static struct opcode opcode_table[256] = {
 	G(ByteOp, group11), G(0, group11),
 	/* 0xC8 - 0xCF */
 	N, N, N, D(ImplicitOps | Stack),
-	D(ImplicitOps), D(SrcImmByte), D(ImplicitOps | No64), D(ImplicitOps),
+	D(ImplicitOps), DI(SrcImmByte, intn),
+	D(ImplicitOps | No64), DI(ImplicitOps, iret),
 	/* 0xD0 - 0xD7 */
 	D2bv(DstMem | SrcOne | ModRM), D2bv(DstMem | ModRM),
 	N, N, N, N,
@@ -2492,7 +2493,8 @@ static struct opcode opcode_table[256] = {
 	D2bv(SrcNone | DstAcc),	D2bv(SrcAcc | ImplicitOps),
 	/* 0xF0 - 0xF7 */
 	N, N, N, N,
-	D(ImplicitOps | Priv), D(ImplicitOps), G(ByteOp, group3), G(0, group3),
+	DI(ImplicitOps | Priv, hlt), D(ImplicitOps),
+	G(ByteOp, group3), G(0, group3),
 	/* 0xF8 - 0xFF */
 	D(ImplicitOps), D(ImplicitOps), D(ImplicitOps), D(ImplicitOps),
 	D(ImplicitOps), D(ImplicitOps), G(0, group4), G(0, group5),
@@ -2502,7 +2504,7 @@ static struct opcode twobyte_table[256] = {
 	/* 0x00 - 0x0F */
 	N, GD(0, &group7), N, N,
 	N, D(ImplicitOps | VendorSpecific), D(ImplicitOps | Priv), N,
-	D(ImplicitOps | Priv), D(ImplicitOps | Priv), N, N,
+	DI(ImplicitOps | Priv, invd), DI(ImplicitOps | Priv, wbinvd), N, N,
 	N, D(ImplicitOps | ModRM), N, N,
 	/* 0x10 - 0x1F */
 	N, N, N, N, N, N, N, N, D(ImplicitOps | ModRM), N, N, N, N, N, N, N,
@@ -2512,7 +2514,7 @@ static struct opcode twobyte_table[256] = {
 	N, N, N, N,
 	N, N, N, N, N, N, N, N,
 	/* 0x30 - 0x3F */
-	D(ImplicitOps | Priv), I(ImplicitOps, em_rdtsc),
+	D(ImplicitOps | Priv), II(ImplicitOps, em_rdtsc, rdtsc),
 	D(ImplicitOps | Priv), N,
 	D(ImplicitOps | VendorSpecific), D(ImplicitOps | Priv | VendorSpecific),
 	N, N,
-- 
1.7.1



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

* [PATCH 03/13] KVM: X86: Don't write-back cpu-state on X86EMUL_INTERCEPTED
  2011-03-25  9:29 [PATCH 0/13] KVM: Make the instruction emulator aware of Nested Virtualization v2 Joerg Roedel
  2011-03-25  9:29 ` [PATCH 01/13] KVM: x86 emulator: add framework for instruction Joerg Roedel
  2011-03-25  9:29 ` [PATCH 02/13] KVM: x86 emulator: add SVM intercepts Joerg Roedel
@ 2011-03-25  9:29 ` Joerg Roedel
  2011-03-25  9:29 ` [PATCH 04/13] KVM: X86: Add x86 callback for intercept check Joerg Roedel
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 29+ messages in thread
From: Joerg Roedel @ 2011-03-25  9:29 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, Joerg Roedel

This patch prevents the changed CPU state to be written back
when the emulator detected that the instruction was
intercepted by the guest.

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

diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index 277f189..7960eeb 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -325,6 +325,7 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len);
 #define EMULATION_FAILED -1
 #define EMULATION_OK 0
 #define EMULATION_RESTART 1
+#define EMULATION_INTERCEPTED 2
 int x86_emulate_insn(struct x86_emulate_ctxt *ctxt);
 int emulator_task_switch(struct x86_emulate_ctxt *ctxt,
 			 u16 tss_selector, int reason,
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index cf5f396..078acc4 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -3455,6 +3455,9 @@ writeback:
 done:
 	if (rc == X86EMUL_PROPAGATE_FAULT)
 		ctxt->have_exception = true;
+	if (rc == X86EMUL_INTERCEPTED)
+		return EMULATION_INTERCEPTED;
+
 	return (rc == X86EMUL_UNHANDLEABLE) ? EMULATION_FAILED : EMULATION_OK;
 
 twobyte_insn:
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 2338309..90a41aa 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4458,6 +4458,9 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu,
 restart:
 	r = x86_emulate_insn(&vcpu->arch.emulate_ctxt);
 
+	if (r == EMULATION_INTERCEPTED)
+		return EMULATE_DONE;
+
 	if (r == EMULATION_FAILED) {
 		if (reexecute_instruction(vcpu, cr2))
 			return EMULATE_DONE;
-- 
1.7.1



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

* [PATCH 04/13] KVM: X86: Add x86 callback for intercept check
  2011-03-25  9:29 [PATCH 0/13] KVM: Make the instruction emulator aware of Nested Virtualization v2 Joerg Roedel
                   ` (2 preceding siblings ...)
  2011-03-25  9:29 ` [PATCH 03/13] KVM: X86: Don't write-back cpu-state on X86EMUL_INTERCEPTED Joerg Roedel
@ 2011-03-25  9:29 ` Joerg Roedel
  2011-03-26  9:23   ` Avi Kivity
  2011-03-25  9:29 ` [PATCH 05/13] KVM: SVM: Add intercept check for emulated cr accesses Joerg Roedel
                   ` (9 subsequent siblings)
  13 siblings, 1 reply; 29+ messages in thread
From: Joerg Roedel @ 2011-03-25  9:29 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, Joerg Roedel

This patch adds a callback into kvm_x86_ops so that svm and
vmx code can do intercept checks on emulated instructions.

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
 arch/x86/include/asm/kvm_host.h |   21 +++++++++++++++++++++
 arch/x86/kvm/svm.c              |    9 +++++++++
 arch/x86/kvm/x86.c              |   20 +++++++++++++++++++-
 3 files changed, 49 insertions(+), 1 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 35f81b1..7544964 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -504,6 +504,22 @@ struct kvm_vcpu_stat {
 	u32 nmi_injections;
 };
 
+/*
+ * This struct is used to carry enough information from the instruction
+ * decoder to main KVM so that a decision can be made whether the
+ * instruction needs to be intercepted or not.
+ */
+struct x86_instruction_info {
+	u8  intercept;		/* which intercept			*/
+	u8  rep_prefix;		/* rep prefix?				*/
+	u8  modrm;		/* index of register used		*/
+	u64 src_val;		/* value of source operand		*/
+	u8  src_bytes;		/* size of source operand		*/
+	u8  dst_bytes;		/* size of destination operand		*/
+	u8  ad_bytes;		/* size of src/dst address		*/
+	u64 next_rip;		/* rip following the instruction	*/
+};
+
 struct kvm_x86_ops {
 	int (*cpu_has_kvm_support)(void);          /* __init */
 	int (*disabled_by_bios)(void);             /* __init */
@@ -591,6 +607,11 @@ struct kvm_x86_ops {
 	void (*write_tsc_offset)(struct kvm_vcpu *vcpu, u64 offset);
 
 	void (*get_exit_info)(struct kvm_vcpu *vcpu, u64 *info1, u64 *info2);
+
+	int (*check_intercept)(struct kvm_vcpu *vcpu,
+			       struct x86_instruction_info *info,
+			       enum x86_intercept_stage stage);
+
 	const struct trace_print_flags *exit_reasons_str;
 };
 
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 2a19322..b36df64 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -3871,6 +3871,13 @@ static void svm_fpu_deactivate(struct kvm_vcpu *vcpu)
 	update_cr0_intercept(svm);
 }
 
+static int svm_check_intercept(struct kvm_vcpu *vcpu,
+			       struct x86_instruction_info *info,
+			       enum x86_intercept_stage stage)
+{
+	return X86EMUL_CONTINUE;
+}
+
 static struct kvm_x86_ops svm_x86_ops = {
 	.cpu_has_kvm_support = has_svm,
 	.disabled_by_bios = is_disabled,
@@ -3956,6 +3963,8 @@ static struct kvm_x86_ops svm_x86_ops = {
 	.adjust_tsc_offset = svm_adjust_tsc_offset,
 
 	.set_tdp_cr3 = set_tdp_cr3,
+
+	.check_intercept = svm_check_intercept,
 };
 
 static int __init svm_init(void)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 90a41aa..bf72ec6 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4245,7 +4245,25 @@ static int emulator_intercept(struct x86_emulate_ctxt *ctxt,
 			      enum x86_intercept intercept,
 			      enum x86_intercept_stage stage)
 {
-	return X86EMUL_CONTINUE;
+	struct x86_instruction_info info = {
+		.intercept  = intercept,
+		.rep_prefix = ctxt->decode.rep_prefix,
+		.modrm      = ctxt->decode.modrm,
+		.src_val    = ctxt->decode.src.val64,
+		.src_bytes  = ctxt->decode.src.bytes,
+		.dst_bytes  = ctxt->decode.dst.bytes,
+		.ad_bytes   = ctxt->decode.ad_bytes,
+		.next_rip   = ctxt->eip,
+	};
+
+	/*
+	 * The callback only needs to be implemented if the architecture
+	 * supports emulated guest-mode. This BUG_ON reminds the
+	 * programmer that this callback needs to be implemented.
+	 */
+	BUG_ON(kvm_x86_ops->check_intercept == NULL);
+
+	return kvm_x86_ops->check_intercept(ctxt->vcpu, &info, stage);
 }
 
 static struct x86_emulate_ops emulate_ops = {
-- 
1.7.1



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

* [PATCH 05/13] KVM: SVM: Add intercept check for emulated cr accesses
  2011-03-25  9:29 [PATCH 0/13] KVM: Make the instruction emulator aware of Nested Virtualization v2 Joerg Roedel
                   ` (3 preceding siblings ...)
  2011-03-25  9:29 ` [PATCH 04/13] KVM: X86: Add x86 callback for intercept check Joerg Roedel
@ 2011-03-25  9:29 ` Joerg Roedel
  2011-03-26  9:37   ` Avi Kivity
  2011-03-25  9:29 ` [PATCH 06/13] KVM: SVM: Add intercept check for accessing dr registers Joerg Roedel
                   ` (8 subsequent siblings)
  13 siblings, 1 reply; 29+ messages in thread
From: Joerg Roedel @ 2011-03-25  9:29 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, Joerg Roedel

This patch adds all necessary intercept checks for
instructions that access the crX registers.

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
 arch/x86/include/asm/kvm_emulate.h |    3 +
 arch/x86/kvm/emulate.c             |    8 ++-
 arch/x86/kvm/svm.c                 |   80 +++++++++++++++++++++++++++++++++++-
 3 files changed, 87 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index 7960eeb..c1489e1 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -275,6 +275,9 @@ enum x86_intercept_stage {
 
 enum x86_intercept {
 	x86_intercept_none,
+	x86_intercept_cr_read,
+	x86_intercept_cr_write,
+	x86_intercept_clts,
 	x86_intercept_lmsw,
 	x86_intercept_smsw,
 	x86_intercept_lidt,
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 078acc4..384cfa2 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2503,14 +2503,16 @@ static struct opcode opcode_table[256] = {
 static struct opcode twobyte_table[256] = {
 	/* 0x00 - 0x0F */
 	N, GD(0, &group7), N, N,
-	N, D(ImplicitOps | VendorSpecific), D(ImplicitOps | Priv), N,
+	N, D(ImplicitOps | VendorSpecific), DI(ImplicitOps | Priv, clts), N,
 	DI(ImplicitOps | Priv, invd), DI(ImplicitOps | Priv, wbinvd), N, N,
 	N, D(ImplicitOps | ModRM), N, N,
 	/* 0x10 - 0x1F */
 	N, N, N, N, N, N, N, N, D(ImplicitOps | ModRM), N, N, N, N, N, N, N,
 	/* 0x20 - 0x2F */
-	D(ModRM | DstMem | Priv | Op3264), D(ModRM | DstMem | Priv | Op3264),
-	D(ModRM | SrcMem | Priv | Op3264), D(ModRM | SrcMem | Priv | Op3264),
+	DI(ModRM | DstMem | Priv | Op3264, cr_read),
+	D(ModRM | DstMem | Priv | Op3264),
+	DI(ModRM | SrcMem | Priv | Op3264, cr_write),
+	D(ModRM | SrcMem | Priv | Op3264),
 	N, N, N, N,
 	N, N, N, N, N, N, N, N,
 	/* 0x30 - 0x3F */
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index b36df64..3b6992e 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -3871,11 +3871,89 @@ static void svm_fpu_deactivate(struct kvm_vcpu *vcpu)
 	update_cr0_intercept(svm);
 }
 
+#define POST_EX(exit) { .exit_code = (exit), \
+			.stage = x86_icpt_post_except, \
+			.valid = true }
+
+static struct __x86_intercept {
+	u32 exit_code;
+	enum x86_intercept_stage stage;
+	bool valid;
+} x86_intercept_map[] = {
+	[x86_intercept_cr_read]		= POST_EX(SVM_EXIT_READ_CR0),
+	[x86_intercept_cr_write]	= POST_EX(SVM_EXIT_WRITE_CR0),
+	[x86_intercept_clts]		= POST_EX(SVM_EXIT_WRITE_CR0),
+	[x86_intercept_lmsw]		= POST_EX(SVM_EXIT_WRITE_CR0),
+	[x86_intercept_smsw]		= POST_EX(SVM_EXIT_READ_CR0),
+};
+
+#undef POST_EX
+
 static int svm_check_intercept(struct kvm_vcpu *vcpu,
 			       struct x86_instruction_info *info,
 			       enum x86_intercept_stage stage)
 {
-	return X86EMUL_CONTINUE;
+	struct vcpu_svm *svm = to_svm(vcpu);
+	int vmexit, ret = X86EMUL_CONTINUE;
+	struct __x86_intercept icpt_info;
+	struct vmcb *vmcb = svm->vmcb;
+	int reg;
+
+	if (info->intercept >= ARRAY_SIZE(x86_intercept_map))
+		goto out;
+
+	icpt_info = x86_intercept_map[info->intercept];
+
+	if (!icpt_info.valid || stage != icpt_info.stage)
+		goto out;
+
+	reg = (info->modrm >> 3) & 7;
+
+	switch (icpt_info.exit_code) {
+	case SVM_EXIT_READ_CR0:
+		if (info->intercept == x86_intercept_cr_read)
+			icpt_info.exit_code += reg;
+	case SVM_EXIT_WRITE_CR0: {
+		unsigned long cr0, val;
+		u64 intercept;
+
+		if (info->intercept == x86_intercept_cr_write)
+			icpt_info.exit_code += reg;
+
+		if (icpt_info.exit_code != SVM_EXIT_WRITE_CR0)
+			break;
+
+		intercept = svm->nested.intercept;
+
+		if (!(intercept & (1ULL << INTERCEPT_SELECTIVE_CR0)))
+			break;
+
+		cr0 = vcpu->arch.cr0 & ~SVM_CR0_SELECTIVE_MASK;
+		val = info->src_val  & ~SVM_CR0_SELECTIVE_MASK;
+
+		if (info->intercept == x86_intercept_lmsw) {
+			cr0 &= 0xfUL;
+			val &= 0xfUL;
+		}
+
+		if (cr0 ^ val)
+			icpt_info.exit_code = SVM_EXIT_CR0_SEL_WRITE;
+
+		break;
+	}
+	default:
+		break;
+	}
+
+	vmcb->control.next_rip  = info->next_rip;
+	vmcb->control.exit_code = icpt_info.exit_code;
+	vmexit = nested_svm_exit_handled(svm);
+
+	ret = (vmexit == NESTED_EXIT_DONE) ? X86EMUL_INTERCEPTED
+					   : X86EMUL_CONTINUE;
+
+out:
+	return ret;
 }
 
 static struct kvm_x86_ops svm_x86_ops = {
-- 
1.7.1



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

* [PATCH 06/13] KVM: SVM: Add intercept check for accessing dr registers
  2011-03-25  9:29 [PATCH 0/13] KVM: Make the instruction emulator aware of Nested Virtualization v2 Joerg Roedel
                   ` (4 preceding siblings ...)
  2011-03-25  9:29 ` [PATCH 05/13] KVM: SVM: Add intercept check for emulated cr accesses Joerg Roedel
@ 2011-03-25  9:29 ` Joerg Roedel
  2011-03-25  9:29 ` [PATCH 07/13] KVM: SVM: Add intercept checks for descriptor table accesses Joerg Roedel
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 29+ messages in thread
From: Joerg Roedel @ 2011-03-25  9:29 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, Joerg Roedel

This patch adds the intercept checks for instruction
accessing the debug registers.

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

diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index c1489e1..db744c9 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -280,6 +280,8 @@ enum x86_intercept {
 	x86_intercept_clts,
 	x86_intercept_lmsw,
 	x86_intercept_smsw,
+	x86_intercept_dr_read,
+	x86_intercept_dr_write,
 	x86_intercept_lidt,
 	x86_intercept_sidt,
 	x86_intercept_lgdt,
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 384cfa2..0719954 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2510,9 +2510,9 @@ static struct opcode twobyte_table[256] = {
 	N, N, N, N, N, N, N, N, D(ImplicitOps | ModRM), N, N, N, N, N, N, N,
 	/* 0x20 - 0x2F */
 	DI(ModRM | DstMem | Priv | Op3264, cr_read),
-	D(ModRM | DstMem | Priv | Op3264),
+	DI(ModRM | DstMem | Priv | Op3264, dr_read),
 	DI(ModRM | SrcMem | Priv | Op3264, cr_write),
-	D(ModRM | SrcMem | Priv | Op3264),
+	DI(ModRM | SrcMem | Priv | Op3264, dr_write),
 	N, N, N, N,
 	N, N, N, N, N, N, N, N,
 	/* 0x30 - 0x3F */
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 3b6992e..25d7460 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -3885,6 +3885,8 @@ static struct __x86_intercept {
 	[x86_intercept_clts]		= POST_EX(SVM_EXIT_WRITE_CR0),
 	[x86_intercept_lmsw]		= POST_EX(SVM_EXIT_WRITE_CR0),
 	[x86_intercept_smsw]		= POST_EX(SVM_EXIT_READ_CR0),
+	[x86_intercept_dr_read]		= POST_EX(SVM_EXIT_READ_DR0),
+	[x86_intercept_dr_write]	= POST_EX(SVM_EXIT_WRITE_DR0),
 };
 
 #undef POST_EX
@@ -3941,6 +3943,10 @@ static int svm_check_intercept(struct kvm_vcpu *vcpu,
 
 		break;
 	}
+	case SVM_EXIT_READ_DR0:
+	case SVM_EXIT_WRITE_DR0:
+		icpt_info.exit_code += reg;
+		break;
 	default:
 		break;
 	}
-- 
1.7.1



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

* [PATCH 07/13] KVM: SVM: Add intercept checks for descriptor table accesses
  2011-03-25  9:29 [PATCH 0/13] KVM: Make the instruction emulator aware of Nested Virtualization v2 Joerg Roedel
                   ` (5 preceding siblings ...)
  2011-03-25  9:29 ` [PATCH 06/13] KVM: SVM: Add intercept check for accessing dr registers Joerg Roedel
@ 2011-03-25  9:29 ` Joerg Roedel
  2011-03-26  9:43   ` Avi Kivity
  2011-03-25  9:29 ` [PATCH 08/13] KVM: SVM: Add intercept checks for SVM instructions Joerg Roedel
                   ` (6 subsequent siblings)
  13 siblings, 1 reply; 29+ messages in thread
From: Joerg Roedel @ 2011-03-25  9:29 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, Joerg Roedel

This patch add intercept checks into the KVM instruction
emulator to check for the 8 instructions that access the
descriptor table addresses.

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

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 0719954..505348f 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2370,8 +2370,17 @@ static struct opcode group5[] = {
 	D(SrcMem | ModRM | Stack), N,
 };
 
+static struct opcode group6[] = {
+	DI(ModRM,	 sldt),
+	DI(ModRM,	 str),
+	DI(ModRM | Priv, lldt),
+	DI(ModRM | Priv, ltr),
+	N, N, N, N,
+};
+
 static struct group_dual group7 = { {
-	N, N, DI(ModRM | SrcMem | Priv, lgdt), DI(ModRM | SrcMem | Priv, lidt),
+	DI(ModRM | DstMem | Priv, sgdt), DI(ModRM | DstMem | Priv, sidt),
+	DI(ModRM | SrcMem | Priv, lgdt), DI(ModRM | SrcMem | Priv, lidt),
 	DI(SrcNone | ModRM | DstMem | Mov, smsw), N,
 	DI(SrcMem16 | ModRM | Mov | Priv, lmsw),
 	DI(SrcMem | ModRM | ByteOp | Priv | NoAccess, invlpg),
@@ -2502,7 +2511,7 @@ static struct opcode opcode_table[256] = {
 
 static struct opcode twobyte_table[256] = {
 	/* 0x00 - 0x0F */
-	N, GD(0, &group7), N, N,
+	G(0, group6), GD(0, &group7), N, N,
 	N, D(ImplicitOps | VendorSpecific), DI(ImplicitOps | Priv, clts), N,
 	DI(ImplicitOps | Priv, invd), DI(ImplicitOps | Priv, wbinvd), N, N,
 	N, D(ImplicitOps | ModRM), N, N,
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 25d7460..faa959e 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -3874,6 +3874,10 @@ static void svm_fpu_deactivate(struct kvm_vcpu *vcpu)
 #define POST_EX(exit) { .exit_code = (exit), \
 			.stage = x86_icpt_post_except, \
 			.valid = true }
+#define POST_MEM(exit) { .exit_code = (exit), \
+			 .stage = x86_icpt_post_memaccess, \
+			 .valid = true }
+
 
 static struct __x86_intercept {
 	u32 exit_code;
@@ -3887,9 +3891,18 @@ static struct __x86_intercept {
 	[x86_intercept_smsw]		= POST_EX(SVM_EXIT_READ_CR0),
 	[x86_intercept_dr_read]		= POST_EX(SVM_EXIT_READ_DR0),
 	[x86_intercept_dr_write]	= POST_EX(SVM_EXIT_WRITE_DR0),
+	[x86_intercept_sldt]		= POST_MEM(SVM_EXIT_LDTR_READ),
+	[x86_intercept_str]		= POST_MEM(SVM_EXIT_TR_READ),
+	[x86_intercept_lldt]		= POST_MEM(SVM_EXIT_LDTR_WRITE),
+	[x86_intercept_ltr]		= POST_MEM(SVM_EXIT_TR_WRITE),
+	[x86_intercept_sgdt]		= POST_MEM(SVM_EXIT_GDTR_READ),
+	[x86_intercept_sidt]		= POST_MEM(SVM_EXIT_IDTR_READ),
+	[x86_intercept_lgdt]		= POST_MEM(SVM_EXIT_GDTR_WRITE),
+	[x86_intercept_lidt]		= POST_MEM(SVM_EXIT_IDTR_WRITE),
 };
 
 #undef POST_EX
+#undef POST_MEM
 
 static int svm_check_intercept(struct kvm_vcpu *vcpu,
 			       struct x86_instruction_info *info,
-- 
1.7.1



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

* [PATCH 08/13] KVM: SVM: Add intercept checks for SVM instructions
  2011-03-25  9:29 [PATCH 0/13] KVM: Make the instruction emulator aware of Nested Virtualization v2 Joerg Roedel
                   ` (6 preceding siblings ...)
  2011-03-25  9:29 ` [PATCH 07/13] KVM: SVM: Add intercept checks for descriptor table accesses Joerg Roedel
@ 2011-03-25  9:29 ` Joerg Roedel
  2011-03-25  9:29 ` [PATCH 09/13] KVM: SVM: Add intercept checks for remaining group7 instructions Joerg Roedel
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 29+ messages in thread
From: Joerg Roedel @ 2011-03-25  9:29 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, Joerg Roedel

This patch adds the necessary code changes in the
instruction emulator and the extensions to svm.c to
implement intercept checks for the svm instructions.

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

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 505348f..dc53806 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -75,6 +75,8 @@
 #define Stack       (1<<13)     /* Stack instruction (push/pop) */
 #define Group       (1<<14)     /* Bits 3:5 of modrm byte extend opcode */
 #define GroupDual   (1<<15)     /* Alternate decoding of mod == 3 */
+#define RMExt       (1<<16)     /* Opcode extension in ModRM r/m if mod == 3 */
+
 /* Misc flags */
 #define VendorSpecific (1<<22) /* Vendor specific instruction */
 #define NoAccess    (1<<23) /* Don't access memory (lea/invlpg/verr etc) */
@@ -2329,6 +2331,7 @@ static int em_mov(struct x86_emulate_ctxt *ctxt)
 #define D(_y) { .flags = (_y) }
 #define DI(_y, _i) { .flags = (_y), .intercept = x86_intercept_##_i }
 #define N    D(0)
+#define EXT(_f, _e) { .flags = ((_f) | RMExt), .u.group = (_e) }
 #define G(_f, _g) { .flags = ((_f) | Group), .u.group = (_g) }
 #define GD(_f, _g) { .flags = ((_f) | Group | GroupDual), .u.gdual = (_g) }
 #define I(_f, _e) { .flags = (_f), .u.execute = (_e) }
@@ -2343,6 +2346,17 @@ static int em_mov(struct x86_emulate_ctxt *ctxt)
 		D2bv(((_f) & ~Lock) | DstAcc | SrcImm)
 
 
+static struct opcode group7_rm3[] = {
+	DI(SrcNone | ModRM | Priv, vmrun),
+	DI(SrcNone | ModRM | Priv, vmmcall),
+	DI(SrcNone | ModRM | Priv, vmload),
+	DI(SrcNone | ModRM | Priv, vmsave),
+	DI(SrcNone | ModRM | Priv, stgi),
+	DI(SrcNone | ModRM | Priv, clgi),
+	DI(SrcNone | ModRM | Priv, skinit),
+	DI(SrcNone | ModRM | Priv, invlpga),
+};
+
 static struct opcode group1[] = {
 	X7(D(Lock)), N
 };
@@ -2386,7 +2400,7 @@ static struct group_dual group7 = { {
 	DI(SrcMem | ModRM | ByteOp | Priv | NoAccess, invlpg),
 }, {
 	D(SrcNone | ModRM | Priv | VendorSpecific), N,
-	N, D(SrcNone | ModRM | Priv | VendorSpecific),
+	N, EXT(0, group7_rm3),
 	DI(SrcNone | ModRM | DstMem | Mov, smsw), N,
 	DI(SrcMem16 | ModRM | Mov | Priv, lmsw), N,
 } };
@@ -2581,6 +2595,7 @@ static struct opcode twobyte_table[256] = {
 #undef G
 #undef GD
 #undef I
+#undef EXT
 
 #undef D2bv
 #undef I2bv
@@ -2758,6 +2773,12 @@ done_prefixes:
 			opcode = g_mod3[goffset];
 		else
 			opcode = g_mod012[goffset];
+
+		if (opcode.flags & RMExt) {
+			goffset = c->modrm & 7;
+			opcode = opcode.u.group[goffset];
+		}
+
 		c->d |= opcode.flags;
 	}
 
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index faa959e..dded390 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -3899,6 +3899,14 @@ static struct __x86_intercept {
 	[x86_intercept_sidt]		= POST_MEM(SVM_EXIT_IDTR_READ),
 	[x86_intercept_lgdt]		= POST_MEM(SVM_EXIT_GDTR_WRITE),
 	[x86_intercept_lidt]		= POST_MEM(SVM_EXIT_IDTR_WRITE),
+	[x86_intercept_vmrun]		= POST_EX(SVM_EXIT_VMRUN),
+	[x86_intercept_vmmcall]		= POST_EX(SVM_EXIT_VMMCALL),
+	[x86_intercept_vmload]		= POST_EX(SVM_EXIT_VMLOAD),
+	[x86_intercept_vmsave]		= POST_EX(SVM_EXIT_VMSAVE),
+	[x86_intercept_stgi]		= POST_EX(SVM_EXIT_STGI),
+	[x86_intercept_clgi]		= POST_EX(SVM_EXIT_CLGI),
+	[x86_intercept_skinit]		= POST_EX(SVM_EXIT_SKINIT),
+	[x86_intercept_invlpga]		= POST_EX(SVM_EXIT_INVLPGA),
 };
 
 #undef POST_EX
-- 
1.7.1



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

* [PATCH 09/13] KVM: SVM: Add intercept checks for remaining group7 instructions
  2011-03-25  9:29 [PATCH 0/13] KVM: Make the instruction emulator aware of Nested Virtualization v2 Joerg Roedel
                   ` (7 preceding siblings ...)
  2011-03-25  9:29 ` [PATCH 08/13] KVM: SVM: Add intercept checks for SVM instructions Joerg Roedel
@ 2011-03-25  9:29 ` Joerg Roedel
  2011-03-25  9:29 ` [PATCH 10/13] KVM: SVM: Add intercept checks for remaining twobyte instructions Joerg Roedel
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 29+ messages in thread
From: Joerg Roedel @ 2011-03-25  9:29 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, Joerg Roedel

This patch implements the emulator intercept checks for the
RDTSCP, MONITOR, and MWAIT instructions.

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

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index dc53806..0aaba1e 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2346,6 +2346,12 @@ static int em_mov(struct x86_emulate_ctxt *ctxt)
 		D2bv(((_f) & ~Lock) | DstAcc | SrcImm)
 
 
+static struct opcode group7_rm1[] = {
+	DI(SrcNone | ModRM | Priv, monitor),
+	DI(SrcNone | ModRM | Priv, mwait),
+	N, N, N, N, N, N,
+};
+
 static struct opcode group7_rm3[] = {
 	DI(SrcNone | ModRM | Priv, vmrun),
 	DI(SrcNone | ModRM | Priv, vmmcall),
@@ -2357,6 +2363,11 @@ static struct opcode group7_rm3[] = {
 	DI(SrcNone | ModRM | Priv, invlpga),
 };
 
+static struct opcode group7_rm7[] = {
+	N,
+	DI(SrcNone | ModRM, rdtscp),
+	N, N, N, N, N, N,
+};
 static struct opcode group1[] = {
 	X7(D(Lock)), N
 };
@@ -2399,10 +2410,10 @@ static struct group_dual group7 = { {
 	DI(SrcMem16 | ModRM | Mov | Priv, lmsw),
 	DI(SrcMem | ModRM | ByteOp | Priv | NoAccess, invlpg),
 }, {
-	D(SrcNone | ModRM | Priv | VendorSpecific), N,
+	D(SrcNone | ModRM | Priv | VendorSpecific), EXT(0, group7_rm1),
 	N, EXT(0, group7_rm3),
 	DI(SrcNone | ModRM | DstMem | Mov, smsw), N,
-	DI(SrcMem16 | ModRM | Mov | Priv, lmsw), N,
+	DI(SrcMem16 | ModRM | Mov | Priv, lmsw), EXT(0, group7_rm7),
 } };
 
 static struct opcode group8[] = {
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index dded390..958697e 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -3907,6 +3907,9 @@ static struct __x86_intercept {
 	[x86_intercept_clgi]		= POST_EX(SVM_EXIT_CLGI),
 	[x86_intercept_skinit]		= POST_EX(SVM_EXIT_SKINIT),
 	[x86_intercept_invlpga]		= POST_EX(SVM_EXIT_INVLPGA),
+	[x86_intercept_rdtscp]		= POST_EX(SVM_EXIT_RDTSCP),
+	[x86_intercept_monitor]		= POST_MEM(SVM_EXIT_MONITOR),
+	[x86_intercept_mwait]		= POST_EX(SVM_EXIT_MWAIT),
 };
 
 #undef POST_EX
-- 
1.7.1



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

* [PATCH 10/13] KVM: SVM: Add intercept checks for remaining twobyte instructions
  2011-03-25  9:29 [PATCH 0/13] KVM: Make the instruction emulator aware of Nested Virtualization v2 Joerg Roedel
                   ` (8 preceding siblings ...)
  2011-03-25  9:29 ` [PATCH 09/13] KVM: SVM: Add intercept checks for remaining group7 instructions Joerg Roedel
@ 2011-03-25  9:29 ` Joerg Roedel
  2011-03-25  9:29 ` [PATCH 11/13] KVM: SVM: Add intercept checks for one-byte instructions Joerg Roedel
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 29+ messages in thread
From: Joerg Roedel @ 2011-03-25  9:29 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, Joerg Roedel

This patch adds intercepts checks for the remaining twobyte
instructions to the KVM instruction emulator.

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
 arch/x86/include/asm/kvm_emulate.h |    2 ++
 arch/x86/kvm/emulate.c             |    8 ++++----
 arch/x86/kvm/svm.c                 |   19 +++++++++++++++++++
 3 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index db744c9..41c0120 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -315,6 +315,8 @@ enum x86_intercept {
 	x86_intercept_wbinvd,
 	x86_intercept_monitor,
 	x86_intercept_mwait,
+	x86_intercept_rdmsr,
+	x86_intercept_wrmsr,
 
 	nr_x86_intercepts
 };
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 0aaba1e..8947643 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2550,8 +2550,8 @@ static struct opcode twobyte_table[256] = {
 	N, N, N, N,
 	N, N, N, N, N, N, N, N,
 	/* 0x30 - 0x3F */
-	D(ImplicitOps | Priv), II(ImplicitOps, em_rdtsc, rdtsc),
-	D(ImplicitOps | Priv), N,
+	DI(ImplicitOps | Priv, wrmsr), II(ImplicitOps, em_rdtsc, rdtsc),
+	DI(ImplicitOps | Priv, rdmsr), DI(ImplicitOps | Priv, rdpmc),
 	D(ImplicitOps | VendorSpecific), D(ImplicitOps | Priv | VendorSpecific),
 	N, N,
 	N, N, N, N, N, N, N, N,
@@ -2569,12 +2569,12 @@ static struct opcode twobyte_table[256] = {
 	X16(D(ByteOp | DstMem | SrcNone | ModRM| Mov)),
 	/* 0xA0 - 0xA7 */
 	D(ImplicitOps | Stack), D(ImplicitOps | Stack),
-	N, D(DstMem | SrcReg | ModRM | BitOp),
+	DI(ImplicitOps, cpuid), D(DstMem | SrcReg | ModRM | BitOp),
 	D(DstMem | SrcReg | Src2ImmByte | ModRM),
 	D(DstMem | SrcReg | Src2CL | ModRM), N, N,
 	/* 0xA8 - 0xAF */
 	D(ImplicitOps | Stack), D(ImplicitOps | Stack),
-	N, D(DstMem | SrcReg | ModRM | BitOp | Lock),
+	DI(ImplicitOps, rsm), D(DstMem | SrcReg | ModRM | BitOp | Lock),
 	D(DstMem | SrcReg | Src2ImmByte | ModRM),
 	D(DstMem | SrcReg | Src2CL | ModRM),
 	D(ModRM), I(DstReg | SrcMem | ModRM, em_imul),
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 958697e..c2e90bb 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -3871,6 +3871,9 @@ static void svm_fpu_deactivate(struct kvm_vcpu *vcpu)
 	update_cr0_intercept(svm);
 }
 
+#define PRE_EX(exit)  { .exit_code = (exit), \
+			.stage = x86_icpt_pre_except, \
+			.valid = true }
 #define POST_EX(exit) { .exit_code = (exit), \
 			.stage = x86_icpt_post_except, \
 			.valid = true }
@@ -3910,8 +3913,18 @@ static struct __x86_intercept {
 	[x86_intercept_rdtscp]		= POST_EX(SVM_EXIT_RDTSCP),
 	[x86_intercept_monitor]		= POST_MEM(SVM_EXIT_MONITOR),
 	[x86_intercept_mwait]		= POST_EX(SVM_EXIT_MWAIT),
+	[x86_intercept_invlpg]		= POST_EX(SVM_EXIT_INVLPG),
+	[x86_intercept_invd]		= POST_EX(SVM_EXIT_INVD),
+	[x86_intercept_wbinvd]		= POST_EX(SVM_EXIT_WBINVD),
+	[x86_intercept_wrmsr]		= POST_EX(SVM_EXIT_MSR),
+	[x86_intercept_rdtsc]		= POST_EX(SVM_EXIT_RDTSC),
+	[x86_intercept_rdmsr]		= POST_EX(SVM_EXIT_MSR),
+	[x86_intercept_rdpmc]		= POST_EX(SVM_EXIT_RDPMC),
+	[x86_intercept_cpuid]		= PRE_EX(SVM_EXIT_CPUID),
+	[x86_intercept_rsm]		= PRE_EX(SVM_EXIT_RSM),
 };
 
+#undef PRE_EX
 #undef POST_EX
 #undef POST_MEM
 
@@ -3971,6 +3984,12 @@ static int svm_check_intercept(struct kvm_vcpu *vcpu,
 	case SVM_EXIT_WRITE_DR0:
 		icpt_info.exit_code += reg;
 		break;
+	case SVM_EXIT_MSR:
+		if (info->intercept == x86_intercept_wrmsr)
+			vmcb->control.exit_info_1 = 1;
+		else
+			vmcb->control.exit_info_1 = 0;
+		break;
 	default:
 		break;
 	}
-- 
1.7.1



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

* [PATCH 11/13] KVM: SVM: Add intercept checks for one-byte instructions
  2011-03-25  9:29 [PATCH 0/13] KVM: Make the instruction emulator aware of Nested Virtualization v2 Joerg Roedel
                   ` (9 preceding siblings ...)
  2011-03-25  9:29 ` [PATCH 10/13] KVM: SVM: Add intercept checks for remaining twobyte instructions Joerg Roedel
@ 2011-03-25  9:29 ` Joerg Roedel
  2011-03-26  9:53   ` Avi Kivity
  2011-03-25  9:29 ` [PATCH 12/13] KVM: SVM: Add checks for IO instructions Joerg Roedel
                   ` (2 subsequent siblings)
  13 siblings, 1 reply; 29+ messages in thread
From: Joerg Roedel @ 2011-03-25  9:29 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, Joerg Roedel

This patch add intercept checks for emulated one-byte
instructions to the KVM instruction emulation path.

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

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 8947643..4c0939d 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2484,7 +2484,7 @@ static struct opcode opcode_table[256] = {
 	D(DstMem | SrcNone | ModRM | Mov), D(ModRM | SrcMem | NoAccess | DstReg),
 	D(ImplicitOps | SrcMem16 | ModRM), G(0, group1A),
 	/* 0x90 - 0x97 */
-	X8(D(SrcAcc | DstReg)),
+	DI(SrcAcc | DstReg, pause), X7(D(SrcAcc | DstReg)),
 	/* 0x98 - 0x9F */
 	D(DstAcc | SrcNone), I(ImplicitOps | SrcAcc, em_cwd),
 	I(SrcImmFAddr | No64, em_call_far), N,
@@ -2526,7 +2526,7 @@ static struct opcode opcode_table[256] = {
 	D(SrcImmFAddr | No64), D(SrcImmByte | ImplicitOps),
 	D2bv(SrcNone | DstAcc),	D2bv(SrcAcc | ImplicitOps),
 	/* 0xF0 - 0xF7 */
-	N, N, N, N,
+	N, DI(ImplicitOps, icebp), N, N,
 	DI(ImplicitOps | Priv, hlt), D(ImplicitOps),
 	G(ByteOp, group3), G(0, group3),
 	/* 0xF8 - 0xFF */
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index c2e90bb..847a3f9 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -3922,6 +3922,13 @@ static struct __x86_intercept {
 	[x86_intercept_rdpmc]		= POST_EX(SVM_EXIT_RDPMC),
 	[x86_intercept_cpuid]		= PRE_EX(SVM_EXIT_CPUID),
 	[x86_intercept_rsm]		= PRE_EX(SVM_EXIT_RSM),
+	[x86_intercept_pause]		= PRE_EX(SVM_EXIT_PAUSE),
+	[x86_intercept_pushf]		= PRE_EX(SVM_EXIT_PUSHF),
+	[x86_intercept_popf]		= PRE_EX(SVM_EXIT_POPF),
+	[x86_intercept_intn]		= PRE_EX(SVM_EXIT_SWINT),
+	[x86_intercept_iret]		= PRE_EX(SVM_EXIT_IRET),
+	[x86_intercept_icebp]		= PRE_EX(SVM_EXIT_ICEBP),
+	[x86_intercept_hlt]		= POST_EX(SVM_EXIT_HLT),
 };
 
 #undef PRE_EX
@@ -3990,6 +3997,13 @@ static int svm_check_intercept(struct kvm_vcpu *vcpu,
 		else
 			vmcb->control.exit_info_1 = 0;
 		break;
+	case SVM_EXIT_PAUSE:
+		/*
+		 * We get this for NOP only, but pause
+		 * is rep not, check this here
+		 */
+		if (info->rep_prefix != REPE_PREFIX)
+			goto out;
 	default:
 		break;
 	}
-- 
1.7.1



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

* [PATCH 12/13] KVM: SVM: Add checks for IO instructions
  2011-03-25  9:29 [PATCH 0/13] KVM: Make the instruction emulator aware of Nested Virtualization v2 Joerg Roedel
                   ` (10 preceding siblings ...)
  2011-03-25  9:29 ` [PATCH 11/13] KVM: SVM: Add intercept checks for one-byte instructions Joerg Roedel
@ 2011-03-25  9:29 ` Joerg Roedel
  2011-03-25  9:29 ` [PATCH 13/13] KVM: SVM: Remove nested sel_cr0_write handling code Joerg Roedel
  2011-03-26  9:55 ` [PATCH 0/13] KVM: Make the instruction emulator aware of Nested Virtualization v2 Avi Kivity
  13 siblings, 0 replies; 29+ messages in thread
From: Joerg Roedel @ 2011-03-25  9:29 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, Joerg Roedel

This patch adds code to check for IOIO intercepts on
instructions decoded by the KVM instruction emulator.

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
 arch/x86/include/asm/kvm_emulate.h |    4 ++++
 arch/x86/kvm/emulate.c             |   10 ++++++----
 arch/x86/kvm/svm.c                 |   36 ++++++++++++++++++++++++++++++++++++
 3 files changed, 46 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index 41c0120..0b2e2de 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -317,6 +317,10 @@ enum x86_intercept {
 	x86_intercept_mwait,
 	x86_intercept_rdmsr,
 	x86_intercept_wrmsr,
+	x86_intercept_in,
+	x86_intercept_ins,
+	x86_intercept_out,
+	x86_intercept_outs,
 
 	nr_x86_intercepts
 };
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 4c0939d..879ce78 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2339,6 +2339,7 @@ static int em_mov(struct x86_emulate_ctxt *ctxt)
 	{ .flags = (_f), .u.execute = (_e), .intercept = x86_intercept_##_i }
 
 #define D2bv(_f)      D((_f) | ByteOp), D(_f)
+#define D2bvI(_f, _i) DI((_f) | ByteOp, _i), DI((_f), _i)
 #define I2bv(_f, _e)  I((_f) | ByteOp, _e), I(_f, _e)
 
 #define D6ALU(_f) D2bv((_f) | DstMem | SrcReg | ModRM),			\
@@ -2468,8 +2469,8 @@ static struct opcode opcode_table[256] = {
 	I(DstReg | SrcMem | ModRM | Src2Imm, em_imul_3op),
 	I(SrcImmByte | Mov | Stack, em_push),
 	I(DstReg | SrcMem | ModRM | Src2ImmByte, em_imul_3op),
-	D2bv(DstDI | Mov | String), /* insb, insw/insd */
-	D2bv(SrcSI | ImplicitOps | String), /* outsb, outsw/outsd */
+	D2bvI(DstDI | Mov | String, ins), /* insb, insw/insd */
+	D2bvI(SrcSI | ImplicitOps | String, outs), /* outsb, outsw/outsd */
 	/* 0x70 - 0x7F */
 	X16(D(SrcImmByte)),
 	/* 0x80 - 0x87 */
@@ -2520,11 +2521,11 @@ static struct opcode opcode_table[256] = {
 	N, N, N, N, N, N, N, N,
 	/* 0xE0 - 0xE7 */
 	X4(D(SrcImmByte)),
-	D2bv(SrcImmUByte | DstAcc), D2bv(SrcAcc | DstImmUByte),
+	D2bvI(SrcImmUByte | DstAcc, in), D2bvI(SrcAcc | DstImmUByte, out),
 	/* 0xE8 - 0xEF */
 	D(SrcImm | Stack), D(SrcImm | ImplicitOps),
 	D(SrcImmFAddr | No64), D(SrcImmByte | ImplicitOps),
-	D2bv(SrcNone | DstAcc),	D2bv(SrcAcc | ImplicitOps),
+	D2bvI(SrcNone | DstAcc, in), D2bvI(SrcAcc | ImplicitOps, out),
 	/* 0xF0 - 0xF7 */
 	N, DI(ImplicitOps, icebp), N, N,
 	DI(ImplicitOps | Priv, hlt), D(ImplicitOps),
@@ -2609,6 +2610,7 @@ static struct opcode twobyte_table[256] = {
 #undef EXT
 
 #undef D2bv
+#undef D2bvI
 #undef I2bv
 #undef D6ALU
 
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 847a3f9..1672e3c 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -3929,6 +3929,10 @@ static struct __x86_intercept {
 	[x86_intercept_iret]		= PRE_EX(SVM_EXIT_IRET),
 	[x86_intercept_icebp]		= PRE_EX(SVM_EXIT_ICEBP),
 	[x86_intercept_hlt]		= POST_EX(SVM_EXIT_HLT),
+	[x86_intercept_in]		= POST_EX(SVM_EXIT_IOIO),
+	[x86_intercept_ins]		= POST_EX(SVM_EXIT_IOIO),
+	[x86_intercept_out]		= POST_EX(SVM_EXIT_IOIO),
+	[x86_intercept_outs]		= POST_EX(SVM_EXIT_IOIO),
 };
 
 #undef PRE_EX
@@ -4004,6 +4008,38 @@ static int svm_check_intercept(struct kvm_vcpu *vcpu,
 		 */
 		if (info->rep_prefix != REPE_PREFIX)
 			goto out;
+	case SVM_EXIT_IOIO: {
+		u64 exit_info;
+		u32 bytes;
+
+		exit_info = (vcpu->arch.regs[VCPU_REGS_RDX] & 0xffff) << 16;
+
+		if (info->intercept == x86_intercept_in ||
+		    info->intercept == x86_intercept_ins) {
+			exit_info |= SVM_IOIO_TYPE_MASK;
+			bytes = info->src_bytes;
+		} else {
+			bytes = info->dst_bytes;
+		}
+
+		if (info->intercept == x86_intercept_outs ||
+		    info->intercept == x86_intercept_ins)
+			exit_info |= SVM_IOIO_STR_MASK;
+
+		if (info->rep_prefix)
+			exit_info |= SVM_IOIO_REP_MASK;
+
+		bytes = min(bytes, 4u);
+
+		exit_info |= bytes << SVM_IOIO_SIZE_SHIFT;
+
+		exit_info |= (u32)info->ad_bytes << (SVM_IOIO_ASIZE_SHIFT - 1);
+
+		vmcb->control.exit_info_1 = exit_info;
+		vmcb->control.exit_info_2 = info->next_rip;
+
+		break;
+	}
 	default:
 		break;
 	}
-- 
1.7.1



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

* [PATCH 13/13] KVM: SVM: Remove nested sel_cr0_write handling code
  2011-03-25  9:29 [PATCH 0/13] KVM: Make the instruction emulator aware of Nested Virtualization v2 Joerg Roedel
                   ` (11 preceding siblings ...)
  2011-03-25  9:29 ` [PATCH 12/13] KVM: SVM: Add checks for IO instructions Joerg Roedel
@ 2011-03-25  9:29 ` Joerg Roedel
  2011-03-26  9:55 ` [PATCH 0/13] KVM: Make the instruction emulator aware of Nested Virtualization v2 Avi Kivity
  13 siblings, 0 replies; 29+ messages in thread
From: Joerg Roedel @ 2011-03-25  9:29 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, Joerg Roedel

This patch removes all the old code which handled the nested
selective cr0 write intercepts. This code was only in place
as a work-around until the instruction emulator is capable
of doing the same. This is the case with this patch-set and
so the code can be removed.

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

diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 1672e3c..37c0060 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -93,14 +93,6 @@ struct nested_state {
 	/* A VMEXIT is required but not yet emulated */
 	bool exit_required;
 
-	/*
-	 * If we vmexit during an instruction emulation we need this to restore
-	 * the l1 guest rip after the emulation
-	 */
-	unsigned long vmexit_rip;
-	unsigned long vmexit_rsp;
-	unsigned long vmexit_rax;
-
 	/* cache for intercepts of the guest */
 	u32 intercept_cr;
 	u32 intercept_dr;
@@ -1365,31 +1357,6 @@ static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
 
-	if (is_guest_mode(vcpu)) {
-		/*
-		 * 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) {
-				svm->nested.vmexit_rip = kvm_rip_read(vcpu);
-				svm->nested.vmexit_rsp = kvm_register_read(vcpu, VCPU_REGS_RSP);
-				svm->nested.vmexit_rax = kvm_register_read(vcpu, VCPU_REGS_RAX);
-				return;
-			}
-		}
-	}
-
 #ifdef CONFIG_X86_64
 	if (vcpu->arch.efer & EFER_LME) {
 		if (!is_paging(vcpu) && (cr0 & X86_CR0_PG)) {
@@ -2676,6 +2643,29 @@ static int emulate_on_interception(struct vcpu_svm *svm)
 	return emulate_instruction(&svm->vcpu, 0) == EMULATE_DONE;
 }
 
+bool check_selective_cr0_intercepted(struct vcpu_svm *svm, unsigned long val)
+{
+	unsigned long cr0 = svm->vcpu.arch.cr0;
+	bool ret = false;
+	u64 intercept;
+
+	intercept = svm->nested.intercept;
+
+	if (!is_guest_mode(&svm->vcpu) ||
+	    (!(intercept & (1ULL << INTERCEPT_SELECTIVE_CR0))))
+		return false;
+
+	cr0 &= ~SVM_CR0_SELECTIVE_MASK;
+	val &= ~SVM_CR0_SELECTIVE_MASK;
+
+	if (cr0 ^ val) {
+		svm->vmcb->control.exit_code = SVM_EXIT_CR0_SEL_WRITE;
+		ret = (nested_svm_exit_handled(svm) == NESTED_EXIT_DONE);
+	}
+
+	return ret;
+}
+
 #define CR_VALID (1ULL << 63)
 
 static int cr_interception(struct vcpu_svm *svm)
@@ -2699,7 +2689,8 @@ static int cr_interception(struct vcpu_svm *svm)
 		val = kvm_register_read(&svm->vcpu, reg);
 		switch (cr) {
 		case 0:
-			err = kvm_set_cr0(&svm->vcpu, val);
+			if (!check_selective_cr0_intercepted(svm, val))
+				err = kvm_set_cr0(&svm->vcpu, val);
 			break;
 		case 3:
 			err = kvm_set_cr3(&svm->vcpu, val);
@@ -2744,23 +2735,6 @@ static int cr_interception(struct vcpu_svm *svm)
 	return 1;
 }
 
-static int cr0_write_interception(struct vcpu_svm *svm)
-{
-	struct kvm_vcpu *vcpu = &svm->vcpu;
-	int r;
-
-	r = cr_interception(svm);
-
-	if (svm->nested.vmexit_rip) {
-		kvm_register_write(vcpu, VCPU_REGS_RIP, svm->nested.vmexit_rip);
-		kvm_register_write(vcpu, VCPU_REGS_RSP, svm->nested.vmexit_rsp);
-		kvm_register_write(vcpu, VCPU_REGS_RAX, svm->nested.vmexit_rax);
-		svm->nested.vmexit_rip = 0;
-	}
-
-	return r;
-}
-
 static int dr_interception(struct vcpu_svm *svm)
 {
 	int reg, dr;
@@ -3048,7 +3022,7 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm) = {
 	[SVM_EXIT_READ_CR4]			= cr_interception,
 	[SVM_EXIT_READ_CR8]			= cr_interception,
 	[SVM_EXIT_CR0_SEL_WRITE]		= emulate_on_interception,
-	[SVM_EXIT_WRITE_CR0]			= cr0_write_interception,
+	[SVM_EXIT_WRITE_CR0]			= cr_interception,
 	[SVM_EXIT_WRITE_CR3]			= cr_interception,
 	[SVM_EXIT_WRITE_CR4]			= cr_interception,
 	[SVM_EXIT_WRITE_CR8]			= cr8_write_interception,
-- 
1.7.1



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

* Re: [PATCH 04/13] KVM: X86: Add x86 callback for intercept check
  2011-03-25  9:29 ` [PATCH 04/13] KVM: X86: Add x86 callback for intercept check Joerg Roedel
@ 2011-03-26  9:23   ` Avi Kivity
  0 siblings, 0 replies; 29+ messages in thread
From: Avi Kivity @ 2011-03-26  9:23 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: Marcelo Tosatti, kvm

On 03/25/2011 11:29 AM, Joerg Roedel wrote:
> This patch adds a callback into kvm_x86_ops so that svm and
> vmx code can do intercept checks on emulated instructions.
>
>
>
> +/*
> + * This struct is used to carry enough information from the instruction
> + * decoder to main KVM so that a decision can be made whether the
> + * instruction needs to be intercepted or not.
> + */
> +struct x86_instruction_info {
> +	u8  intercept;		/* which intercept			*/
> +	u8  rep_prefix;		/* rep prefix?				*/
> +	u8  modrm;		/* index of register used		*/
> +	u64 src_val;		/* value of source operand		*/
> +	u8  src_bytes;		/* size of source operand		*/
> +	u8  dst_bytes;		/* size of destination operand		*/
> +	u8  ad_bytes;		/* size of src/dst address		*/
> +	u64 next_rip;		/* rip following the instruction	*/
> +};

Should be in kvm_emulate.h.

> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 90a41aa..bf72ec6 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -4245,7 +4245,25 @@ static int emulator_intercept(struct x86_emulate_ctxt *ctxt,
>   			      enum x86_intercept intercept,
>   			      enum x86_intercept_stage stage)
>   {
> -	return X86EMUL_CONTINUE;
> +	struct x86_instruction_info info = {
> +		.intercept  = intercept,
> +		.rep_prefix = ctxt->decode.rep_prefix,
> +		.modrm      = ctxt->decode.modrm,
> +		.src_val    = ctxt->decode.src.val64,
> +		.src_bytes  = ctxt->decode.src.bytes,
> +		.dst_bytes  = ctxt->decode.dst.bytes,
> +		.ad_bytes   = ctxt->decode.ad_bytes,
> +		.next_rip   = ctxt->eip,
> +	};

And this should be in emulate.c, so kvm code doesn't have to peek into 
the emulator internals.


> +
> +	/*
> +	 * The callback only needs to be implemented if the architecture
> +	 * supports emulated guest-mode. This BUG_ON reminds the
> +	 * programmer that this callback needs to be implemented.
> +	 */
> +	BUG_ON(kvm_x86_ops->check_intercept == NULL);
> +

BUG_ON()s are nasty.  I prefer a null implementation for vmx.

> +	return kvm_x86_ops->check_intercept(ctxt->vcpu,&info, stage);
>   }
>
>   static struct x86_emulate_ops emulate_ops = {


-- 
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.


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

* Re: [PATCH 05/13] KVM: SVM: Add intercept check for emulated cr accesses
  2011-03-25  9:29 ` [PATCH 05/13] KVM: SVM: Add intercept check for emulated cr accesses Joerg Roedel
@ 2011-03-26  9:37   ` Avi Kivity
  2011-03-26 11:06     ` Joerg Roedel
  0 siblings, 1 reply; 29+ messages in thread
From: Avi Kivity @ 2011-03-26  9:37 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: Marcelo Tosatti, kvm

On 03/25/2011 11:29 AM, Joerg Roedel wrote:
> This patch adds all necessary intercept checks for
> instructions that access the crX registers.
>
>
> @@ -3871,11 +3871,89 @@ static void svm_fpu_deactivate(struct kvm_vcpu *vcpu)
>   	update_cr0_intercept(svm);
>   }
>
> +#define POST_EX(exit) { .exit_code = (exit), \
> +			.stage = x86_icpt_post_except, \
> +			.valid = true }
> +
> +static struct __x86_intercept {
> +	u32 exit_code;
> +	enum x86_intercept_stage stage;
> +	bool valid;

Isn't .valid always true, even in later patches?

> +} x86_intercept_map[] = {

const?

> +	[x86_intercept_cr_read]		= POST_EX(SVM_EXIT_READ_CR0),
> +	[x86_intercept_cr_write]	= POST_EX(SVM_EXIT_WRITE_CR0),
> +	[x86_intercept_clts]		= POST_EX(SVM_EXIT_WRITE_CR0),
> +	[x86_intercept_lmsw]		= POST_EX(SVM_EXIT_WRITE_CR0),
> +	[x86_intercept_smsw]		= POST_EX(SVM_EXIT_READ_CR0),
> +};
> +
> +#undef POST_EX
> +
>   static int svm_check_intercept(struct kvm_vcpu *vcpu,
>   			       struct x86_instruction_info *info,
>   			       enum x86_intercept_stage stage)
>   {
> -	return X86EMUL_CONTINUE;
> +	struct vcpu_svm *svm = to_svm(vcpu);
> +	int vmexit, ret = X86EMUL_CONTINUE;
> +	struct __x86_intercept icpt_info;
> +	struct vmcb *vmcb = svm->vmcb;
> +	int reg;
> +
> +	if (info->intercept>= ARRAY_SIZE(x86_intercept_map))
> +		goto out;
> +
> +	icpt_info = x86_intercept_map[info->intercept];
> +
> +	if (!icpt_info.valid || stage != icpt_info.stage)
> +		goto out;
> +
> +	reg = (info->modrm>>  3)&  7;

Doesn't work for r8-r15 or cr8-cr15; better to have the emulator put it 
into a separate variable.

> +
> +	switch (icpt_info.exit_code) {
> +	case SVM_EXIT_READ_CR0:
> +		if (info->intercept == x86_intercept_cr_read)
> +			icpt_info.exit_code += reg;

break; ?

(would work without it too, but we'll just get endless fixes for it)

> +	case SVM_EXIT_WRITE_CR0: {
> +		unsigned long cr0, val;
> +		u64 intercept;
> +
> +		if (info->intercept == x86_intercept_cr_write)
> +			icpt_info.exit_code += reg;
> +
> +		if (icpt_info.exit_code != SVM_EXIT_WRITE_CR0)
> +			break;
> +
> +		intercept = svm->nested.intercept;
> +
> +		if (!(intercept&  (1ULL<<  INTERCEPT_SELECTIVE_CR0)))
> +			break;
> +
> +		cr0 = vcpu->arch.cr0&  ~SVM_CR0_SELECTIVE_MASK;
> +		val = info->src_val&  ~SVM_CR0_SELECTIVE_MASK;
> +
> +		if (info->intercept == x86_intercept_lmsw) {
> +			cr0&= 0xfUL;
> +			val&= 0xfUL;

Probably, val |= X86_CR0_PE, since lmsw can't change that bit.

> +		}
> +
> +		if (cr0 ^ val)
> +			icpt_info.exit_code = SVM_EXIT_CR0_SEL_WRITE;
> +
> +		break;
> +	}
> +	default:
> +		break;
> +	}
> +
> +	vmcb->control.next_rip  = info->next_rip;
> +	vmcb->control.exit_code = icpt_info.exit_code;
> +	vmexit = nested_svm_exit_handled(svm);
> +
> +	ret = (vmexit == NESTED_EXIT_DONE) ? X86EMUL_INTERCEPTED
> +					   : X86EMUL_CONTINUE;
> +
> +out:
> +	return ret;
>   }
>
>   static struct kvm_x86_ops svm_x86_ops = {


-- 
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.


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

* Re: [PATCH 07/13] KVM: SVM: Add intercept checks for descriptor table accesses
  2011-03-25  9:29 ` [PATCH 07/13] KVM: SVM: Add intercept checks for descriptor table accesses Joerg Roedel
@ 2011-03-26  9:43   ` Avi Kivity
  2011-03-26 11:10     ` Joerg Roedel
  0 siblings, 1 reply; 29+ messages in thread
From: Avi Kivity @ 2011-03-26  9:43 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: Marcelo Tosatti, kvm

On 03/25/2011 11:29 AM, Joerg Roedel wrote:
> This patch add intercept checks into the KVM instruction
> emulator to check for the 8 instructions that access the
> descriptor table addresses.
>
>
> +static struct opcode group6[] = {
> +	DI(ModRM,	 sldt),
> +	DI(ModRM,	 str),
> +	DI(ModRM | Priv, lldt),
> +	DI(ModRM | Priv, ltr),
> +	N, N, N, N,
> +};
> +
>   static struct group_dual group7 = { {
> -	N, N, DI(ModRM | SrcMem | Priv, lgdt), DI(ModRM | SrcMem | Priv, lidt),
> +	DI(ModRM | DstMem | Priv, sgdt), DI(ModRM | DstMem | Priv, sidt),
> +	DI(ModRM | SrcMem | Priv, lgdt), DI(ModRM | SrcMem | Priv, lidt),
>   	DI(SrcNone | ModRM | DstMem | Mov, smsw), N,
>   	DI(SrcMem16 | ModRM | Mov | Priv, lmsw),
>   	DI(SrcMem | ModRM | ByteOp | Priv | NoAccess, invlpg),

You're adding decode info for instructions that aren't emulated.  Safe 
AFAICT because of 'default: goto cannot_emulate', I guess.

-- 
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.


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

* Re: [PATCH 11/13] KVM: SVM: Add intercept checks for one-byte instructions
  2011-03-25  9:29 ` [PATCH 11/13] KVM: SVM: Add intercept checks for one-byte instructions Joerg Roedel
@ 2011-03-26  9:53   ` Avi Kivity
  0 siblings, 0 replies; 29+ messages in thread
From: Avi Kivity @ 2011-03-26  9:53 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: Marcelo Tosatti, kvm

On 03/25/2011 11:29 AM, Joerg Roedel wrote:
> This patch add intercept checks for emulated one-byte
> instructions to the KVM instruction emulation path.
>
>
>   #undef PRE_EX
> @@ -3990,6 +3997,13 @@ static int svm_check_intercept(struct kvm_vcpu *vcpu,
>   		else
>   			vmcb->control.exit_info_1 = 0;
>   		break;
> +	case SVM_EXIT_PAUSE:
> +		/*
> +		 * We get this for NOP only, but pause
> +		 * is rep not, check this here
> +		 */
> +		if (info->rep_prefix != REPE_PREFIX)
> +			goto out;

Eventually we'll have decode table support for REP prefix (for mmx/sse 
instructions) so this will go away too.

-- 
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.


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

* Re: [PATCH 01/13] KVM: x86 emulator: add framework for instruction
  2011-03-25  9:29 ` [PATCH 01/13] KVM: x86 emulator: add framework for instruction Joerg Roedel
@ 2011-03-26  9:54   ` Avi Kivity
  2011-03-27 12:56   ` Gleb Natapov
  1 sibling, 0 replies; 29+ messages in thread
From: Avi Kivity @ 2011-03-26  9:54 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: Marcelo Tosatti, kvm

On 03/25/2011 11:29 AM, Joerg Roedel wrote:
> From: Avi Kivity<avi@redhat.com>
>
> When running in guest mode, certain instructions can be intercepted by
> hardware.  This also holds for nested guests running on emulated
> virtualization hardware, in particular instructions emulated by kvm
> itself.
>
> This patch adds a framework for intercepting instructions.  If an
> instruction is marked for interception, and if we're running in guest
> mode, a callback is called to check whether an intercept is needed or
> not.  The callback is called at three points in time: immediately after
> beginning execution, after checking privilge exceptions, and after
> checking memory exception.  This suits the different interception points
> defined for different instructions and for the various virtualization
> instruction sets.
>
> In addition, a new X86EMUL_INTERCEPT is defined, which any callback or
> memory access may define, allowing the more complicated intercepts to be
> implemented in existing callbacks.
>

Subject line truncated.

-- 
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.


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

* Re: [PATCH 0/13] KVM: Make the instruction emulator aware of Nested Virtualization v2
  2011-03-25  9:29 [PATCH 0/13] KVM: Make the instruction emulator aware of Nested Virtualization v2 Joerg Roedel
                   ` (12 preceding siblings ...)
  2011-03-25  9:29 ` [PATCH 13/13] KVM: SVM: Remove nested sel_cr0_write handling code Joerg Roedel
@ 2011-03-26  9:55 ` Avi Kivity
  13 siblings, 0 replies; 29+ messages in thread
From: Avi Kivity @ 2011-03-26  9:55 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: Marcelo Tosatti, kvm

On 03/25/2011 11:29 AM, Joerg Roedel wrote:
> Hi,
>
> this is version 2 of the patch-set to make the KVM instruction emulator
> aware of intercepted instructions. Noting the differences to v1 does not
> make a lot of sense this this is basically a re-implementation so that
> almost everything changed :-)
> The re-write was done on the basis of Avi's patches he sent after the
> last discussion. With these changes the implementation in the SVM code
> got a lot smaller and more generic (and easier to extend). The big
> switch is now only necessary for handling special cases.
>
> Comments and feedback is appreciated.
>

Looks good in general.

-- 
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.


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

* Re: [PATCH 05/13] KVM: SVM: Add intercept check for emulated cr accesses
  2011-03-26  9:37   ` Avi Kivity
@ 2011-03-26 11:06     ` Joerg Roedel
  2011-03-27  9:45       ` Avi Kivity
  0 siblings, 1 reply; 29+ messages in thread
From: Joerg Roedel @ 2011-03-26 11:06 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Joerg Roedel, Marcelo Tosatti, kvm

On Sat, Mar 26, 2011 at 11:37:42AM +0200, Avi Kivity wrote:
> On 03/25/2011 11:29 AM, Joerg Roedel wrote:
>> This patch adds all necessary intercept checks for
>> instructions that access the crX registers.
>>
>>
>> @@ -3871,11 +3871,89 @@ static void svm_fpu_deactivate(struct kvm_vcpu *vcpu)
>>   	update_cr0_intercept(svm);
>>   }
>>
>> +#define POST_EX(exit) { .exit_code = (exit), \
>> +			.stage = x86_icpt_post_except, \
>> +			.valid = true }
>> +
>> +static struct __x86_intercept {
>> +	u32 exit_code;
>> +	enum x86_intercept_stage stage;
>> +	bool valid;
>
> Isn't .valid always true, even in later patches?

The rational here was that the arrary below may not be fully populated
in the future and the svm_check_intercept function needs a way to find
out if it retrieved a populated value. Checks for zero values don't work
because exit_code and stage could both be zero and valid. So I added an
extra field to check that.
I''ll fix the other things you pointed out in the next version.

Regards,

	Joerg


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

* Re: [PATCH 07/13] KVM: SVM: Add intercept checks for descriptor table accesses
  2011-03-26  9:43   ` Avi Kivity
@ 2011-03-26 11:10     ` Joerg Roedel
  0 siblings, 0 replies; 29+ messages in thread
From: Joerg Roedel @ 2011-03-26 11:10 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Joerg Roedel, Marcelo Tosatti, kvm

On Sat, Mar 26, 2011 at 11:43:47AM +0200, Avi Kivity wrote:
> On 03/25/2011 11:29 AM, Joerg Roedel wrote:
>> This patch add intercept checks into the KVM instruction
>> emulator to check for the 8 instructions that access the
>> descriptor table addresses.
>>
>>
>> +static struct opcode group6[] = {
>> +	DI(ModRM,	 sldt),
>> +	DI(ModRM,	 str),
>> +	DI(ModRM | Priv, lldt),
>> +	DI(ModRM | Priv, ltr),
>> +	N, N, N, N,
>> +};
>> +
>>   static struct group_dual group7 = { {
>> -	N, N, DI(ModRM | SrcMem | Priv, lgdt), DI(ModRM | SrcMem | Priv, lidt),
>> +	DI(ModRM | DstMem | Priv, sgdt), DI(ModRM | DstMem | Priv, sidt),
>> +	DI(ModRM | SrcMem | Priv, lgdt), DI(ModRM | SrcMem | Priv, lidt),
>>   	DI(SrcNone | ModRM | DstMem | Mov, smsw), N,
>>   	DI(SrcMem16 | ModRM | Mov | Priv, lmsw),
>>   	DI(SrcMem | ModRM | ByteOp | Priv | NoAccess, invlpg),
>
> You're adding decode info for instructions that aren't emulated.  Safe  
> AFAICT because of 'default: goto cannot_emulate', I guess.

Right, all that can happen is that the nested guest shoot itself in the
foot by getting an #UD. Same for the SVM instructions.

	Joerg

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

* Re: [PATCH 05/13] KVM: SVM: Add intercept check for emulated cr accesses
  2011-03-26 11:06     ` Joerg Roedel
@ 2011-03-27  9:45       ` Avi Kivity
  0 siblings, 0 replies; 29+ messages in thread
From: Avi Kivity @ 2011-03-27  9:45 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: Joerg Roedel, Marcelo Tosatti, kvm

On 03/26/2011 01:06 PM, Joerg Roedel wrote:
> On Sat, Mar 26, 2011 at 11:37:42AM +0200, Avi Kivity wrote:
> >  On 03/25/2011 11:29 AM, Joerg Roedel wrote:
> >>  This patch adds all necessary intercept checks for
> >>  instructions that access the crX registers.
> >>
> >>
> >>  @@ -3871,11 +3871,89 @@ static void svm_fpu_deactivate(struct kvm_vcpu *vcpu)
> >>    	update_cr0_intercept(svm);
> >>    }
> >>
> >>  +#define POST_EX(exit) { .exit_code = (exit), \
> >>  +			.stage = x86_icpt_post_except, \
> >>  +			.valid = true }
> >>  +
> >>  +static struct __x86_intercept {
> >>  +	u32 exit_code;
> >>  +	enum x86_intercept_stage stage;
> >>  +	bool valid;
> >
> >  Isn't .valid always true, even in later patches?
>
> The rational here was that the arrary below may not be fully populated
> in the future and the svm_check_intercept function needs a way to find
> out if it retrieved a populated value. Checks for zero values don't work
> because exit_code and stage could both be zero and valid. So I added an
> extra field to check that.

Of course, for some reason I had in my mind a full array with a search 
for the index, not a sparse array with direct access.

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


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

* Re: [PATCH 01/13] KVM: x86 emulator: add framework for instruction
  2011-03-25  9:29 ` [PATCH 01/13] KVM: x86 emulator: add framework for instruction Joerg Roedel
  2011-03-26  9:54   ` Avi Kivity
@ 2011-03-27 12:56   ` Gleb Natapov
  2011-03-28 10:19     ` Joerg Roedel
  1 sibling, 1 reply; 29+ messages in thread
From: Gleb Natapov @ 2011-03-27 12:56 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: Avi Kivity, Marcelo Tosatti, kvm

On Fri, Mar 25, 2011 at 10:29:04AM +0100, Joerg Roedel wrote:
> @@ -259,6 +267,18 @@ struct x86_emulate_ctxt {
>  #define X86EMUL_MODE_PROT32   4	/* 32-bit protected mode. */
>  #define X86EMUL_MODE_PROT64   8	/* 64-bit (long) mode.    */
>  
> +enum x86_intercept_stage {
> +	x86_icpt_pre_except,
> +	x86_icpt_post_except,
> +	x86_icpt_post_memaccess,
> +};
> +
> +enum x86_intercept {
> +	x86_intercept_none,
> +
> +	nr_x86_intercepts
> +};
> +
Can we name enums in upper case please?

--
			Gleb.

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

* Re: [PATCH 01/13] KVM: x86 emulator: add framework for instruction
  2011-03-27 12:56   ` Gleb Natapov
@ 2011-03-28 10:19     ` Joerg Roedel
  0 siblings, 0 replies; 29+ messages in thread
From: Joerg Roedel @ 2011-03-28 10:19 UTC (permalink / raw)
  To: Gleb Natapov; +Cc: Joerg Roedel, Avi Kivity, Marcelo Tosatti, kvm

On Sun, Mar 27, 2011 at 02:56:56PM +0200, Gleb Natapov wrote:
> On Fri, Mar 25, 2011 at 10:29:04AM +0100, Joerg Roedel wrote:
> > @@ -259,6 +267,18 @@ struct x86_emulate_ctxt {
> >  #define X86EMUL_MODE_PROT32   4	/* 32-bit protected mode. */
> >  #define X86EMUL_MODE_PROT64   8	/* 64-bit (long) mode.    */
> >  
> > +enum x86_intercept_stage {
> > +	x86_icpt_pre_except,
> > +	x86_icpt_post_except,
> > +	x86_icpt_post_memaccess,
> > +};
> > +
> > +enum x86_intercept {
> > +	x86_intercept_none,
> > +
> > +	nr_x86_intercepts
> > +};
> > +
> Can we name enums in upper case please?

Just did a quick grep and it seems that both, upper and lower case is
used in enums throughout the kernel. It makes certainly sense to have it
in upper case to make a visual distinction between constants and
variables, but for the x86_intercept enum this means clobbering the
opcode-tables in the emulator with upper-case strings making them less
readable imo.
But I change x86_intercept_stage to upper-case in the next version.

	Joerg


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

* [PATCH 07/13] KVM: SVM: Add intercept checks for descriptor table accesses
  2011-03-28 10:46 [PATCH 0/13] KVM: Make the instruction emulator aware of Nested Virtualization v3 Joerg Roedel
@ 2011-03-28 10:46 ` Joerg Roedel
  2011-03-28 12:35   ` Avi Kivity
  0 siblings, 1 reply; 29+ messages in thread
From: Joerg Roedel @ 2011-03-28 10:46 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, Joerg Roedel

This patch add intercept checks into the KVM instruction
emulator to check for the 8 instructions that access the
descriptor table addresses.

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

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index e589bcc..ec2e9ad 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2390,8 +2390,17 @@ static struct opcode group5[] = {
 	D(SrcMem | ModRM | Stack), N,
 };
 
+static struct opcode group6[] = {
+	DI(ModRM,	 sldt),
+	DI(ModRM,	 str),
+	DI(ModRM | Priv, lldt),
+	DI(ModRM | Priv, ltr),
+	N, N, N, N,
+};
+
 static struct group_dual group7 = { {
-	N, N, DI(ModRM | SrcMem | Priv, lgdt), DI(ModRM | SrcMem | Priv, lidt),
+	DI(ModRM | DstMem | Priv, sgdt), DI(ModRM | DstMem | Priv, sidt),
+	DI(ModRM | SrcMem | Priv, lgdt), DI(ModRM | SrcMem | Priv, lidt),
 	DI(SrcNone | ModRM | DstMem | Mov, smsw), N,
 	DI(SrcMem16 | ModRM | Mov | Priv, lmsw),
 	DI(SrcMem | ModRM | ByteOp | Priv | NoAccess, invlpg),
@@ -2522,7 +2531,7 @@ static struct opcode opcode_table[256] = {
 
 static struct opcode twobyte_table[256] = {
 	/* 0x00 - 0x0F */
-	N, GD(0, &group7), N, N,
+	G(0, group6), GD(0, &group7), N, N,
 	N, D(ImplicitOps | VendorSpecific), DI(ImplicitOps | Priv, clts), N,
 	DI(ImplicitOps | Priv, invd), DI(ImplicitOps | Priv, wbinvd), N, N,
 	N, D(ImplicitOps | ModRM), N, N,
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 381b038..485a09f 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -3871,6 +3871,10 @@ static void svm_fpu_deactivate(struct kvm_vcpu *vcpu)
 #define POST_EX(exit) { .exit_code = (exit), \
 			.stage = X86_ICPT_POST_EXCEPT, \
 			.valid = true }
+#define POST_MEM(exit) { .exit_code = (exit), \
+			 .stage = X86_ICPT_POST_MEMACCESS, \
+			 .valid = true }
+
 
 static struct __x86_intercept {
 	u32 exit_code;
@@ -3884,9 +3888,18 @@ static struct __x86_intercept {
 	[x86_intercept_smsw]		= POST_EX(SVM_EXIT_READ_CR0),
 	[x86_intercept_dr_read]		= POST_EX(SVM_EXIT_READ_DR0),
 	[x86_intercept_dr_write]	= POST_EX(SVM_EXIT_WRITE_DR0),
+	[x86_intercept_sldt]		= POST_MEM(SVM_EXIT_LDTR_READ),
+	[x86_intercept_str]		= POST_MEM(SVM_EXIT_TR_READ),
+	[x86_intercept_lldt]		= POST_MEM(SVM_EXIT_LDTR_WRITE),
+	[x86_intercept_ltr]		= POST_MEM(SVM_EXIT_TR_WRITE),
+	[x86_intercept_sgdt]		= POST_MEM(SVM_EXIT_GDTR_READ),
+	[x86_intercept_sidt]		= POST_MEM(SVM_EXIT_IDTR_READ),
+	[x86_intercept_lgdt]		= POST_MEM(SVM_EXIT_GDTR_WRITE),
+	[x86_intercept_lidt]		= POST_MEM(SVM_EXIT_IDTR_WRITE),
 };
 
 #undef POST_EX
+#undef POST_MEM
 
 static int svm_check_intercept(struct kvm_vcpu *vcpu,
 			       struct x86_instruction_info *info,
-- 
1.7.1



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

* Re: [PATCH 07/13] KVM: SVM: Add intercept checks for descriptor table accesses
  2011-03-28 10:46 ` [PATCH 07/13] KVM: SVM: Add intercept checks for descriptor table accesses Joerg Roedel
@ 2011-03-28 12:35   ` Avi Kivity
  2011-03-28 13:56     ` Roedel, Joerg
  0 siblings, 1 reply; 29+ messages in thread
From: Avi Kivity @ 2011-03-28 12:35 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: Marcelo Tosatti, kvm

On 03/28/2011 12:46 PM, Joerg Roedel wrote:
> This patch add intercept checks into the KVM instruction
> emulator to check for the 8 instructions that access the
> descriptor table addresses.
>
> +static struct opcode group6[] = {
> +	DI(ModRM,	 sldt),
> +	DI(ModRM,	 str),
> +	DI(ModRM | Priv, lldt),
> +	DI(ModRM | Priv, ltr),
> +	N, N, N, N,
> +};
> +
>   static struct group_dual group7 = { {
> -	N, N, DI(ModRM | SrcMem | Priv, lgdt), DI(ModRM | SrcMem | Priv, lidt),
> +	DI(ModRM | DstMem | Priv, sgdt), DI(ModRM | DstMem | Priv, sidt),
> +	DI(ModRM | SrcMem | Priv, lgdt), DI(ModRM | SrcMem | Priv, lidt),

| Mov, to avoid RMW for SIDT, for example.  Also need to indicate the 
operand size correctly.

> diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
> index 381b038..485a09f 100644
> --- a/arch/x86/kvm/svm.c
> +++ b/arch/x86/kvm/svm.c
> @@ -3871,6 +3871,10 @@ static void svm_fpu_deactivate(struct kvm_vcpu *vcpu)
>   #define POST_EX(exit) { .exit_code = (exit), \
>   			.stage = X86_ICPT_POST_EXCEPT, \
>   			.valid = true }
> +#define POST_MEM(exit) { .exit_code = (exit), \
> +			 .stage = X86_ICPT_POST_MEMACCESS, \
> +			 .valid = true }
> +
>
>   static struct __x86_intercept {
>   	u32 exit_code;
> @@ -3884,9 +3888,18 @@ static struct __x86_intercept {
>   	[x86_intercept_smsw]		= POST_EX(SVM_EXIT_READ_CR0),
>   	[x86_intercept_dr_read]		= POST_EX(SVM_EXIT_READ_DR0),
>   	[x86_intercept_dr_write]	= POST_EX(SVM_EXIT_WRITE_DR0),
> +	[x86_intercept_sldt]		= POST_MEM(SVM_EXIT_LDTR_READ),
> +	[x86_intercept_str]		= POST_MEM(SVM_EXIT_TR_READ),
> +	[x86_intercept_lldt]		= POST_MEM(SVM_EXIT_LDTR_WRITE),
> +	[x86_intercept_ltr]		= POST_MEM(SVM_EXIT_TR_WRITE),
> +	[x86_intercept_sgdt]		= POST_MEM(SVM_EXIT_GDTR_READ),
> +	[x86_intercept_sidt]		= POST_MEM(SVM_EXIT_IDTR_READ),
> +	[x86_intercept_lgdt]		= POST_MEM(SVM_EXIT_GDTR_WRITE),
> +	[x86_intercept_lidt]		= POST_MEM(SVM_EXIT_IDTR_WRITE),
>   };

Spec says POST_EX()?

>
>   #undef POST_EX
> +#undef POST_MEM
>
>   static int svm_check_intercept(struct kvm_vcpu *vcpu,
>   			       struct x86_instruction_info *info,


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


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

* Re: [PATCH 07/13] KVM: SVM: Add intercept checks for descriptor table accesses
  2011-03-28 12:35   ` Avi Kivity
@ 2011-03-28 13:56     ` Roedel, Joerg
  2011-03-28 14:34       ` Avi Kivity
  0 siblings, 1 reply; 29+ messages in thread
From: Roedel, Joerg @ 2011-03-28 13:56 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Marcelo Tosatti, kvm@vger.kernel.org

On Mon, Mar 28, 2011 at 08:35:54AM -0400, Avi Kivity wrote:
> On 03/28/2011 12:46 PM, Joerg Roedel wrote:
> > This patch add intercept checks into the KVM instruction
> > emulator to check for the 8 instructions that access the
> > descriptor table addresses.
> >
> > +static struct opcode group6[] = {
> > +	DI(ModRM,	 sldt),
> > +	DI(ModRM,	 str),
> > +	DI(ModRM | Priv, lldt),
> > +	DI(ModRM | Priv, ltr),
> > +	N, N, N, N,
> > +};
> > +
> >   static struct group_dual group7 = { {
> > -	N, N, DI(ModRM | SrcMem | Priv, lgdt), DI(ModRM | SrcMem | Priv, lidt),
> > +	DI(ModRM | DstMem | Priv, sgdt), DI(ModRM | DstMem | Priv, sidt),
> > +	DI(ModRM | SrcMem | Priv, lgdt), DI(ModRM | SrcMem | Priv, lidt),
> 
> | Mov, to avoid RMW for SIDT, for example.  Also need to indicate the 
> operand size correctly.
> 
> > diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
> > index 381b038..485a09f 100644
> > --- a/arch/x86/kvm/svm.c
> > +++ b/arch/x86/kvm/svm.c
> > @@ -3871,6 +3871,10 @@ static void svm_fpu_deactivate(struct kvm_vcpu *vcpu)
> >   #define POST_EX(exit) { .exit_code = (exit), \
> >   			.stage = X86_ICPT_POST_EXCEPT, \
> >   			.valid = true }
> > +#define POST_MEM(exit) { .exit_code = (exit), \
> > +			 .stage = X86_ICPT_POST_MEMACCESS, \
> > +			 .valid = true }
> > +
> >
> >   static struct __x86_intercept {
> >   	u32 exit_code;
> > @@ -3884,9 +3888,18 @@ static struct __x86_intercept {
> >   	[x86_intercept_smsw]		= POST_EX(SVM_EXIT_READ_CR0),
> >   	[x86_intercept_dr_read]		= POST_EX(SVM_EXIT_READ_DR0),
> >   	[x86_intercept_dr_write]	= POST_EX(SVM_EXIT_WRITE_DR0),
> > +	[x86_intercept_sldt]		= POST_MEM(SVM_EXIT_LDTR_READ),
> > +	[x86_intercept_str]		= POST_MEM(SVM_EXIT_TR_READ),
> > +	[x86_intercept_lldt]		= POST_MEM(SVM_EXIT_LDTR_WRITE),
> > +	[x86_intercept_ltr]		= POST_MEM(SVM_EXIT_TR_WRITE),
> > +	[x86_intercept_sgdt]		= POST_MEM(SVM_EXIT_GDTR_READ),
> > +	[x86_intercept_sidt]		= POST_MEM(SVM_EXIT_IDTR_READ),
> > +	[x86_intercept_lgdt]		= POST_MEM(SVM_EXIT_GDTR_WRITE),
> > +	[x86_intercept_lidt]		= POST_MEM(SVM_EXIT_IDTR_WRITE),
> >   };
> 
> Spec says POST_EX()?

Well, not entirely clear. Spec says that #GP takes precedence before the
intercept and the intruction reference says the #GP fires if the
supplied address is not within segment limits or the segment itself is
not valid, which, in my interpretation, made them POST_MEM.

	Joerg

-- 
AMD Operating System Research Center

Advanced Micro Devices GmbH Einsteinring 24 85609 Dornach
General Managers: Alberto Bozzo, Andrew Bowd
Registration: Dornach, Landkr. Muenchen; Registerger. Muenchen, HRB Nr. 43632


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

* Re: [PATCH 07/13] KVM: SVM: Add intercept checks for descriptor table accesses
  2011-03-28 13:56     ` Roedel, Joerg
@ 2011-03-28 14:34       ` Avi Kivity
  0 siblings, 0 replies; 29+ messages in thread
From: Avi Kivity @ 2011-03-28 14:34 UTC (permalink / raw)
  To: Roedel, Joerg; +Cc: Marcelo Tosatti, kvm@vger.kernel.org

On 03/28/2011 03:56 PM, Roedel, Joerg wrote:
> On Mon, Mar 28, 2011 at 08:35:54AM -0400, Avi Kivity wrote:
> >  On 03/28/2011 12:46 PM, Joerg Roedel wrote:
> >  >  This patch add intercept checks into the KVM instruction
> >  >  emulator to check for the 8 instructions that access the
> >  >  descriptor table addresses.
> >  >
> >  >  +static struct opcode group6[] = {
> >  >  +	DI(ModRM,	 sldt),
> >  >  +	DI(ModRM,	 str),
> >  >  +	DI(ModRM | Priv, lldt),
> >  >  +	DI(ModRM | Priv, ltr),
> >  >  +	N, N, N, N,
> >  >  +};
> >  >  +
> >  >    static struct group_dual group7 = { {
> >  >  -	N, N, DI(ModRM | SrcMem | Priv, lgdt), DI(ModRM | SrcMem | Priv, lidt),
> >  >  +	DI(ModRM | DstMem | Priv, sgdt), DI(ModRM | DstMem | Priv, sidt),
> >  >  +	DI(ModRM | SrcMem | Priv, lgdt), DI(ModRM | SrcMem | Priv, lidt),
> >
> >  | Mov, to avoid RMW for SIDT, for example.  Also need to indicate the
> >  operand size correctly.
> >
> >  >  diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
> >  >  index 381b038..485a09f 100644
> >  >  --- a/arch/x86/kvm/svm.c
> >  >  +++ b/arch/x86/kvm/svm.c
> >  >  @@ -3871,6 +3871,10 @@ static void svm_fpu_deactivate(struct kvm_vcpu *vcpu)
> >  >    #define POST_EX(exit) { .exit_code = (exit), \
> >  >    			.stage = X86_ICPT_POST_EXCEPT, \
> >  >    			.valid = true }
> >  >  +#define POST_MEM(exit) { .exit_code = (exit), \
> >  >  +			 .stage = X86_ICPT_POST_MEMACCESS, \
> >  >  +			 .valid = true }
> >  >  +
> >  >
> >  >    static struct __x86_intercept {
> >  >    	u32 exit_code;
> >  >  @@ -3884,9 +3888,18 @@ static struct __x86_intercept {
> >  >    	[x86_intercept_smsw]		= POST_EX(SVM_EXIT_READ_CR0),
> >  >    	[x86_intercept_dr_read]		= POST_EX(SVM_EXIT_READ_DR0),
> >  >    	[x86_intercept_dr_write]	= POST_EX(SVM_EXIT_WRITE_DR0),
> >  >  +	[x86_intercept_sldt]		= POST_MEM(SVM_EXIT_LDTR_READ),
> >  >  +	[x86_intercept_str]		= POST_MEM(SVM_EXIT_TR_READ),
> >  >  +	[x86_intercept_lldt]		= POST_MEM(SVM_EXIT_LDTR_WRITE),
> >  >  +	[x86_intercept_ltr]		= POST_MEM(SVM_EXIT_TR_WRITE),
> >  >  +	[x86_intercept_sgdt]		= POST_MEM(SVM_EXIT_GDTR_READ),
> >  >  +	[x86_intercept_sidt]		= POST_MEM(SVM_EXIT_IDTR_READ),
> >  >  +	[x86_intercept_lgdt]		= POST_MEM(SVM_EXIT_GDTR_WRITE),
> >  >  +	[x86_intercept_lidt]		= POST_MEM(SVM_EXIT_IDTR_WRITE),
> >  >    };
> >
> >  Spec says POST_EX()?
>
> Well, not entirely clear. Spec says that #GP takes precedence before the
> intercept and the intruction reference says the #GP fires if the
> supplied address is not within segment limits or the segment itself is
> not valid, which, in my interpretation, made them POST_MEM.

My interpretation would be that a #GP(0) due to CPL check takes 
precedence over the intercept, which takes precedence over a 
#GP(selector) due to the actual memory reference.

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


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

end of thread, other threads:[~2011-03-28 14:34 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-03-25  9:29 [PATCH 0/13] KVM: Make the instruction emulator aware of Nested Virtualization v2 Joerg Roedel
2011-03-25  9:29 ` [PATCH 01/13] KVM: x86 emulator: add framework for instruction Joerg Roedel
2011-03-26  9:54   ` Avi Kivity
2011-03-27 12:56   ` Gleb Natapov
2011-03-28 10:19     ` Joerg Roedel
2011-03-25  9:29 ` [PATCH 02/13] KVM: x86 emulator: add SVM intercepts Joerg Roedel
2011-03-25  9:29 ` [PATCH 03/13] KVM: X86: Don't write-back cpu-state on X86EMUL_INTERCEPTED Joerg Roedel
2011-03-25  9:29 ` [PATCH 04/13] KVM: X86: Add x86 callback for intercept check Joerg Roedel
2011-03-26  9:23   ` Avi Kivity
2011-03-25  9:29 ` [PATCH 05/13] KVM: SVM: Add intercept check for emulated cr accesses Joerg Roedel
2011-03-26  9:37   ` Avi Kivity
2011-03-26 11:06     ` Joerg Roedel
2011-03-27  9:45       ` Avi Kivity
2011-03-25  9:29 ` [PATCH 06/13] KVM: SVM: Add intercept check for accessing dr registers Joerg Roedel
2011-03-25  9:29 ` [PATCH 07/13] KVM: SVM: Add intercept checks for descriptor table accesses Joerg Roedel
2011-03-26  9:43   ` Avi Kivity
2011-03-26 11:10     ` Joerg Roedel
2011-03-25  9:29 ` [PATCH 08/13] KVM: SVM: Add intercept checks for SVM instructions Joerg Roedel
2011-03-25  9:29 ` [PATCH 09/13] KVM: SVM: Add intercept checks for remaining group7 instructions Joerg Roedel
2011-03-25  9:29 ` [PATCH 10/13] KVM: SVM: Add intercept checks for remaining twobyte instructions Joerg Roedel
2011-03-25  9:29 ` [PATCH 11/13] KVM: SVM: Add intercept checks for one-byte instructions Joerg Roedel
2011-03-26  9:53   ` Avi Kivity
2011-03-25  9:29 ` [PATCH 12/13] KVM: SVM: Add checks for IO instructions Joerg Roedel
2011-03-25  9:29 ` [PATCH 13/13] KVM: SVM: Remove nested sel_cr0_write handling code Joerg Roedel
2011-03-26  9:55 ` [PATCH 0/13] KVM: Make the instruction emulator aware of Nested Virtualization v2 Avi Kivity
  -- strict thread matches above, loose matches on Subject: below --
2011-03-28 10:46 [PATCH 0/13] KVM: Make the instruction emulator aware of Nested Virtualization v3 Joerg Roedel
2011-03-28 10:46 ` [PATCH 07/13] KVM: SVM: Add intercept checks for descriptor table accesses Joerg Roedel
2011-03-28 12:35   ` Avi Kivity
2011-03-28 13:56     ` Roedel, Joerg
2011-03-28 14:34       ` Avi Kivity

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).