login
Header Space

 
 

[PATCH 052/104] KVM: Cleanup string I/O instruction emulation

Previous thread: none

Next thread: [PATCH -rc] KVM: Fix virtualization menu help text by Avi Kivity on Monday, September 17, 2007 - 5:10 am. (2 messages)
To: <kvm-devel@...>
Cc: <linux-kernel@...>
Date: Monday, September 17, 2007 - 4:30 am

The following represents the patch queue for the 2.6.24, posted here for
review.  Most of the patches have already been on kvm-devel (and all of
them on kvm-commits), but some folding has occured to merge fixes
and to make the whole series bisect-friendly.

A few patches are likely to change in the near future; they will be reposted
if they do.

The most visible new feature is the in-kernel lapic/ioapic/pic emulation;
others include making kvm preemptible (a first step for guest swapping),
additional x86 emulator work, and Rusty Unleashed.

Amit Shah (1):
      KVM: Set the ET flag in CR0 after initializing FX

Aurelien Jarno (1):
      KVM: Remove dead code in the cmpxchg instruction emulation

Avi Kivity (11):
      KVM: Future-proof the exit information union ABI
      KVM: x86 emulator: fix cmov for writeback changes
      KVM: x86 emulator: fix faulty check for two-byte opcode
      KVM: Use the scheduler preemption notifiers to make kvm preemptible
      KVM: Close minor race in signal handling
      KVM: X86 emulator: fix 'push reg' writeback
      KVM: MMU: Don't do GFP_NOWAIT allocations
      KVM: VMX: Move vm entry failure handling to the exit handler
      KVM: Move main vcpu loop into subarch independent code
      KVM: Improve emulation failure reporting
      KVM: Skip pio instruction when it is emulated, not executed

Christian Ehrhardt (1):
      KVM: Rename kvm_arch_ops to kvm_x86_ops

Eddie Dong (11):
      KVM: In-kernel string pio write support
      KVM: Add support for in-kernel PIC emulation
      KVM: Define and use cr8 access functions
      KVM: Emulate local APIC in kernel
      KVM: In-kernel I/O APIC model
      KVM: Emulate hlt in the kernel
      KVM: Protect in-kernel pio using kvm-&gt;lock
      KVM: in-kernel LAPIC save and restore support
      KVM: pending irq save/restore
      KVM: Keep track of missed timer irq injections
      KVM: Migrate lapic hrtimer when vcpu moves to another cpu

Gabriel C (1):
      KVM: Fix defined but...
To: Avi Kivity <avi@...>
Cc: <linux-kernel@...>, <git@...>
Date: Monday, September 17, 2007 - 11:59 am

The following might be a bug in git-send-email (git maintainers Cc'ed
and KVM list removed from Cc): 

Patch 54 got the same Message-Id as patch 61 and patch 89 got the same 
Message-Id as patch 104.

That's not legal, and users who automatically filter duplicate emails 
based on the Message-Id will not see two of the patches.

The emails are:
http://marc.info/?l=linux-kernel&amp;m=119002061330270&amp;w=2
http://marc.info/?l=linux-kernel&amp;m=119002059626434&amp;w=2
http://marc.info/?l=linux-kernel&amp;m=119002060011801&amp;w=2
http://marc.info/?l=linux-kernel&amp;m=119002060318915&amp;w=2

cu
Adrian

-- 

       "Is there not promise of rain?" Ling Tan asked suddenly out
        of the darkness. There had been need of rain for many days.
       "Only a promise," Lao Er said.
                                       Pearl S. Buck - Dragon Seed

-
To: Adrian Bunk <bunk@...>
Cc: Avi Kivity <avi@...>, <linux-kernel@...>, <git@...>
Date: Monday, September 17, 2007 - 4:22 pm

The old code generated rand(4200) for each message and appended
it to the timestamp.  I do not know where the original author
got 4200 from, but I think if you send many messages within a
single second it is possible to get collisions.

I guess something like this patch is an improvement?  It
generates a single prefix from timestamp and random, and appends
a number that is incremented for each message.

---
diff --git a/git-send-email.perl b/git-send-email.perl
index dd7560b..e250732 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -477,10 +477,18 @@ sub extract_valid_address {
 
 # We'll setup a template for the message id, using the "from" address:
 
+my ($message_id_stamp, $message_id_serial);
 sub make_message_id
 {
-	my $date = time;
-	my $pseudo_rand = int (rand(4200));
+	my $uniq;
+	if (!defined $message_id_stamp) {
+		$message_id_stamp = sprintf("%s-%s", time, int(rand(4200)));
+		$message_id_serial = 0;
+	}
+	$message_id_serial++;
+
+	$uniq = "$message_id_stamp-$message_id_serial";
+
 	my $du_part;
 	for ($sender, $repocommitter, $repoauthor) {
 		$du_part = extract_valid_address(sanitize_address($_));
@@ -490,8 +498,8 @@ sub make_message_id
 		use Sys::Hostname qw();
 		$du_part = 'user@' . Sys::Hostname::hostname();
 	}
-	my $message_id_template = "&lt;%s-git-send-email-$du_part&gt;";
-	$message_id = sprintf $message_id_template, "$date$pseudo_rand";
+	my $message_id_template = "&lt;%s-git-send-email-%s&gt;";
+	$message_id = sprintf($message_id_template, $uniq, $du_part);
 	#print "new message id = $message_id\n"; # Was useful for debugging
 }
 
-
To: Junio C Hamano <gitster@...>
Cc: Adrian Bunk <bunk@...>, Avi Kivity <avi@...>, <linux-kernel@...>, <git@...>
Date: Monday, September 17, 2007 - 4:47 pm

Much better.   You may also consider a possibility of
letting your local MTA do the  Message-ID generation, unless
you are tracking something with it and thus need to know the
generated values.  .. but apparently git much prefers sending
email by SMTP, where the message-id must be present, or one
really should block any such emails..  (except that systems
like qmail send error messages without message-id ...)

My own recipe is:
       sprintf("%d-%d-%d", time , getpid, ++localsequence)
catenate on that your favourite domain name where that recipe
is likely to be valid, and you are all set.


  /Matti Aarnio  --  one of  &lt;postmaster@vger.kernel.org&gt;
-
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Rusty Russell <rusty@...>
Date: Monday, September 17, 2007 - 4:30 am

From: Rusty Russell &lt;rusty@rustcorp.com.au&gt;

Speling error in comment.

Signed-off-by: Rusty Russell &lt;rusty@rustcorp.com.au&gt;
Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/x86_emulate.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index f5e4644..db9f955 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -6,7 +6,7 @@
  * Copyright (c) 2005 Keir Fraser
  *
  * Linux coding style, mod r/m decoder, segment base fixes, real-mode
- * privieged instructions:
+ * privileged instructions:
  *
  * Copyright (C) 2006 Qumranet
  *
-- 
1.5.3

-
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Rusty Russell <rusty@...>
Date: Monday, September 17, 2007 - 4:30 am

From: Rusty Russell &lt;rusty@rustcorp.com.au&gt;

The kernel now has asm/cpu-features.h: use those macros instead of inventing
our own.

Also spell out definition of CR3_RESEVED_BITS, fix spelling and
tighten it for the non-PAE case.

Signed-off-by: Rusty Russell &lt;rusty@rustcorp.com.au&gt;
Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/kvm.h         |    9 +++------
 drivers/kvm/kvm_main.c    |   33 +++++++++++++++++++++------------
 drivers/kvm/paging_tmpl.h |    2 +-
 3 files changed, 25 insertions(+), 19 deletions(-)

diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index 7117c3b..983c33f 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -19,12 +19,9 @@
 #include &lt;linux/kvm.h&gt;
 #include &lt;linux/kvm_para.h&gt;
 
-#define CR3_WPT_MASK (1ULL &lt;&lt; 3)
-#define CR3_PCD_MASK (1ULL &lt;&lt; 4)
-
-#define CR3_RESEVED_BITS 0x07ULL
-#define CR3_L_MODE_RESEVED_BITS (~((1ULL &lt;&lt; 40) - 1) | 0x0fe7ULL)
-#define CR3_FLAGS_MASK ((1ULL &lt;&lt; 5) - 1)
+#define CR3_PAE_RESERVED_BITS ((X86_CR3_PWT | X86_CR3_PCD) - 1)
+#define CR3_NONPAE_RESERVED_BITS ((PAGE_SIZE-1) &amp; ~(X86_CR3_PWT | X86_CR3_PCD))
+#define CR3_L_MODE_RESERVED_BITS (CR3_NONPAE_RESERVED_BITS|0xFFFFFF0000000000ULL)
 
 #define CR4_VME_MASK (1ULL &lt;&lt; 0)
 #define CR4_PSE_MASK (1ULL &lt;&lt; 4)
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 5d8febe..34a571d 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -571,23 +571,32 @@ EXPORT_SYMBOL_GPL(set_cr4);
 void set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
 {
 	if (is_long_mode(vcpu)) {
-		if (cr3 &amp; CR3_L_MODE_RESEVED_BITS) {
+		if (cr3 &amp; CR3_L_MODE_RESERVED_BITS) {
 			printk(KERN_DEBUG "set_cr3: #GP, reserved bits\n");
 			inject_gp(vcpu);
 			return;
 		}
 	} else {
-		if (cr3 &amp; CR3_RESEVED_BITS) {
-			printk(KERN_DEBUG "set_cr3: #GP, reserved bits\n");
-			inject_gp(vcpu);
-			return;
-		}
-		if (is_paging(vcpu) &amp;&amp; is_pae(vcpu) &amp;&amp;
-		...
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Jeff Dike <jdike@...>
Date: Monday, September 17, 2007 - 4:30 am

From: Jeff Dike &lt;jdike@addtoit.com&gt;

Signed-off-by: Jeff Dike &lt;jdike@linux.intel.com&gt;
Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/kvm_main.c |    2 +-
 drivers/kvm/svm.c      |    1 -
 drivers/kvm/vmx.c      |    1 -
 3 files changed, 1 insertions(+), 3 deletions(-)

diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index fc63de2..193197f 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -1276,6 +1276,7 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
 	r = x86_emulate_memop(&amp;emulate_ctxt, &amp;emulate_ops);
 
 	if ((r || vcpu-&gt;mmio_is_write) &amp;&amp; run) {
+		run-&gt;exit_reason = KVM_EXIT_MMIO;
 		run-&gt;mmio.phys_addr = vcpu-&gt;mmio_phys_addr;
 		memcpy(run-&gt;mmio.data, vcpu-&gt;mmio_data, 8);
 		run-&gt;mmio.len = vcpu-&gt;mmio_size;
@@ -1937,7 +1938,6 @@ static int kvm_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 			/*
 			 * Read-modify-write.  Back to userspace.
 			 */
-			kvm_run-&gt;exit_reason = KVM_EXIT_MMIO;
 			r = 0;
 			goto out;
 		}
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
index 5c058fa..850a1b1 100644
--- a/drivers/kvm/svm.c
+++ b/drivers/kvm/svm.c
@@ -928,7 +928,6 @@ static int pf_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 		return 1;
 	case EMULATE_DO_MMIO:
 		++vcpu-&gt;stat.mmio_exits;
-		kvm_run-&gt;exit_reason = KVM_EXIT_MMIO;
 		return 0;
 	case EMULATE_FAIL:
 		vcpu_printf(vcpu, "%s: emulate fail\n", __FUNCTION__);
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index f3e7818..2c4f01b 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -1610,7 +1610,6 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 			return 1;
 		case EMULATE_DO_MMIO:
 			++vcpu-&gt;stat.mmio_exits;
-			kvm_run-&gt;exit_reason = KVM_EXIT_MMIO;
 			return 0;
 		 case EMULATE_FAIL:
 			vcpu_printf(vcpu, "%s: emulate fail\n", __FUNCTION__);
-- 
1.5.3

-
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Rusty Russell <rusty@...>
Date: Monday, September 17, 2007 - 4:30 am

From: Rusty Russell &lt;rusty@rustcorp.com.au&gt;

On this machine (Intel), writing to the CR4 bits 0x00000800 and
0x00001000 cause a GPF.  The Intel manual is a little unclear, but
AFIACT they're reserved, too.

Also fix spelling of CR4_RESEVED_BITS.

Signed-off-by: Rusty Russell &lt;rusty@rustcorp.com.au&gt;
Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/kvm.h      |   16 +++++-----------
 drivers/kvm/kvm_main.c |   16 ++++++++++------
 drivers/kvm/svm.c      |    7 +++----
 drivers/kvm/vmx.c      |    8 ++++----
 drivers/kvm/vmx.h      |    2 --
 5 files changed, 22 insertions(+), 27 deletions(-)

diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index 983c33f..25439a5 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -23,12 +23,6 @@
 #define CR3_NONPAE_RESERVED_BITS ((PAGE_SIZE-1) &amp; ~(X86_CR3_PWT | X86_CR3_PCD))
 #define CR3_L_MODE_RESERVED_BITS (CR3_NONPAE_RESERVED_BITS|0xFFFFFF0000000000ULL)
 
-#define CR4_VME_MASK (1ULL &lt;&lt; 0)
-#define CR4_PSE_MASK (1ULL &lt;&lt; 4)
-#define CR4_PAE_MASK (1ULL &lt;&lt; 5)
-#define CR4_PGE_MASK (1ULL &lt;&lt; 7)
-#define CR4_VMXE_MASK (1ULL &lt;&lt; 13)
-
 #define KVM_GUEST_CR0_MASK \
 	(X86_CR0_PG | X86_CR0_PE | X86_CR0_WP | X86_CR0_NE \
 	 | X86_CR0_NW | X86_CR0_CD)
@@ -36,9 +30,9 @@
 	(X86_CR0_PG | X86_CR0_PE | X86_CR0_WP | X86_CR0_NE | X86_CR0_TS \
 	 | X86_CR0_MP)
 #define KVM_GUEST_CR4_MASK \
-	(CR4_PSE_MASK | CR4_PAE_MASK | CR4_PGE_MASK | CR4_VMXE_MASK | CR4_VME_MASK)
-#define KVM_PMODE_VM_CR4_ALWAYS_ON (CR4_VMXE_MASK | CR4_PAE_MASK)
-#define KVM_RMODE_VM_CR4_ALWAYS_ON (CR4_VMXE_MASK | CR4_PAE_MASK | CR4_VME_MASK)
+	(X86_CR4_VME | X86_CR4_PSE | X86_CR4_PAE | X86_CR4_PGE | X86_CR4_VMXE)
+#define KVM_PMODE_VM_CR4_ALWAYS_ON (X86_CR4_PAE | X86_CR4_VMXE)
+#define KVM_RMODE_VM_CR4_ALWAYS_ON (X86_CR4_VME | X86_CR4_PAE | X86_CR4_VMXE)
 
 #define INVALID_PAGE (~(hpa_t)0)
 #define UNMAPPED_GVA (~(gpa_t)0)
@@ -645,12 +639,12 @@ static inline int is_long_mode(struct kvm_vcpu *vcpu)
 
 static...
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Rusty Russell <rusty@...>
Date: Monday, September 17, 2007 - 4:30 am

From: Rusty Russell &lt;rusty@rustcorp.com.au&gt;

Intel manual (and KVM definition) say the TPR is 4 bits wide.  Also fix
CR8_RESEVED_BITS typo.

Signed-off-by: Rusty Russell &lt;rusty@rustcorp.com.au&gt;
Acked-by: H. Peter Anvin &lt;hpa@zytor.com&gt;
Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/kvm_main.c             |    4 ++--
 include/asm-i386/processor-flags.h |    2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 193197f..f0fc8d9 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -92,7 +92,7 @@ static struct dentry *debugfs_dir;
 			  | X86_CR4_PGE | X86_CR4_PCE | X86_CR4_OSFXSR	\
 			  | X86_CR4_OSXMMEXCPT | X86_CR4_VMXE))
 
-#define CR8_RESEVED_BITS (~0x0fULL)
+#define CR8_RESERVED_BITS (~(unsigned long)X86_CR8_TPR)
 #define EFER_RESERVED_BITS 0xfffffffffffff2fe
 
 #ifdef CONFIG_X86_64
@@ -625,7 +625,7 @@ EXPORT_SYMBOL_GPL(set_cr3);
 
 void set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8)
 {
-	if ( cr8 &amp; CR8_RESEVED_BITS) {
+	if (cr8 &amp; CR8_RESERVED_BITS) {
 		printk(KERN_DEBUG "set_cr8: #GP, reserved bits 0x%lx\n", cr8);
 		inject_gp(vcpu);
 		return;
diff --git a/include/asm-i386/processor-flags.h b/include/asm-i386/processor-flags.h
index 5404e90..199cab1 100644
--- a/include/asm-i386/processor-flags.h
+++ b/include/asm-i386/processor-flags.h
@@ -63,7 +63,7 @@
 /*
  * x86-64 Task Priority Register, CR8
  */
-#define X86_CR8_TPR	0x00000007 /* task priority register */
+#define X86_CR8_TPR	0x0000000F /* task priority register */
 
 /*
  * AMD and Transmeta use MSRs for configuration; see &lt;asm/msr-index.h&gt;
-- 
1.5.3

-
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Rusty Russell <rusty@...>
Date: Monday, September 17, 2007 - 4:31 am

From: Rusty Russell &lt;rusty@rustcorp.com.au&gt;

Don't fall through and turn on PAE in this case.

Signed-off-by: Rusty Russell &lt;rusty@rustcorp.com.au&gt;
Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/kvm_main.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index f0fc8d9..093cea3 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -558,6 +558,7 @@ void set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
 		   &amp;&amp; !load_pdptrs(vcpu, vcpu-&gt;cr3)) {
 		printk(KERN_DEBUG "set_cr4: #GP, pdptrs reserved bits\n");
 		inject_gp(vcpu);
+		return;
 	}
 
 	if (cr4 &amp; X86_CR4_VMXE) {
-- 
1.5.3

-
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Rusty Russell <rusty@...>
Date: Monday, September 17, 2007 - 4:31 am

From: Rusty Russell &lt;rusty@rustcorp.com.au&gt;

load_pdptrs can be handed an invalid cr3, and it should not oops.
This can happen because we injected #gp in set_cr3() after we set
vcpu-&gt;cr3 to the invalid value, or from kvm_vcpu_ioctl_set_sregs(), or
memory configuration changes after the guest did set_cr3().

We should also copy the pdpte array once, before checking and
assigning, otherwise an SMP guest can potentially alter the values
between the check and the set.

Finally one nitpick: ret = 1 should be done as late as possible: this
allows GCC to check for unset "ret" should the function change in
future.

Signed-off-by: Rusty Russell &lt;rusty@rustcorp.com.au&gt;
Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/kvm_main.c |   22 ++++++++++++----------
 1 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 80ee427..65c9a31 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -442,30 +442,32 @@ static int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3)
 	gfn_t pdpt_gfn = cr3 &gt;&gt; PAGE_SHIFT;
 	unsigned offset = ((cr3 &amp; (PAGE_SIZE-1)) &gt;&gt; 5) &lt;&lt; 2;
 	int i;
-	u64 pdpte;
 	u64 *pdpt;
 	int ret;
 	struct page *page;
+	u64 pdpte[ARRAY_SIZE(vcpu-&gt;pdptrs)];
 
 	spin_lock(&amp;vcpu-&gt;kvm-&gt;lock);
 	page = gfn_to_page(vcpu-&gt;kvm, pdpt_gfn);
-	/* FIXME: !page - emulate? 0xff? */
+	if (!page) {
+		ret = 0;
+		goto out;
+	}
+
 	pdpt = kmap_atomic(page, KM_USER0);
+	memcpy(pdpte, pdpt+offset, sizeof(pdpte));
+	kunmap_atomic(pdpt, KM_USER0);
 
-	ret = 1;
-	for (i = 0; i &lt; 4; ++i) {
-		pdpte = pdpt[offset + i];
-		if ((pdpte &amp; 1) &amp;&amp; (pdpte &amp; 0xfffffff0000001e6ull)) {
+	for (i = 0; i &lt; ARRAY_SIZE(pdpte); ++i) {
+		if ((pdpte[i] &amp; 1) &amp;&amp; (pdpte[i] &amp; 0xfffffff0000001e6ull)) {
 			ret = 0;
 			goto out;
 		}
 	}
+	ret = 1;
 
-	for (i = 0; i &lt; 4; ++i)
-		vcpu-&gt;pdptrs[i] = pdpt[offset + i];
-...
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Yang, Sheng <sheng.yang@...>
Date: Monday, September 17, 2007 - 4:31 am

From: Yang, Sheng &lt;sheng.yang@intel.com&gt;

This patch mainly imports some constants and rename two exist constants
of vmcs according to IA32 SDM.

It also adds two constants to indicate Lock bit and Enable bit in
MSR_IA32_FEATURE_CONTROL, and replace the hardcode _5_ with these two
bits.

Signed-off-by: Sheng Yang &lt;sheng.yang@intel.com&gt;
Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/vmx.c |   16 +++++++++---
 drivers/kvm/vmx.h |   69 +++++++++++++++++++++++++++++++++--------------------
 2 files changed, 55 insertions(+), 30 deletions(-)

diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index 79674a7..dac2f93 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -751,7 +751,10 @@ static __init int vmx_disabled_by_bios(void)
 	u64 msr;
 
 	rdmsrl(MSR_IA32_FEATURE_CONTROL, msr);
-	return (msr &amp; 5) == 1; /* locked but not enabled */
+	return (msr &amp; (MSR_IA32_FEATURE_CONTROL_LOCKED |
+		       MSR_IA32_FEATURE_CONTROL_VMXON_ENABLED))
+	    == MSR_IA32_FEATURE_CONTROL_LOCKED;
+	/* locked but not enabled */
 }
 
 static void hardware_enable(void *garbage)
@@ -761,9 +764,14 @@ static void hardware_enable(void *garbage)
 	u64 old;
 
 	rdmsrl(MSR_IA32_FEATURE_CONTROL, old);
-	if ((old &amp; 5) != 5)
+	if ((old &amp; (MSR_IA32_FEATURE_CONTROL_LOCKED |
+		    MSR_IA32_FEATURE_CONTROL_VMXON_ENABLED))
+	    != (MSR_IA32_FEATURE_CONTROL_LOCKED |
+		MSR_IA32_FEATURE_CONTROL_VMXON_ENABLED))
 		/* enable and lock */
-		wrmsrl(MSR_IA32_FEATURE_CONTROL, old | 5);
+		wrmsrl(MSR_IA32_FEATURE_CONTROL, old |
+		       MSR_IA32_FEATURE_CONTROL_LOCKED |
+		       MSR_IA32_FEATURE_CONTROL_VMXON_ENABLED);
 	write_cr4(read_cr4() | X86_CR4_VMXE); /* FIXME: not cpu hotplug safe */
 	asm volatile (ASM_VMX_VMXON_RAX : : "a"(&amp;phys_addr), "m"(phys_addr)
 		      : "memory", "cc");
@@ -1326,7 +1334,7 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu)
 			       CPU_BASED_HLT_EXITING         /* 20.6.2 */
 			       | CPU_BASED_CR8_LOAD_EXITING    /...
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Avi Kivity <avi@...>
Date: Monday, September 17, 2007 - 4:30 am

The writeback fixes (02c03a326a5df825cc01de426f72e160db2b9538) broke
cmov emulation.  Fix.

Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/x86_emulate.c |   22 +++++++++++-----------
 1 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index db9f955..82b4ea6 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -1235,40 +1235,40 @@ twobyte_insn:
 		break;
 	case 0x40 ... 0x4f:	/* cmov */
 		dst.val = dst.orig_val = src.val;
-		d &amp;= ~Mov;	/* default to no move */
+		no_wb = 1;
 		/*
 		 * First, assume we're decoding an even cmov opcode
 		 * (lsb == 0).
 		 */
 		switch ((b &amp; 15) &gt;&gt; 1) {
 		case 0:	/* cmovo */
-			d |= (_eflags &amp; EFLG_OF) ? Mov : 0;
+			no_wb = (_eflags &amp; EFLG_OF) ? 0 : 1;
 			break;
 		case 1:	/* cmovb/cmovc/cmovnae */
-			d |= (_eflags &amp; EFLG_CF) ? Mov : 0;
+			no_wb = (_eflags &amp; EFLG_CF) ? 0 : 1;
 			break;
 		case 2:	/* cmovz/cmove */
-			d |= (_eflags &amp; EFLG_ZF) ? Mov : 0;
+			no_wb = (_eflags &amp; EFLG_ZF) ? 0 : 1;
 			break;
 		case 3:	/* cmovbe/cmovna */
-			d |= (_eflags &amp; (EFLG_CF | EFLG_ZF)) ? Mov : 0;
+			no_wb = (_eflags &amp; (EFLG_CF | EFLG_ZF)) ? 0 : 1;
 			break;
 		case 4:	/* cmovs */
-			d |= (_eflags &amp; EFLG_SF) ? Mov : 0;
+			no_wb = (_eflags &amp; EFLG_SF) ? 0 : 1;
 			break;
 		case 5:	/* cmovp/cmovpe */
-			d |= (_eflags &amp; EFLG_PF) ? Mov : 0;
+			no_wb = (_eflags &amp; EFLG_PF) ? 0 : 1;
 			break;
 		case 7:	/* cmovle/cmovng */
-			d |= (_eflags &amp; EFLG_ZF) ? Mov : 0;
+			no_wb = (_eflags &amp; EFLG_ZF) ? 0 : 1;
 			/* fall through */
 		case 6:	/* cmovl/cmovnge */
-			d |= (!(_eflags &amp; EFLG_SF) !=
-			      !(_eflags &amp; EFLG_OF)) ? Mov : 0;
+			no_wb &amp;= (!(_eflags &amp; EFLG_SF) !=
+			      !(_eflags &amp; EFLG_OF)) ? 0 : 1;
 			break;
 		}
 		/* Odd cmov opcodes (lsb == 1) have inverted sense. */
-		d ^= (b &amp; 1) ? Mov : 0;
+		no_wb ^= b &amp;...
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Yang, Sheng <sheng.yang@...>
Date: Monday, September 17, 2007 - 4:31 am

From: Yang, Sheng &lt;sheng.yang@intel.com&gt;

Put cpu feature detecting part in hardware_setup, and stored the vmcs
condition in global variable for further check.

[glommer: fix for some i386-only machines not supporting CR8 load/store
 exiting]

Signed-off-by: Sheng Yang &lt;sheng.yang@intel.com&gt;
Signed-off-by: Glauber de Oliveira Costa &lt;gcosta@redhat.com&gt;
Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/vmx.c |  147 ++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 102 insertions(+), 45 deletions(-)

diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index df57878..18f9b0b 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -71,18 +71,17 @@ static DEFINE_PER_CPU(struct vmcs *, current_vmcs);
 static struct page *vmx_io_bitmap_a;
 static struct page *vmx_io_bitmap_b;
 
-#ifdef CONFIG_X86_64
-#define HOST_IS_64 1
-#else
-#define HOST_IS_64 0
-#endif
 #define EFER_SAVE_RESTORE_BITS ((u64)EFER_SCE)
 
-static struct vmcs_descriptor {
+static struct vmcs_config {
 	int size;
 	int order;
 	u32 revision_id;
-} vmcs_descriptor;
+	u32 pin_based_exec_ctrl;
+	u32 cpu_based_exec_ctrl;
+	u32 vmexit_ctrl;
+	u32 vmentry_ctrl;
+} vmcs_config;
 
 #define VMX_SEGMENT_FIELD(seg)					\
 	[VCPU_SREG_##seg] = {                                   \
@@ -839,14 +838,93 @@ static void hardware_disable(void *garbage)
 	asm volatile (ASM_VMX_VMXOFF : : : "cc");
 }
 
-static __init void setup_vmcs_descriptor(void)
+static __init int adjust_vmx_controls(u32 ctl_min, u32 ctl_opt,
+				      u32 msr, u32* result)
+{
+	u32 vmx_msr_low, vmx_msr_high;
+	u32 ctl = ctl_min | ctl_opt;
+
+	rdmsr(msr, vmx_msr_low, vmx_msr_high);
+
+	ctl &amp;= vmx_msr_high; /* bit == 0 in high word ==&gt; must be zero */
+	ctl |= vmx_msr_low;  /* bit == 1 in low word  ==&gt; must be one  */
+
+	/* Ensure minimum (required) set of control bits are supported. */
+	if (ctl_min &amp; ~ctl)
+		return -1;
+
+	*result = ctl;
+	return 0;
+}
+
+static _...
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Shaohua Li <shaohua.li@...>
Date: Monday, September 17, 2007 - 4:31 am

From: Shaohua Li &lt;shaohua.li@intel.com&gt;

This allows the kvm mmu to perform sleepy operations, such as memory
allocation.

Signed-off-by: Shaohua Li &lt;shaohua.li@intel.com&gt;
Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/kvm.h      |    2 +-
 drivers/kvm/kvm_main.c |   69 +++++++++++++++++++++++-------------------------
 drivers/kvm/mmu.c      |    9 +++---
 drivers/kvm/svm.c      |    8 +++---
 drivers/kvm/vmx.c      |    8 +++---
 5 files changed, 46 insertions(+), 50 deletions(-)

diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index 0667183..1072c83 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -393,7 +393,7 @@ struct kvm_memory_slot {
 };
 
 struct kvm {
-	spinlock_t lock; /* protects everything except vcpus */
+	struct mutex lock; /* protects everything except vcpus */
 	int naliases;
 	struct kvm_mem_alias aliases[KVM_ALIAS_SLOTS];
 	int nmemslots;
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 6035e6d..7aeaaba 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -363,7 +363,7 @@ static struct kvm *kvm_create_vm(void)
 		return ERR_PTR(-ENOMEM);
 
 	kvm_io_bus_init(&amp;kvm-&gt;pio_bus);
-	spin_lock_init(&amp;kvm-&gt;lock);
+	mutex_init(&amp;kvm-&gt;lock);
 	INIT_LIST_HEAD(&amp;kvm-&gt;active_mmu_pages);
 	kvm_io_bus_init(&amp;kvm-&gt;mmio_bus);
 	spin_lock(&amp;kvm_lock);
@@ -489,7 +489,7 @@ static int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3)
 	struct page *page;
 	u64 pdpte[ARRAY_SIZE(vcpu-&gt;pdptrs)];
 
-	spin_lock(&amp;vcpu-&gt;kvm-&gt;lock);
+	mutex_lock(&amp;vcpu-&gt;kvm-&gt;lock);
 	page = gfn_to_page(vcpu-&gt;kvm, pdpt_gfn);
 	if (!page) {
 		ret = 0;
@@ -510,7 +510,7 @@ static int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3)
 
 	memcpy(vcpu-&gt;pdptrs, pdpte, sizeof(vcpu-&gt;pdptrs));
 out:
-	spin_unlock(&amp;vcpu-&gt;kvm-&gt;lock);
+	mutex_unlock(&amp;vcpu-&gt;kvm-&gt;lock);
 
 	return ret;
 }
@@ -570,9 +570,9 @@ void set_cr0(struct kvm...
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Laurent Vivier <Laurent.Vivier@...>
Date: Monday, September 17, 2007 - 4:31 am

From: Laurent Vivier &lt;Laurent.Vivier@bull.net&gt;

... instead of a x86_emulate_ctxt, so that other callers can use it easily.

Signed-off-by: Laurent Vivier &lt;Laurent.Vivier@bull.net&gt;
Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/kvm_main.c    |   25 +++++++++++--------------
 drivers/kvm/x86_emulate.c |   35 ++++++++++++++++++++---------------
 drivers/kvm/x86_emulate.h |   10 +++++-----
 3 files changed, 36 insertions(+), 34 deletions(-)

diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 6ad1b04..a65a145 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -1020,9 +1020,8 @@ void mark_page_dirty(struct kvm *kvm, gfn_t gfn)
 static int emulator_read_std(unsigned long addr,
 			     void *val,
 			     unsigned int bytes,
-			     struct x86_emulate_ctxt *ctxt)
+			     struct kvm_vcpu *vcpu)
 {
-	struct kvm_vcpu *vcpu = ctxt-&gt;vcpu;
 	void *data = val;
 
 	while (bytes) {
@@ -1056,7 +1055,7 @@ static int emulator_read_std(unsigned long addr,
 static int emulator_write_std(unsigned long addr,
 			      const void *val,
 			      unsigned int bytes,
-			      struct x86_emulate_ctxt *ctxt)
+			      struct kvm_vcpu *vcpu)
 {
 	printk(KERN_ERR "emulator_write_std: addr %lx n %d\n",
 	       addr, bytes);
@@ -1083,9 +1082,8 @@ static struct kvm_io_device *vcpu_find_pio_dev(struct kvm_vcpu *vcpu,
 static int emulator_read_emulated(unsigned long addr,
 				  void *val,
 				  unsigned int bytes,
-				  struct x86_emulate_ctxt *ctxt)
+				  struct kvm_vcpu *vcpu)
 {
-	struct kvm_vcpu      *vcpu = ctxt-&gt;vcpu;
 	struct kvm_io_device *mmio_dev;
 	gpa_t                 gpa;
 
@@ -1093,7 +1091,7 @@ static int emulator_read_emulated(unsigned long addr,
 		memcpy(val, vcpu-&gt;mmio_data, bytes);
 		vcpu-&gt;mmio_read_completed = 0;
 		return X86EMUL_CONTINUE;
-	} else if (emulator_read_std(addr, val, bytes, ctxt)
+	} else if (emulator_read_std(addr, val, bytes, vcpu)
 		   == X86EMUL_CONTINUE)
 		return X8...
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Rusty Russell <rusty@...>
Date: Monday, September 17, 2007 - 4:31 am

From: Rusty Russell &lt;rusty@rustcorp.com.au&gt;

set_msr_interception() is used by svm to set up which MSRs should be
intercepted.  It can only fail if someone has changed the code to try
to intercept an MSR without updating the array of ranges.

The return value is ignored anyway: it should just BUG() if it doesn't
work.  (A build-time failure would be better, but that's tricky).

Signed-off-by: Rusty Russell &lt;rusty@rustcorp.com.au&gt;
Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/svm.c |    9 ++++-----
 1 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
index 827bc27..7beaff1 100644
--- a/drivers/kvm/svm.c
+++ b/drivers/kvm/svm.c
@@ -359,8 +359,8 @@ err_1:
 
 }
 
-static int set_msr_interception(u32 *msrpm, unsigned msr,
-				int read, int write)
+static void set_msr_interception(u32 *msrpm, unsigned msr,
+				 int read, int write)
 {
 	int i;
 
@@ -375,11 +375,10 @@ static int set_msr_interception(u32 *msrpm, unsigned msr,
 			u32 mask = ((write) ? 0 : 2) | ((read) ? 0 : 1);
 			*base = (*base &amp; ~(0x3 &lt;&lt; msr_shift)) |
 				(mask &lt;&lt; msr_shift);
-			return 1;
+			return;
 		}
 	}
-	printk(KERN_DEBUG "%s: not found 0x%x\n", __FUNCTION__, msr);
-	return 0;
+	BUG();
 }
 
 static __init int svm_hardware_setup(void)
-- 
1.5.3

-
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Gregory Haskins <ghaskins@...>
Date: Monday, September 17, 2007 - 4:31 am

From: Gregory Haskins &lt;ghaskins@novell.com&gt;

struct kvm_vcpu has vmx-specific members; remove them to a private structure.

Signed-off-by: Gregory Haskins &lt;ghaskins@novell.com&gt;
Signed-off-by: Rusty Russell &lt;rusty@rustcorp.com.au&gt;
Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/kvm.h      |   31 +----
 drivers/kvm/kvm_main.c |   26 +---
 drivers/kvm/kvm_svm.h  |    3 +
 drivers/kvm/svm.c      |  394 ++++++++++++++++++++++++++++--------------------
 drivers/kvm/vmx.c      |  249 +++++++++++++++++++-----------
 5 files changed, 397 insertions(+), 306 deletions(-)

diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index 57504ae..954a140 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -15,7 +15,6 @@
 #include &lt;linux/mm.h&gt;
 #include &lt;asm/signal.h&gt;
 
-#include "vmx.h"
 #include &lt;linux/kvm.h&gt;
 #include &lt;linux/kvm_para.h&gt;
 
@@ -140,14 +139,6 @@ struct kvm_mmu_page {
 	};
 };
 
-struct vmcs {
-	u32 revision_id;
-	u32 abort;
-	char data[0];
-};
-
-#define vmx_msr_entry kvm_msr_entry
-
 struct kvm_vcpu;
 
 /*
@@ -309,15 +300,12 @@ void kvm_io_bus_register_dev(struct kvm_io_bus *bus,
 			     struct kvm_io_device *dev);
 
 struct kvm_vcpu {
+	int valid;
 	struct kvm *kvm;
 	int vcpu_id;
-	union {
-		struct vmcs *vmcs;
-		struct vcpu_svm *svm;
-	};
+	void *_priv;
 	struct mutex mutex;
 	int   cpu;
-	int   launched;
 	u64 host_tsc;
 	struct kvm_run *run;
 	int interrupt_window_open;
@@ -340,14 +328,6 @@ struct kvm_vcpu {
 	u64 shadow_efer;
 	u64 apic_base;
 	u64 ia32_misc_enable_msr;
-	int nmsrs;
-	int save_nmsrs;
-	int msr_offset_efer;
-#ifdef CONFIG_X86_64
-	int msr_offset_kernel_gs_base;
-#endif
-	struct vmx_msr_entry *guest_msrs;
-	struct vmx_msr_entry *host_msrs;
 
 	struct kvm_mmu mmu;
 
@@ -366,11 +346,6 @@ struct kvm_vcpu {
 	char *guest_fx_image;
 	int fpu_active;
 	int guest_fpu_loaded;
-	struct vmx_host_state {
-		int loaded;
-		u16 fs_sel, gs_sel, ldt_sel;
-		int ...
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Rusty Russell <rusty@...>
Date: Monday, September 17, 2007 - 4:31 am

From: Rusty Russell &lt;rusty@rustcorp.com.au&gt;

alloc_vmcs_cpu is already declared (static) above, no need to
redeclare.

Signed-off-by: Rusty Russell &lt;rusty@rustcorp.com.au&gt;
Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/vmx.c |    2 --
 1 files changed, 0 insertions(+), 2 deletions(-)

diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index c4b8bfe..a94eb20 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -949,8 +949,6 @@ static void free_kvm_area(void)
 		free_vmcs(per_cpu(vmxarea, cpu));
 }
 
-extern struct vmcs *alloc_vmcs_cpu(int cpu);
-
 static __init int alloc_kvm_area(void)
 {
 	int cpu;
-- 
1.5.3

-
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Avi Kivity <avi@...>
Date: Monday, September 17, 2007 - 4:31 am

Current kvm disables preemption while the new virtualization registers are
in use.  This of course is not very good for latency sensitive workloads (one
use of virtualization is to offload user interface and other latency
insensitive stuff to a container, so that it is easier to analyze the
remaining workload).  This patch re-enables preemption for kvm; preemption
is now only disabled when switching the registers in and out, and during
the switch to guest mode and back.

Contains fixes from Shaohua Li &lt;shaohua.li@intel.com&gt;.

Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/Kconfig    |    1 +
 drivers/kvm/kvm.h      |    4 +++-
 drivers/kvm/kvm_main.c |   43 +++++++++++++++++++++++++++++++++++++------
 drivers/kvm/mmu.c      |    2 --
 drivers/kvm/svm.c      |    6 ++----
 drivers/kvm/vmx.c      |   22 +++++++++++++---------
 6 files changed, 56 insertions(+), 22 deletions(-)

diff --git a/drivers/kvm/Kconfig b/drivers/kvm/Kconfig
index 7b64fd4..9b72f33 100644
--- a/drivers/kvm/Kconfig
+++ b/drivers/kvm/Kconfig
@@ -16,6 +16,7 @@ if VIRTUALIZATION
 config KVM
 	tristate "Kernel-based Virtual Machine (KVM) support"
 	depends on X86 &amp;&amp; EXPERIMENTAL
+	select PREEMPT_NOTIFIERS
 	select ANON_INODES
 	---help---
 	  Support hosting fully virtualized guest machines using hardware
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index e92c84b..0667183 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -13,6 +13,7 @@
 #include &lt;linux/signal.h&gt;
 #include &lt;linux/sched.h&gt;
 #include &lt;linux/mm.h&gt;
+#include &lt;linux/preempt.h&gt;
 #include &lt;asm/signal.h&gt;
 
 #include &lt;linux/kvm.h&gt;
@@ -301,6 +302,7 @@ void kvm_io_bus_register_dev(struct kvm_io_bus *bus,
 
 struct kvm_vcpu {
 	struct kvm *kvm;
+	struct preempt_notifier preempt_notifier;
 	int vcpu_id;
 	struct mutex mutex;
 	int   cpu;
@@ -429,7 +431,7 @@ struct kvm_arch_ops {
 	struct kvm_vcpu *(*vcpu_create)(struct kvm *kvm, unsigned id);
 	void (*vcpu_f...
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Laurent Vivier <Laurent.Vivier@...>
Date: Monday, September 17, 2007 - 4:31 am

From: Laurent Vivier &lt;Laurent.Vivier@bull.net&gt;

... in favor of the more general emulator_{read,write}_*.

Signed-off-by: Laurent Vivier &lt;Laurent.Vivier@bull.net&gt;
Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/kvm.h      |   17 +++++------
 drivers/kvm/kvm_main.c |   74 ++---------------------------------------------
 drivers/kvm/svm.c      |    3 +-
 drivers/kvm/vmx.c      |   19 +++++++-----
 4 files changed, 25 insertions(+), 88 deletions(-)

diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index 1072c83..030b93b 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -561,15 +561,14 @@ void kvm_load_guest_fpu(struct kvm_vcpu *vcpu);
 void kvm_put_guest_fpu(struct kvm_vcpu *vcpu);
 void kvm_flush_remote_tlbs(struct kvm *kvm);
 
-int kvm_read_guest(struct kvm_vcpu *vcpu,
-	       gva_t addr,
-	       unsigned long size,
-	       void *dest);
-
-int kvm_write_guest(struct kvm_vcpu *vcpu,
-		gva_t addr,
-		unsigned long size,
-		void *data);
+int emulator_read_std(unsigned long addr,
+                      void *val,
+		      unsigned int bytes,
+		      struct kvm_vcpu *vcpu);
+int emulator_write_emulated(unsigned long addr,
+			    const void *val,
+			    unsigned int bytes,
+			    struct kvm_vcpu *vcpu);
 
 unsigned long segment_base(u16 selector);
 
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index a65a145..4bbd89e 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -146,74 +146,6 @@ static inline int valid_vcpu(int n)
 	return likely(n &gt;= 0 &amp;&amp; n &lt; KVM_MAX_VCPUS);
 }
 
-int kvm_read_guest(struct kvm_vcpu *vcpu, gva_t addr, unsigned long size,
-		   void *dest)
-{
-	unsigned char *host_buf = dest;
-	unsigned long req_size = size;
-
-	while (size) {
-		hpa_t paddr;
-		unsigned now;
-		unsigned offset;
-		hva_t guest_buf;
-
-		paddr = gva_to_hpa(vcpu, addr);
-
-		if (is_error_hpa(paddr))
-			break;
-
-		guest_buf = (hva_t)kmap_atomic(
-					pfn_to_page(paddr &gt...
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Rusty Russell <rusty@...>
Date: Monday, September 17, 2007 - 4:31 am

From: Rusty Russell &lt;rusty@rustcorp.com.au&gt;

We shouldn't define stat_set on the debug attributes, since that will
cause silent failure on writing: without a set argument, userspace
will get -EACCESS.

Signed-off-by: Rusty Russell &lt;rusty@rustcorp.com.au&gt;
Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/kvm_main.c |    6 +-----
 1 files changed, 1 insertions(+), 5 deletions(-)

diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 55639ac..25d76a5 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -3017,11 +3017,7 @@ static u64 stat_get(void *_offset)
 	return total;
 }
 
-static void stat_set(void *offset, u64 val)
-{
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(stat_fops, stat_get, stat_set, "%llu\n");
+DEFINE_SIMPLE_ATTRIBUTE(stat_fops, stat_get, NULL, "%llu\n");
 
 static __init void kvm_init_debug(void)
 {
-- 
1.5.3

-
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Rusty Russell <rusty@...>
Date: Monday, September 17, 2007 - 4:31 am

From: Rusty Russell &lt;rusty@rustcorp.com.au&gt;

container_of is wonderful, but not casting at all is better.  This
patch changes vmx.c's internal functions to pass "struct vcpu_vmx"
instead of "struct kvm_vcpu" and using container_of.

Signed-off-by: Rusty Russell &lt;rusty@rustcorp.com.au&gt;
Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/vmx.c |  140 ++++++++++++++++++++++++----------------------------
 1 files changed, 65 insertions(+), 75 deletions(-)

diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index 5b77d9b..cc7ee3d 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -140,9 +140,8 @@ static inline u64 msr_efer_save_restore_bits(struct kvm_msr_entry msr)
 	return (u64)msr.data &amp; EFER_SAVE_RESTORE_BITS;
 }
 
-static inline int msr_efer_need_save_restore(struct kvm_vcpu *vcpu)
+static inline int msr_efer_need_save_restore(struct vcpu_vmx *vmx)
 {
-	struct vcpu_vmx *vmx = to_vmx(vcpu);
 	int efer_offset = vmx-&gt;msr_offset_efer;
 	return msr_efer_save_restore_bits(vmx-&gt;host_msrs[efer_offset]) !=
 		msr_efer_save_restore_bits(vmx-&gt;guest_msrs[efer_offset]);
@@ -168,9 +167,8 @@ static inline int is_external_interrupt(u32 intr_info)
 		== (INTR_TYPE_EXT_INTR | INTR_INFO_VALID_MASK);
 }
 
-static int __find_msr_index(struct kvm_vcpu *vcpu, u32 msr)
+static int __find_msr_index(struct vcpu_vmx *vmx, u32 msr)
 {
-	struct vcpu_vmx *vmx = to_vmx(vcpu);
 	int i;
 
 	for (i = 0; i &lt; vmx-&gt;nmsrs; ++i)
@@ -179,12 +177,11 @@ static int __find_msr_index(struct kvm_vcpu *vcpu, u32 msr)
 	return -1;
 }
 
-static struct kvm_msr_entry *find_msr_entry(struct kvm_vcpu *vcpu, u32 msr)
+static struct kvm_msr_entry *find_msr_entry(struct vcpu_vmx *vmx, u32 msr)
 {
-	struct vcpu_vmx *vmx = to_vmx(vcpu);
 	int i;
 
-	i = __find_msr_index(vcpu, msr);
+	i = __find_msr_index(vmx, msr);
 	if (i &gt;= 0)
 		return &amp;vmx-&gt;guest_msrs[i];
 	return NULL;
@@ -205,24 +202,24 @@ static void vmcs_clear(struct vmcs *vmcs)
 
 static void _...
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Li, Xin B <xin.b.li@...>
Date: Monday, September 17, 2007 - 4:31 am

From: Li, Xin B &lt;xin.b.li@intel.com&gt;

Remove a duplicated ia32e mode VM Entry control definition and use the
proper one.

Signed-off-by: Xin Li &lt;xin.b.li@intel.com&gt;
Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/vmx.c |    8 ++++----
 drivers/kvm/vmx.h |    3 ---
 2 files changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index 708055a..30c627d 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -1111,7 +1111,7 @@ static void enter_lmode(struct kvm_vcpu *vcpu)
 	find_msr_entry(to_vmx(vcpu), MSR_EFER)-&gt;data |= EFER_LMA | EFER_LME;
 	vmcs_write32(VM_ENTRY_CONTROLS,
 		     vmcs_read32(VM_ENTRY_CONTROLS)
-		     | VM_ENTRY_CONTROLS_IA32E_MASK);
+		     | VM_ENTRY_IA32E_MODE);
 }
 
 static void exit_lmode(struct kvm_vcpu *vcpu)
@@ -1120,7 +1120,7 @@ static void exit_lmode(struct kvm_vcpu *vcpu)
 
 	vmcs_write32(VM_ENTRY_CONTROLS,
 		     vmcs_read32(VM_ENTRY_CONTROLS)
-		     &amp; ~VM_ENTRY_CONTROLS_IA32E_MASK);
+		     &amp; ~VM_ENTRY_IA32E_MODE);
 }
 
 #endif
@@ -1185,13 +1185,13 @@ static void vmx_set_efer(struct kvm_vcpu *vcpu, u64 efer)
 	if (efer &amp; EFER_LMA) {
 		vmcs_write32(VM_ENTRY_CONTROLS,
 				     vmcs_read32(VM_ENTRY_CONTROLS) |
-				     VM_ENTRY_CONTROLS_IA32E_MASK);
+				     VM_ENTRY_IA32E_MODE);
 		msr-&gt;data = efer;
 
 	} else {
 		vmcs_write32(VM_ENTRY_CONTROLS,
 				     vmcs_read32(VM_ENTRY_CONTROLS) &amp;
-				     ~VM_ENTRY_CONTROLS_IA32E_MASK);
+				     ~VM_ENTRY_IA32E_MODE);
 
 		msr-&gt;data = efer &amp; ~EFER_LME;
 	}
diff --git a/drivers/kvm/vmx.h b/drivers/kvm/vmx.h
index 7e4dc12..35d0b58 100644
--- a/drivers/kvm/vmx.h
+++ b/drivers/kvm/vmx.h
@@ -268,9 +268,6 @@ enum vmcs_field {
 /* segment AR */
 #define SEGMENT_AR_L_MASK (1 &lt;&lt; 13)
 
-/* entry controls */
-#define VM_ENTRY_CONTROLS_IA32E_MASK (1 &lt;&lt; 9)
-
 #define AR_TYPE_ACCESSES_MASK 1
 #define AR_TYPE_READABLE_MASK (1 &lt;&lt; 1)
 #define AR_TYPE_WRITEABLE_MASK (1 &lt;&...
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Yang, Sheng <sheng.yang@...>
Date: Monday, September 17, 2007 - 4:31 am

From: Yang, Sheng &lt;sheng.yang@intel.com&gt;

This allows running 64-bit Windows.

Signed-off-by: Sheng Yang &lt;sheng.yang@intel.com&gt;
Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/vmx.c   |    3 ++-
 include/linux/kvm.h |    1 +
 2 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index a9b4cb5..cd999c0 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -1831,7 +1831,8 @@ static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 			vcpu_load_rsp_rip(vcpu);
 			set_cr8(vcpu, vcpu-&gt;regs[reg]);
 			skip_emulated_instruction(vcpu);
-			return 1;
+			kvm_run-&gt;exit_reason = KVM_EXIT_SET_TPR;
+			return 0;
 		};
 		break;
 	case 2: /* clts */
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 91a446f..1d5a49c 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -46,6 +46,7 @@ enum kvm_exit_reason {
 	KVM_EXIT_SHUTDOWN         = 8,
 	KVM_EXIT_FAIL_ENTRY       = 9,
 	KVM_EXIT_INTR             = 10,
+	KVM_EXIT_SET_TPR          = 11
 };
 
 /* for KVM_RUN, returned by mmap(vcpu_fd, offset=0) */
-- 
1.5.3

-
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Nitin A Kamble <nitin.a.kamble@...>
Date: Monday, September 17, 2007 - 4:31 am

From: Nitin A Kamble &lt;nitin.a.kamble@intel.com&gt;

Signed-off-by: Nitin A Kamble &lt;nitin.a.kamble@intel.com&gt;
Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/x86_emulate.c |   16 ++++++++++++++--
 1 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index 2b94d16..fa7aa27 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -145,8 +145,10 @@ static u8 opcode_table[256] = {
 	0, 0, 0, 0,
 	/* 0xD8 - 0xDF */
 	0, 0, 0, 0, 0, 0, 0, 0,
-	/* 0xE0 - 0xEF */
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	/* 0xE0 - 0xE7 */
+	0, 0, 0, 0, 0, 0, 0, 0,
+	/* 0xE8 - 0xEF */
+	0, SrcImm|ImplicitOps, 0, 0, 0, 0, 0, 0,
 	/* 0xF0 - 0xF7 */
 	0, 0, 0, 0,
 	ImplicitOps, 0,
@@ -447,6 +449,12 @@ struct operand {
 			   (((reg) + _inc) &amp; ((1UL &lt;&lt; (ad_bytes &lt;&lt; 3)) - 1)); \
 	} while (0)
 
+#define JMP_REL(rel) 							\
+	do {								\
+		_eip += (int)(rel);					\
+		_eip = ((op_bytes == 2) ? (uint16_t)_eip : (uint32_t)_eip); \
+	} while (0)
+
 /*
  * Given the 'reg' portion of a ModRM byte, and a register block, return a
  * pointer into the block that addresses the relevant register.
@@ -1023,6 +1031,10 @@ done_prefixes:
 	case 0xd2 ... 0xd3:	/* Grp2 */
 		src.val = _regs[VCPU_REGS_RCX];
 		goto grp2;
+	case 0xe9: /* jmp rel */
+		JMP_REL(src.val);
+		no_wb = 1; /* Disable writeback. */
+		break;
 	case 0xf6 ... 0xf7:	/* Grp3 */
 		switch (modrm_reg) {
 		case 0 ... 1:	/* test */
-- 
1.5.3

-
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Nitin A Kamble <nitin.a.kamble@...>
Date: Monday, September 17, 2007 - 4:31 am

From: Nitin A Kamble &lt;nitin.a.kamble@intel.com&gt;

Implement emulation of instruction
    and al imm8 (opcode 0x24)
    and ax/eax imm16/imm32 (opcode 0x25)

Signed-off-by: Nitin A Kamble &lt;nitin.a.kamble@intel.com&gt;
Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/x86_emulate.c |   21 +++++++++++++++++++--
 1 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index b4f439c..2b94d16 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -83,7 +83,7 @@ static u8 opcode_table[256] = {
 	/* 0x20 - 0x27 */
 	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
 	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
-	0, 0, 0, 0,
+	SrcImmByte, SrcImm, 0, 0,
 	/* 0x28 - 0x2F */
 	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
 	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
@@ -882,10 +882,27 @@ done_prefixes:
 	      sbb:		/* sbb */
 		emulate_2op_SrcV("sbb", src, dst, _eflags);
 		break;
-	case 0x20 ... 0x25:
+	case 0x20 ... 0x23:
 	      and:		/* and */
 		emulate_2op_SrcV("and", src, dst, _eflags);
 		break;
+	case 0x24:              /* and al imm8 */
+		dst.type = OP_REG;
+		dst.ptr = &amp;_regs[VCPU_REGS_RAX];
+		dst.val = *(u8 *)dst.ptr;
+		dst.bytes = 1;
+		dst.orig_val = dst.val;
+		goto and;
+	case 0x25:              /* and ax imm16, or eax imm32 */
+		dst.type = OP_REG;
+		dst.bytes = op_bytes;
+		dst.ptr = &amp;_regs[VCPU_REGS_RAX];
+		if (op_bytes == 2)
+			dst.val = *(u16 *)dst.ptr;
+		else
+			dst.val = *(u32 *)dst.ptr;
+		dst.orig_val = dst.val;
+		goto and;
 	case 0x28 ... 0x2d:
 	      sub:		/* sub */
 		emulate_2op_SrcV("sub", src, dst, _eflags);
-- 
1.5.3

-
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Nitin A Kamble <nitin.a.kamble@...>
Date: Monday, September 17, 2007 - 4:31 am

From: Nitin A Kamble &lt;nitin.a.kamble@intel.com&gt;

Signed-off-by: Nitin A Kamble &lt;nitin.a.kamble@intel.com&gt;
Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/x86_emulate.c |   16 +++++++++++++++-
 1 files changed, 15 insertions(+), 1 deletions(-)

diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index 1036e02..cf895aa 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -99,7 +99,8 @@ static u8 opcode_table[256] = {
 	/* 0x40 - 0x4F */
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	/* 0x50 - 0x57 */
-	0, 0, 0, 0, 0, 0, 0, 0,
+	ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
+	ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
 	/* 0x58 - 0x5F */
 	ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
 	ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
@@ -1151,6 +1152,19 @@ special_insn:
 	if (twobyte)
 		goto twobyte_special_insn;
 	switch(b) {
+	case 0x50 ... 0x57:  /* push reg */
+		if (op_bytes == 2)
+			src.val = (u16) _regs[b &amp; 0x7];
+		else
+			src.val = (u32) _regs[b &amp; 0x7];
+		dst.type  = OP_MEM;
+		dst.bytes = op_bytes;
+		dst.val = src.val;
+		register_address_increment(_regs[VCPU_REGS_RSP], -op_bytes);
+		dst.ptr = (void *) register_address(
+			ctxt-&gt;ss_base, _regs[VCPU_REGS_RSP]);
+		no_wb = 1; /* force writeback */
+		break;
 	case 0x6c:		/* insb */
 	case 0x6d:		/* insw/insd */
 		 if (kvm_emulate_pio_string(ctxt-&gt;vcpu, NULL,
-- 
1.5.3

-
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Laurent Vivier <Laurent.Vivier@...>
Date: Monday, September 17, 2007 - 4:31 am

From: Laurent Vivier &lt;Laurent.Vivier@bull.net&gt;

Both vmx and svm decode the I/O instructions, and both botch the job,
requiring the instruction prefixes to be fetched in order to completely
decode the instruction.

So, if we see a string I/O instruction, use the x86 emulator to decode it,
as it already has all the prefix decoding machinery.

This patch defines ins/outs opcodes in x86_emulate.c and calls
emulate_instruction() from io_interception() (svm.c) and from handle_io()
(vmx.c).  It removes all vmx/svm prefix instruction decoders
(get_addr_size(), io_get_override(), io_address(), get_io_count())

Signed-off-by: Laurent Vivier &lt;Laurent.Vivier@bull.net&gt;
Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/kvm_main.c    |    3 +
 drivers/kvm/svm.c         |  149 +++------------------------------------------
 drivers/kvm/vmx.c         |   76 ++++-------------------
 drivers/kvm/x86_emulate.c |   49 +++++++++++++--
 4 files changed, 69 insertions(+), 208 deletions(-)

diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 62adaee..661d065 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -1221,7 +1221,10 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
 	emulate_ctxt.fs_base = get_segment_base(vcpu, VCPU_SREG_FS);
 
 	vcpu-&gt;mmio_is_write = 0;
+	vcpu-&gt;pio.string = 0;
 	r = x86_emulate_memop(&amp;emulate_ctxt, &amp;emulate_ops);
+	if (vcpu-&gt;pio.string)
+		return EMULATE_DO_MMIO;
 
 	if ((r || vcpu-&gt;mmio_is_write) &amp;&amp; run) {
 		run-&gt;exit_reason = KVM_EXIT_MMIO;
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
index 436bdff..a83ff01 100644
--- a/drivers/kvm/svm.c
+++ b/drivers/kvm/svm.c
@@ -98,20 +98,6 @@ static inline u32 svm_has(u32 feat)
 	return svm_features &amp; feat;
 }
 
-static unsigned get_addr_size(struct vcpu_svm *svm)
-{
-	struct vmcb_save_area *sa = &amp;svm-&gt;vmcb-&gt;save;
-	u16 cs_attrib;
-
-	if (!(sa-&gt;cr0 &amp; X86_CR0_PE) || (sa-&gt;rflags &amp; X86_EFLAGS_VM))
...
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Avi Kivity <avi@...>
Date: Monday, September 17, 2007 - 4:31 am

Pointed out by Rusty Russell.

Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/x86_emulate.c |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index cf895aa..7439b34 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -1163,7 +1163,6 @@ special_insn:
 		register_address_increment(_regs[VCPU_REGS_RSP], -op_bytes);
 		dst.ptr = (void *) register_address(
 			ctxt-&gt;ss_base, _regs[VCPU_REGS_RSP]);
-		no_wb = 1; /* force writeback */
 		break;
 	case 0x6c:		/* insb */
 	case 0x6d:		/* insw/insd */
-- 
1.5.3

-
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Eddie Dong <eddie.dong@...>
Date: Monday, September 17, 2007 - 4:31 am

From: Eddie Dong &lt;eddie.dong@intel.com&gt;

Add in kernel irqchip save/restore support for pending vectors.

Signed-off-by: Yaozu (Eddie) Dong &lt;eddie.dong@intel.com&gt;
Signed-off-by: Qing He &lt;qing.he@intel.com&gt;
Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/kvm.h      |    2 ++
 drivers/kvm/kvm_main.c |   22 +++++++++++++++++++---
 drivers/kvm/svm.c      |   19 +++++++++++++++++++
 drivers/kvm/vmx.c      |   16 ++++++++++++++++
 4 files changed, 56 insertions(+), 3 deletions(-)

diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index bb506b7..f8fe87d 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -490,6 +490,8 @@ struct kvm_arch_ops {
 	void (*skip_emulated_instruction)(struct kvm_vcpu *vcpu);
 	void (*patch_hypercall)(struct kvm_vcpu *vcpu,
 				unsigned char *hypercall_addr);
+	int (*get_irq)(struct kvm_vcpu *vcpu);
+	void (*set_irq)(struct kvm_vcpu *vcpu, int vec);
 };
 
 extern struct kvm_arch_ops *kvm_arch_ops;
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index a012d70..5092a59 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -2126,6 +2126,7 @@ static int kvm_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
 				    struct kvm_sregs *sregs)
 {
 	struct descriptor_table dt;
+	int pending_vec;
 
 	vcpu_load(vcpu);
 
@@ -2155,10 +2156,15 @@ static int kvm_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
 	sregs-&gt;efer = vcpu-&gt;shadow_efer;
 	sregs-&gt;apic_base = kvm_get_apic_base(vcpu);
 
-	if (irqchip_in_kernel(vcpu-&gt;kvm))
+	if (irqchip_in_kernel(vcpu-&gt;kvm)) {
 		memset(sregs-&gt;interrupt_bitmap, 0,
 		       sizeof sregs-&gt;interrupt_bitmap);
-	else
+		pending_vec = kvm_arch_ops-&gt;get_irq(vcpu);
+		if (pending_vec &gt;= 0) {
+			set_bit(pending_vec, sregs-&gt;interrupt_bitmap);
+			printk("pending irq in kernel %d\n",pending_vec);
+		}
+	} else
 		memcpy(sregs-&gt;interrupt_bitmap, vcpu-&gt;irq_pending,
 		       sizeof sregs-&gt;interrupt_bitmap);
 
@@ -2177,7 +2183,7...
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Amit Shah <amit.shah@...>
Date: Monday, September 17, 2007 - 4:32 am

From: Amit Shah &lt;amit.shah@qumranet.com&gt;

This was missed when moving stuff around in fbc4f2e

Fixes Solaris guests and bug #1773613

Signed-off-by: Amit Shah &lt;amit.shah@qumranet.com&gt;
Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/kvm_main.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index f101430..f0a8780 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -655,6 +655,7 @@ void fx_init(struct kvm_vcpu *vcpu)
 	fx_restore(&amp;vcpu-&gt;host_fx_image);
 	preempt_enable();
 
+	vcpu-&gt;cr0 |= X86_CR0_ET;
 	after_mxcsr_mask = offsetof(struct i387_fxsave_struct, st_space);
 	vcpu-&gt;guest_fx_image.mxcsr = 0x1f80;
 	memset((void *)&amp;vcpu-&gt;guest_fx_image + after_mxcsr_mask,
-- 
1.5.3

-
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Rusty Russell <rusty@...>
Date: Monday, September 17, 2007 - 4:32 am

From: Rusty Russell &lt;rusty@rustcorp.com.au&gt;

invlpg shouldn't fetch the "src" address, since it may not be valid,
however SVM's "solution" which neuters emulation of all group 7
instruction is horrible and breaks kvm-lite.  The simplest fix is to
put a special check in for invlpg.

Signed-off-by: Rusty Russell &lt;rusty@rustcorp.com.au&gt;
Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/kvm.h         |    2 --
 drivers/kvm/svm.c         |    2 --
 drivers/kvm/x86_emulate.c |   16 +++-------------
 3 files changed, 3 insertions(+), 17 deletions(-)

diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index 7c35352..9bf9ac6 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -539,8 +539,6 @@ static inline int is_error_hpa(hpa_t hpa) { return hpa &gt;&gt; HPA_MSB; }
 hpa_t gva_to_hpa(struct kvm_vcpu *vcpu, gva_t gva);
 struct page *gva_to_page(struct kvm_vcpu *vcpu, gva_t gva);
 
-void kvm_emulator_want_group7_invlpg(void);
-
 extern hpa_t bad_page_address;
 
 struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn);
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
index dbd4e81..e51f6b7 100644
--- a/drivers/kvm/svm.c
+++ b/drivers/kvm/svm.c
@@ -376,8 +376,6 @@ static __init int svm_hardware_setup(void)
 	void *iopm_va, *msrpm_va;
 	int r;
 
-	kvm_emulator_want_group7_invlpg();
-
 	iopm_pages = alloc_pages(GFP_KERNEL, IOPM_ALLOC_ORDER);
 
 	if (!iopm_pages)
diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index 7439b34..342594d 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -213,19 +213,6 @@ static u16 twobyte_table[256] = {
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 };
 
-/*
- * Tell the emulator that of the Group 7 instructions (sgdt, lidt, etc.) we
- * are interested only in invlpg and not in any of the rest.
- *
- * invlpg is a special instruction in that the data it references may not
- * be mapped.
- */
-void kvm_emulator_want_group7_invlpg(void)
-{
-	twobyte_table[1] &amp;=...
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Rusty Russell <rusty@...>
Date: Monday, September 17, 2007 - 4:32 am

From: Rusty Russell &lt;rusty@rustcorp.com.au&gt;

Signed-off-by: Rusty Russell &lt;rusty@rustcorp.com.au&gt;
Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/kvm.h |    1 -
 drivers/kvm/svm.c |    6 ------
 2 files changed, 0 insertions(+), 7 deletions(-)

diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index 5e318b6..7c35352 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -487,7 +487,6 @@ struct kvm_arch_ops {
 	unsigned long (*get_rflags)(struct kvm_vcpu *vcpu);
 	void (*set_rflags)(struct kvm_vcpu *vcpu, unsigned long rflags);
 
-	void (*invlpg)(struct kvm_vcpu *vcpu, gva_t addr);
 	void (*tlb_flush)(struct kvm_vcpu *vcpu);
 	void (*inject_page_fault)(struct kvm_vcpu *vcpu,
 				  unsigned long addr, u32 err_code);
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
index 3de9ec3..dbd4e81 100644
--- a/drivers/kvm/svm.c
+++ b/drivers/kvm/svm.c
@@ -881,11 +881,6 @@ static void new_asid(struct vcpu_svm *svm, struct svm_cpu_data *svm_data)
 	svm-&gt;vmcb-&gt;control.asid = svm_data-&gt;next_asid++;
 }
 
-static void svm_invlpg(struct kvm_vcpu *vcpu, gva_t address)
-{
-	invlpga(address, to_svm(vcpu)-&gt;vmcb-&gt;control.asid); // is needed?
-}
-
 static unsigned long svm_get_dr(struct kvm_vcpu *vcpu, int dr)
 {
 	return to_svm(vcpu)-&gt;db_regs[dr];
@@ -1795,7 +1790,6 @@ static struct kvm_arch_ops svm_arch_ops = {
 	.get_rflags = svm_get_rflags,
 	.set_rflags = svm_set_rflags,
 
-	.invlpg = svm_invlpg,
 	.tlb_flush = svm_flush_tlb,
 	.inject_page_fault = svm_inject_page_fault,
 
-- 
1.5.3

-
To: <kvm-devel@...>
Cc: <linux-kernel@...>, He, Qing <qing.he@...>
Date: Monday, September 17, 2007 - 4:32 am

From: He, Qing &lt;qing.he@intel.com&gt;

This patch enables INIT/SIPI handling using in-kernel APIC by
introducing a -&gt;mp_state field to emulate the SMP state transition.

[avi: remove smp_processor_id() warning]

Signed-off-by: Qing He &lt;qing.he@intel.com&gt;
Signed-off-by: Xin Li &lt;xin.b.li@intel.com&gt;
Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/irq.h      |    1 +
 drivers/kvm/kvm.h      |    7 +++++++
 drivers/kvm/kvm_main.c |   26 ++++++++++++++++++++------
 drivers/kvm/lapic.c    |   43 ++++++++++++++++++++++++++++++++++++-------
 drivers/kvm/vmx.c      |   24 +++++++++++++++++++++---
 5 files changed, 85 insertions(+), 16 deletions(-)

diff --git a/drivers/kvm/irq.h b/drivers/kvm/irq.h
index ec46a09..11fc014 100644
--- a/drivers/kvm/irq.h
+++ b/drivers/kvm/irq.h
@@ -138,6 +138,7 @@ int kvm_apic_has_interrupt(struct kvm_vcpu *vcpu);
 int kvm_apic_accept_pic_intr(struct kvm_vcpu *vcpu);
 int kvm_get_apic_interrupt(struct kvm_vcpu *vcpu);
 int kvm_create_lapic(struct kvm_vcpu *vcpu);
+void kvm_lapic_reset(struct kvm_vcpu *vcpu);
 void kvm_free_apic(struct kvm_lapic *apic);
 u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu);
 void kvm_lapic_set_tpr(struct kvm_vcpu *vcpu, unsigned long cr8);
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index dbb929d..5e318b6 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -326,6 +326,13 @@ struct kvm_vcpu {
 	u64 shadow_efer;
 	u64 apic_base;
 	struct kvm_lapic *apic;    /* kernel irqchip context */
+#define VCPU_MP_STATE_RUNNABLE          0
+#define VCPU_MP_STATE_UNINITIALIZED     1
+#define VCPU_MP_STATE_INIT_RECEIVED     2
+#define VCPU_MP_STATE_SIPI_RECEIVED     3
+#define VCPU_MP_STATE_HALTED            4
+	int mp_state;
+	int sipi_vector;
 	u64 ia32_misc_enable_msr;
 
 	struct kvm_mmu mmu;
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index a25dfc9..f101430 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -249,6 +249,10 @@ int kvm_vcpu_init(st...
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Rusty Russell <rusty@...>
Date: Monday, September 17, 2007 - 4:32 am

From: Rusty Russell &lt;rusty@rustcorp.com.au&gt;

We don't update the vcpu control registers in various places.  We
should do so.

Signed-off-by: Rusty Russell &lt;rusty@rustcorp.com.au&gt;
Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/kvm_main.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index f0a8780..07a6d97 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -543,6 +543,7 @@ void set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
 		return;
 	}
 	kvm_arch_ops-&gt;set_cr4(vcpu, cr4);
+	vcpu-&gt;cr4 = cr4;
 	mutex_lock(&amp;vcpu-&gt;kvm-&gt;lock);
 	kvm_mmu_reset_context(vcpu);
 	mutex_unlock(&amp;vcpu-&gt;kvm-&gt;lock);
@@ -1238,10 +1239,8 @@ int emulate_invlpg(struct kvm_vcpu *vcpu, gva_t address)
 
 int emulate_clts(struct kvm_vcpu *vcpu)
 {
-	unsigned long cr0;
-
-	cr0 = vcpu-&gt;cr0 &amp; ~X86_CR0_TS;
-	kvm_arch_ops-&gt;set_cr0(vcpu, cr0);
+	vcpu-&gt;cr0 &amp;= ~X86_CR0_TS;
+	kvm_arch_ops-&gt;set_cr0(vcpu, vcpu-&gt;cr0);
 	return X86EMUL_CONTINUE;
 }
 
@@ -2228,6 +2227,7 @@ static int kvm_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
 	kvm_arch_ops-&gt;decache_cr4_guest_bits(vcpu);
 
 	mmu_reset_needed |= vcpu-&gt;cr0 != sregs-&gt;cr0;
+	vcpu-&gt;cr0 = sregs-&gt;cr0;
 	kvm_arch_ops-&gt;set_cr0(vcpu, sregs-&gt;cr0);
 
 	mmu_reset_needed |= vcpu-&gt;cr4 != sregs-&gt;cr4;
-- 
1.5.3

-
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Rusty Russell <rusty@...>
Date: Monday, September 17, 2007 - 4:32 am

From: Rusty Russell &lt;rusty@rustcorp.com.au&gt;

SVM gets the DB and L bits for the cs by decoding the segment.  This
is in fact the completely generic code, so hoist it for kvm-lite to use.

Signed-off-by: Rusty Russell &lt;rusty@rustcorp.com.au&gt;
Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/kvm.h      |    1 +
 drivers/kvm/kvm_main.c |   10 ++++++++++
 drivers/kvm/svm.c      |   10 +---------
 3 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index 9bf9ac6..ee9f8bd 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -586,6 +586,7 @@ void set_cr4(struct kvm_vcpu *vcpu, unsigned long cr0);
 void set_cr8(struct kvm_vcpu *vcpu, unsigned long cr0);
 unsigned long get_cr8(struct kvm_vcpu *vcpu);
 void lmsw(struct kvm_vcpu *vcpu, unsigned long msw);
+void kvm_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l);
 
 int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata);
 int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data);
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 07a6d97..49a0ff4 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -2272,6 +2272,16 @@ static int kvm_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
 	return 0;
 }
 
+void kvm_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l)
+{
+	struct kvm_segment cs;
+
+	get_segment(vcpu, &amp;cs, VCPU_SREG_CS);
+	*db = cs.db;
+	*l = cs.l;
+}
+EXPORT_SYMBOL_GPL(kvm_get_cs_db_l_bits);
+
 /*
  * List of msr numbers which we expose to userspace through KVM_GET_MSRS
  * and KVM_SET_MSRS, and KVM_GET_MSR_INDEX_LIST.
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
index e51f6b7..35f3f83 100644
--- a/drivers/kvm/svm.c
+++ b/drivers/kvm/svm.c
@@ -724,14 +724,6 @@ static void svm_get_segment(struct kvm_vcpu *vcpu,
 	var-&gt;unusable = !var-&gt;present;
 }
 
-static void svm_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l)
-{
-	struct vmcb_seg *s = svm_seg(v...
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Avi Kivity <avi@...>
Date: Monday, September 17, 2007 - 4:32 am

This simplifies adding new code as well as reducing overall code size.

Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/kvm.h      |    9 +++-
 drivers/kvm/kvm_main.c |  124 +++++++++++++++++++++++++++++++++++++++++-
 drivers/kvm/svm.c      |  142 +++++++++++++-----------------------------------
 drivers/kvm/vmx.c      |  129 ++++++--------------------------------------
 4 files changed, 187 insertions(+), 217 deletions(-)

diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index 42bb225..d93ab48 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -453,13 +453,16 @@ struct kvm_x86_ops {
 	/* Create, but do not attach this VCPU */
 	struct kvm_vcpu *(*vcpu_create)(struct kvm *kvm, unsigned id);
 	void (*vcpu_free)(struct kvm_vcpu *vcpu);
+	void (*vcpu_reset)(struct kvm_vcpu *vcpu);
 
+	void (*prepare_guest_switch)(struct kvm_vcpu *vcpu);
 	void (*vcpu_load)(struct kvm_vcpu *vcpu, int cpu);
 	void (*vcpu_put)(struct kvm_vcpu *vcpu);
 	void (*vcpu_decache)(struct kvm_vcpu *vcpu);
 
 	int (*set_guest_debug)(struct kvm_vcpu *vcpu,
 			       struct kvm_debug_guest *dbg);
+	void (*guest_debug_pre)(struct kvm_vcpu *vcpu);
 	int (*get_msr)(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata);
 	int (*set_msr)(struct kvm_vcpu *vcpu, u32 msr_index, u64 data);
 	u64 (*get_segment_base)(struct kvm_vcpu *vcpu, int seg);
@@ -491,12 +494,16 @@ struct kvm_x86_ops {
 
 	void (*inject_gp)(struct kvm_vcpu *vcpu, unsigned err_code);
 
-	int (*run)(struct kvm_vcpu *vcpu, struct kvm_run *run);
+	void (*run)(struct kvm_vcpu *vcpu, struct kvm_run *run);
+	int (*handle_exit)(struct kvm_run *run, struct kvm_vcpu *vcpu);
 	void (*skip_emulated_instruction)(struct kvm_vcpu *vcpu);
 	void (*patch_hypercall)(struct kvm_vcpu *vcpu,
 				unsigned char *hypercall_addr);
 	int (*get_irq)(struct kvm_vcpu *vcpu);
 	void (*set_irq)(struct kvm_vcpu *vcpu, int vec);
+	void (*inject_pending_irq)(struct kvm_vcpu *vcpu);
+	void (*inject_pending_vectors)(struct kvm_vcpu *vcpu,
+				      ...
To: <kvm-devel@...>
Cc: <linux-kernel@...>, He, Qing <qing.he@...>
Date: Monday, September 17, 2007 - 4:32 am

From: He, Qing &lt;qing.he@intel.com&gt;

According to Intel Software Developer's Manual, Vol. 3B, Appendix H.4.2,
exit qualification should be of natural width. However, current code
uses u64 as the data type for this register, which occasionally
introduces invalid value to VMExit handling logics. This patch fixes
this bug.

I have tested Windows and Linux guest on i386 host, and they can boot
successfully with this patch.

Signed-off-by: Qing He &lt;qing.he@intel.com&gt;
Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/vmx.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index fa4277d..c44c9ac 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -1840,12 +1840,12 @@ static int handle_triple_fault(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 
 static int handle_io(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 {
-	u64 exit_qualification;
+	unsigned long exit_qualification;
 	int size, down, in, string, rep;
 	unsigned port;
 
 	++vcpu-&gt;stat.io_exits;
-	exit_qualification = vmcs_read64(EXIT_QUALIFICATION);
+	exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
 	string = (exit_qualification &amp; 16) != 0;
 
 	if (string) {
@@ -1877,11 +1877,11 @@ vmx_patch_hypercall(struct kvm_vcpu *vcpu, unsigned char *hypercall)
 
 static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 {
-	u64 exit_qualification;
+	unsigned long exit_qualification;
 	int cr;
 	int reg;
 
-	exit_qualification = vmcs_read64(EXIT_QUALIFICATION);
+	exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
 	cr = exit_qualification &amp; 15;
 	reg = (exit_qualification &gt;&gt; 8) &amp; 15;
 	switch ((exit_qualification &gt;&gt; 4) &amp; 3) {
@@ -1950,7 +1950,7 @@ static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 
 static int handle_dr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 {
-	u64 exit_qualification;
+	unsigned long exit_qualification;
 	unsigned ...
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Nitin A Kamble <nitin.a.kamble@...>
Date: Monday, September 17, 2007 - 4:32 am

From: Nitin A Kamble &lt;nitin.a.kamble@intel.com&gt;

Implement the instruction

    	push imm8
    	opcode: 0x6a

Signed-off-by: Nitin A Kamble &lt;nitin.a.kamble@intel.com&gt;
Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/x86_emulate.c |   17 ++++++++++++++---
 1 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index 86171ca..4fc2da6 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -104,10 +104,11 @@ static u8 opcode_table[256] = {
 	/* 0x58 - 0x5F */
 	ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
 	ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
-	/* 0x60 - 0x6B */
+	/* 0x60 - 0x67 */
 	0, 0, 0, DstReg | SrcMem32 | ModRM | Mov /* movsxd (x86/64) */ ,
-	0, 0, 0, 0, 0, 0, 0, 0,
-	/* 0x6C - 0x6F */
+	0, 0, 0, 0,
+	/* 0x68 - 0x6F */
+	0, 0, ImplicitOps|Mov, 0,
 	SrcNone  | ByteOp  | ImplicitOps, SrcNone  | ImplicitOps, /* insb, insw/insd */
 	SrcNone  | ByteOp  | ImplicitOps, SrcNone  | ImplicitOps, /* outsb, outsw/outsd */
 	/* 0x70 - 0x7F */
@@ -919,6 +920,16 @@ done_prefixes:
 			goto cannot_emulate;
 		dst.val = (s32) src.val;
 		break;
+	case 0x6a: /* push imm8 */
+		src.val = 0L;
+		src.val = insn_fetch(s8, 1, _eip);
+push:
+		dst.type  = OP_MEM;
+		dst.bytes = op_bytes;
+		dst.val = src.val;
+		register_address_increment(_regs[VCPU_REGS_RSP], -op_bytes);
+		dst.ptr = register_address(ctxt-&gt;ss_base, _regs[VCPU_REGS_RSP]);
+		break;
 	case 0x80 ... 0x83:	/* Grp1 */
 		switch (modrm_reg) {
 		case 0:
-- 
1.5.3

-
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Nitin A Kamble <nitin.a.kamble@...>
Date: Monday, September 17, 2007 - 4:32 am

From: Nitin A Kamble &lt;nitin.a.kamble@intel.com&gt;

Implement emulation of instruction
	opcode: 0xe8
	call (near)

Signed-off-by: Nitin A Kamble &lt;nitin.a.kamble@intel.com&gt;
Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/x86_emulate.c |   22 +++++++++++++++++++++-
 1 files changed, 21 insertions(+), 1 deletions(-)

diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index 4fc2da6..9f1772f 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -150,7 +150,7 @@ static u8 opcode_table[256] = {
 	/* 0xE0 - 0xE7 */
 	0, 0, 0, 0, 0, 0, 0, 0,
 	/* 0xE8 - 0xEF */
-	0, SrcImm|ImplicitOps, 0, SrcImmByte|ImplicitOps, 0, 0, 0, 0,
+	ImplicitOps, SrcImm|ImplicitOps, 0, SrcImmByte|ImplicitOps, 0, 0, 0, 0,
 	/* 0xF0 - 0xF7 */
 	0, 0, 0, 0,
 	ImplicitOps, 0,
@@ -1033,6 +1033,26 @@ push:
 	case 0xd2 ... 0xd3:	/* Grp2 */
 		src.val = _regs[VCPU_REGS_RCX];
 		goto grp2;
+	case 0xe8: /* call (near) */ {
+		long int rel;
+		switch (op_bytes) {
+		case 2:
+			rel = insn_fetch(s16, 2, _eip);
+			break;
+		case 4:
+			rel = insn_fetch(s32, 4, _eip);
+			break;
+		case 8:
+			rel = insn_fetch(s64, 8, _eip);
+			break;
+		default:
+			DPRINTF("Call: Invalid op_bytes\n");
+			goto cannot_emulate;
+		}
+		src.val = (unsigned long) _eip;
+		JMP_REL(rel);
+		goto push;
+	}
 	case 0xe9: /* jmp rel */
 	case 0xeb: /* jmp rel short */
 		JMP_REL(src.val);
-- 
1.5.3

-
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Nitin A Kamble <nitin.a.kamble@...>
Date: Monday, September 17, 2007 - 4:32 am

From: Nitin A Kamble &lt;nitin.a.kamble@intel.com&gt;

Implement emulation of instruction
	pushf
	opcode: 0x9c

Signed-off-by: Nitin A Kamble &lt;nitin.a.kamble@intel.com&gt;
Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/x86_emulate.c |   11 +++++++++--
 1 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index 9f1772f..18c2b2c 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -123,7 +123,7 @@ static u8 opcode_table[256] = {
 	ByteOp | DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
 	0, 0, 0, DstMem | SrcNone | ModRM | Mov,
 	/* 0x90 - 0x9F */
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps, 0, 0, 0,
 	/* 0xA0 - 0xA7 */
 	ByteOp | DstReg | SrcMem | Mov, DstReg | SrcMem | Mov,
 	ByteOp | DstMem | SrcReg | Mov, DstMem | SrcReg | Mov,
@@ -928,7 +928,8 @@ push:
 		dst.bytes = op_bytes;
 		dst.val = src.val;
 		register_address_increment(_regs[VCPU_REGS_RSP], -op_bytes);
-		dst.ptr = register_address(ctxt-&gt;ss_base, _regs[VCPU_REGS_RSP]);
+		dst.ptr = (void *) register_address(ctxt-&gt;ss_base,
+							_regs[VCPU_REGS_RSP]);
 		break;
 	case 0x80 ... 0x83:	/* Grp1 */
 		switch (modrm_reg) {
@@ -1216,6 +1217,12 @@ special_insn:
 				) == 0)
 			return -1;
 		return 0;
+
+	case 0x9c: /* pushf */
+		src.val =  (unsigned long) _eflags;
+		goto push;
+		break;
+
 	}
 	if (rep_prefix) {
 		if (_regs[VCPU_REGS_RCX] == 0) {
-- 
1.5.3

-
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Avi Kivity <avi@...>
Date: Monday, September 17, 2007 - 4:32 am

Report failed opcodes from all locations.

Signed-off-by: Avi Kivity &lt;avi@qumranet.com&gt;
---
 drivers/kvm/kvm.h      |    1 +
 drivers/kvm/kvm_main.c |   16 ++++++++--------
 drivers/kvm/svm.c      |    2 +-
 drivers/kvm/vmx.c      |    2 +-
 4 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index d93ab48..ad08138 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -558,6 +558,7 @@ enum emulation_result {
 
 int emulate_instruction(struct kvm_vcpu *vcpu, struct kvm_run *run,
 			unsigned long cr2, u16 error_code);
+void kvm_report_emulation_failure(struct kvm_vcpu *cvpu, const char *context);
 void realmode_lgdt(struct kvm_vcpu *vcpu, u16 size, unsigned long address);
 void realmode_lidt(struct kvm_vcpu *vcpu, u16 size, unsigned long address);
 void realmode_lmsw(struct kvm_vcpu *vcpu, unsigned long msw,
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index e6301ce..99e4917 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -1240,25 +1240,25 @@ int emulator_set_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long value)
 	return X86EMUL_CONTINUE;
 }
 
-static void report_emulation_failure(struct x86_emulate_ctxt *ctxt)
+void kvm_report_emulation_failure(struct kvm_vcpu *vcpu, const char *context)
 {
 	static int reported;
 	u8 opcodes[4];
-	unsigned long rip = ctxt-&gt;vcpu-&gt;rip;
+	unsigned long rip = vcpu-&gt;rip;
 	unsigned long rip_linear;
 
-	rip_linear = rip + get_segment_base(ctxt-&gt;vcpu, VCPU_SREG_CS);
+	rip_linear = rip + get_segment_base(vcpu, VCPU_SREG_CS);
 
 	if (reported)
 		return;
 
-	emulator_read_std(rip_linear, (void *)opcodes, 4, ctxt-&gt;vcpu);
+	emulator_read_std(rip_linear, (void *)opcodes, 4, vcpu);
 
-	printk(KERN_ERR "emulation failed but !mmio_needed?"
-	       " rip %lx %02x %02x %02x %02x\n",
-	       rip, opcodes[0], opcodes[1], opcodes[2], opcodes[3]);
+	printk(KERN_ERR "emulation failed (%s) rip %lx %02x %02x %02x %02x\n",
+	      ...
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Nitin A Kamble <nitin.a.kamble@...>
Subject: