[PATCH 092/104] KVM: VMX: Fix exit qualification width on i386

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->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&m=119002061330270&w=2
http://marc.info/?l=linux-kernel&m=119002059626434&w=2
http://marc.info/?l=linux-kernel&m=119002060011801&w=2
http://marc.info/?l=linux-kernel&m=119002060318915&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 = "<%s-git-send-email-$du_part>";
- $message_id = sprintf $message_id_template, "$date$pseudo_rand";
+ my $message_id_template = "<%s-git-send-email-%s>";
+ $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 <postmaster@vger.kernel.org>
-

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

From: Rusty Russell <rusty@rustcorp.com.au>

Speling error in comment.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
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 <rusty@rustcorp.com.au>

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 <rusty@rustcorp.com.au>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
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 <linux/kvm.h>
#include <linux/kvm_para.h>

-#define CR3_WPT_MASK (1ULL << 3)
-#define CR3_PCD_MASK (1ULL << 4)
-
-#define CR3_RESEVED_BITS 0x07ULL
-#define CR3_L_MODE_RESEVED_BITS (~((1ULL << 40) - 1) | 0x0fe7ULL)
-#define CR3_FLAGS_MASK ((1ULL << 5) - 1)
+#define CR3_PAE_RESERVED_BITS ((X86_CR3_PWT | X86_CR3_PCD) - 1)
+#define CR3_NONPAE_RESERVED_BITS ((PAGE_SIZE-1) & ~(X86_CR3_PWT | X86_CR3_PCD))
+#define CR3_L_MODE_RESERVED_BITS (CR3_NONPAE_RESERVED_BITS|0xFFFFFF0000000000ULL)

#define CR4_VME_MASK (1ULL << 0)
#define CR4_PSE_MASK (1ULL << 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 & CR3_L_MODE_RESEVED_BITS) {
+ if (cr3 & CR3_L_MODE_RESERVED_BITS) {
printk(KERN_DEBUG "set_cr3: #GP, reserved bits\n");
inject_gp(vcpu);
return;
}
} else {
- if (cr3 & CR3_RESEVED_BITS) {
- printk(KERN_DEBUG "set_cr3: #GP, reserved bits\n");
- inject_gp(vcpu);
- return;
- }
- if (is_paging(vcpu) && is_pae(vcpu) &&
- ...

To: <kvm-devel@...>
Cc: <linux-kernel@...>, Jeff Dike <jdike@...>
Date: Monday, September 17, 2007 - 4:30 am

From: Jeff Dike <jdike@addtoit.com>

Signed-off-by: Jeff Dike <jdike@linux.intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
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(&emulate_ctxt, &emulate_ops);

if ((r || vcpu->mmio_is_write) && run) {
+ run->exit_reason = KVM_EXIT_MMIO;
run->mmio.phys_addr = vcpu->mmio_phys_addr;
memcpy(run->mmio.data, vcpu->mmio_data, 8);
run->mmio.len = vcpu->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->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->stat.mmio_exits;
- kvm_run->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->stat.mmio_exits;
- kvm_run->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 <rusty@rustcorp.com.au>

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 <rusty@rustcorp.com.au>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
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) & ~(X86_CR3_PWT | X86_CR3_PCD))
#define CR3_L_MODE_RESERVED_BITS (CR3_NONPAE_RESERVED_BITS|0xFFFFFF0000000000ULL)

-#define CR4_VME_MASK (1ULL << 0)
-#define CR4_PSE_MASK (1ULL << 4)
-#define CR4_PAE_MASK (1ULL << 5)
-#define CR4_PGE_MASK (1ULL << 7)
-#define CR4_VMXE_MASK (1ULL << 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 <rusty@rustcorp.com.au>

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

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Acked-by: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
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 & CR8_RESEVED_BITS) {
+ if (cr8 & 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 <asm/msr-index.h>
--
1.5.3

-

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

From: Rusty Russell <rusty@rustcorp.com.au>

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

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
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)
&& !load_pdptrs(vcpu, vcpu->cr3)) {
printk(KERN_DEBUG "set_cr4: #GP, pdptrs reserved bits\n");
inject_gp(vcpu);
+ return;
}

if (cr4 & 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 <rusty@rustcorp.com.au>

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->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 <rusty@rustcorp.com.au>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
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 >> PAGE_SHIFT;
unsigned offset = ((cr3 & (PAGE_SIZE-1)) >> 5) << 2;
int i;
- u64 pdpte;
u64 *pdpt;
int ret;
struct page *page;
+ u64 pdpte[ARRAY_SIZE(vcpu->pdptrs)];

spin_lock(&vcpu->kvm->lock);
page = gfn_to_page(vcpu->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 < 4; ++i) {
- pdpte = pdpt[offset + i];
- if ((pdpte & 1) && (pdpte & 0xfffffff0000001e6ull)) {
+ for (i = 0; i < ARRAY_SIZE(pdpte); ++i) {
+ if ((pdpte[i] & 1) && (pdpte[i] & 0xfffffff0000001e6ull)) {
ret = 0;
goto out;
}
}
+ ret = 1;

- for (i = 0; i < 4; ++i)
- vcpu->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 <sheng.yang@intel.com>

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 <sheng.yang@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
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 & 5) == 1; /* locked but not enabled */
+ return (msr & (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 & 5) != 5)
+ if ((old & (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"(&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 <avi@qumranet.com>
---
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 &= ~Mov; /* default to no move */
+ no_wb = 1;
/*
* First, assume we're decoding an even cmov opcode
* (lsb == 0).
*/
switch ((b & 15) >> 1) {
case 0: /* cmovo */
- d |= (_eflags & EFLG_OF) ? Mov : 0;
+ no_wb = (_eflags & EFLG_OF) ? 0 : 1;
break;
case 1: /* cmovb/cmovc/cmovnae */
- d |= (_eflags & EFLG_CF) ? Mov : 0;
+ no_wb = (_eflags & EFLG_CF) ? 0 : 1;
break;
case 2: /* cmovz/cmove */
- d |= (_eflags & EFLG_ZF) ? Mov : 0;
+ no_wb = (_eflags & EFLG_ZF) ? 0 : 1;
break;
case 3: /* cmovbe/cmovna */
- d |= (_eflags & (EFLG_CF | EFLG_ZF)) ? Mov : 0;
+ no_wb = (_eflags & (EFLG_CF | EFLG_ZF)) ? 0 : 1;
break;
case 4: /* cmovs */
- d |= (_eflags & EFLG_SF) ? Mov : 0;
+ no_wb = (_eflags & EFLG_SF) ? 0 : 1;
break;
case 5: /* cmovp/cmovpe */
- d |= (_eflags & EFLG_PF) ? Mov : 0;
+ no_wb = (_eflags & EFLG_PF) ? 0 : 1;
break;
case 7: /* cmovle/cmovng */
- d |= (_eflags & EFLG_ZF) ? Mov : 0;
+ no_wb = (_eflags & EFLG_ZF) ? 0 : 1;
/* fall through */
case 6: /* cmovl/cmovnge */
- d |= (!(_eflags & EFLG_SF) !=
- !(_eflags & EFLG_OF)) ? Mov : 0;
+ no_wb &= (!(_eflags & EFLG_SF) !=
+ !(_eflags & EFLG_OF)) ? 0 : 1;
break;
}
/* Odd cmov opcodes (lsb == 1) have inverted sense. */
- d ^= (b & 1) ? Mov : 0;
+ no_wb ^= b &...

To: <kvm-devel@...>
Cc: <linux-kernel@...>, Yang, Sheng <sheng.yang@...>
Date: Monday, September 17, 2007 - 4:31 am

From: Yang, Sheng <sheng.yang@intel.com>

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 <sheng.yang@intel.com>
Signed-off-by: Glauber de Oliveira Costa <gcosta@redhat.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
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 &= vmx_msr_high; /* bit == 0 in high word ==> must be zero */
+ ctl |= vmx_msr_low; /* bit == 1 in low word ==> must be one */
+
+ /* Ensure minimum (required) set of control bits are supported. */
+ if (ctl_min & ~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 <shaohua.li@intel.com>

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

Signed-off-by: Shaohua Li <shaohua.li@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
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(&kvm->pio_bus);
- spin_lock_init(&kvm->lock);
+ mutex_init(&kvm->lock);
INIT_LIST_HEAD(&kvm->active_mmu_pages);
kvm_io_bus_init(&kvm->mmio_bus);
spin_lock(&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->pdptrs)];

- spin_lock(&vcpu->kvm->lock);
+ mutex_lock(&vcpu->kvm->lock);
page = gfn_to_page(vcpu->kvm, pdpt_gfn);
if (!page) {
ret = 0;
@@ -510,7 +510,7 @@ static int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3)

memcpy(vcpu->pdptrs, pdpte, sizeof(vcpu->pdptrs));
out:
- spin_unlock(&vcpu->kvm->lock);
+ mutex_unlock(&vcpu->kvm->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 <Laurent.Vivier@bull.net>

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

Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
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->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->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->mmio_data, bytes);
vcpu->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 <rusty@rustcorp.com.au>

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 <rusty@rustcorp.com.au>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
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 & ~(0x3 << msr_shift)) |
(mask << 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 <ghaskins@novell.com>

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

Signed-off-by: Gregory Haskins <ghaskins@novell.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
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 <linux/mm.h>
#include <asm/signal.h>

-#include "vmx.h"
#include <linux/kvm.h>
#include <linux/kvm_para.h>

@@ -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 <rusty@rustcorp.com.au>

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

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
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 <shaohua.li@intel.com>.

Signed-off-by: Avi Kivity <avi@qumranet.com>
---
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 && 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 <linux/signal.h>
#include <linux/sched.h>
#include <linux/mm.h>
+#include <linux/preempt.h>
#include <asm/signal.h>

#include <linux/kvm.h>
@@ -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 <Laurent.Vivier@bull.net>

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

Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
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 >= 0 && n < 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 <rusty@rustcorp.com.au>

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 <rusty@rustcorp.com.au>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
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 <rusty@rustcorp.com.au>

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 <rusty@rustcorp.com.au>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
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 & 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->msr_offset_efer;
return msr_efer_save_restore_bits(vmx->host_msrs[efer_offset]) !=
msr_efer_save_restore_bits(vmx->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 < vmx->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 >= 0)
return &vmx->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 <xin.b.li@intel.com>

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

Signed-off-by: Xin Li <xin.b.li@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
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)->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)
- & ~VM_ENTRY_CONTROLS_IA32E_MASK);
+ & ~VM_ENTRY_IA32E_MODE);
}

#endif
@@ -1185,13 +1185,13 @@ static void vmx_set_efer(struct kvm_vcpu *vcpu, u64 efer)
if (efer & EFER_LMA) {
vmcs_write32(VM_ENTRY_CONTROLS,
vmcs_read32(VM_ENTRY_CONTROLS) |
- VM_ENTRY_CONTROLS_IA32E_MASK);
+ VM_ENTRY_IA32E_MODE);
msr->data = efer;

} else {
vmcs_write32(VM_ENTRY_CONTROLS,
vmcs_read32(VM_ENTRY_CONTROLS) &
- ~VM_ENTRY_CONTROLS_IA32E_MASK);
+ ~VM_ENTRY_IA32E_MODE);

msr->data = efer & ~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 << 13)

-/* entry controls */
-#define VM_ENTRY_CONTROLS_IA32E_MASK (1 << 9)
-
#define AR_TYPE_ACCESSES_MASK 1
#define AR_TYPE_READABLE_MASK (1 << 1)
#define AR_TYPE_WRITEABLE_MASK (1 <&...

To: <kvm-devel@...>
Cc: <linux-kernel@...>, Yang, Sheng <sheng.yang@...>
Date: Monday, September 17, 2007 - 4:31 am

From: Yang, Sheng <sheng.yang@intel.com>

This allows running 64-bit Windows.

Signed-off-by: Sheng Yang <sheng.yang@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
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->regs[reg]);
skip_emulated_instruction(vcpu);
- return 1;
+ kvm_run->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 <nitin.a.kamble@intel.com>

Signed-off-by: Nitin A Kamble <nitin.a.kamble@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
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) & ((1UL << (ad_bytes << 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 <nitin.a.kamble@intel.com>

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

Signed-off-by: Nitin A Kamble <nitin.a.kamble@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
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 = &_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 = &_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 <nitin.a.kamble@intel.com>

Signed-off-by: Nitin A Kamble <nitin.a.kamble@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
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 & 0x7];
+ else
+ src.val = (u32) _regs[b & 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->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->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 <Laurent.Vivier@bull.net>

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 <Laurent.Vivier@bull.net>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
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->mmio_is_write = 0;
+ vcpu->pio.string = 0;
r = x86_emulate_memop(&emulate_ctxt, &emulate_ops);
+ if (vcpu->pio.string)
+ return EMULATE_DO_MMIO;

if ((r || vcpu->mmio_is_write) && run) {
run->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 & feat;
}

-static unsigned get_addr_size(struct vcpu_svm *svm)
-{
- struct vmcb_save_area *sa = &svm->vmcb->save;
- u16 cs_attrib;
-
- if (!(sa->cr0 & X86_CR0_PE) || (sa->rflags & 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 <avi@qumranet.com>
---
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->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 <eddie.dong@intel.com>

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

Signed-off-by: Yaozu (Eddie) Dong <eddie.dong@intel.com>
Signed-off-by: Qing He <qing.he@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
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->efer = vcpu->shadow_efer;
sregs->apic_base = kvm_get_apic_base(vcpu);

- if (irqchip_in_kernel(vcpu->kvm))
+ if (irqchip_in_kernel(vcpu->kvm)) {
memset(sregs->interrupt_bitmap, 0,
sizeof sregs->interrupt_bitmap);
- else
+ pending_vec = kvm_arch_ops->get_irq(vcpu);
+ if (pending_vec >= 0) {
+ set_bit(pending_vec, sregs->interrupt_bitmap);
+ printk("pending irq in kernel %d\n",pending_vec);
+ }
+ } else
memcpy(sregs->interrupt_bitmap, vcpu->irq_pending,
sizeof sregs->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 <amit.shah@qumranet.com>

This was missed when moving stuff around in fbc4f2e

Fixes Solaris guests and bug #1773613

Signed-off-by: Amit Shah <amit.shah@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
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(&vcpu->host_fx_image);
preempt_enable();

+ vcpu->cr0 |= X86_CR0_ET;
after_mxcsr_mask = offsetof(struct i387_fxsave_struct, st_space);
vcpu->guest_fx_image.mxcsr = 0x1f80;
memset((void *)&vcpu->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 <rusty@rustcorp.com.au>

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 <rusty@rustcorp.com.au>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
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 >> 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] &=...

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

From: Rusty Russell <rusty@rustcorp.com.au>

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
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->vmcb->control.asid = svm_data->next_asid++;
}

-static void svm_invlpg(struct kvm_vcpu *vcpu, gva_t address)
-{
- invlpga(address, to_svm(vcpu)->vmcb->control.asid); // is needed?
-}
-
static unsigned long svm_get_dr(struct kvm_vcpu *vcpu, int dr)
{
return to_svm(vcpu)->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 <qing.he@intel.com>

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

[avi: remove smp_processor_id() warning]

Signed-off-by: Qing He <qing.he@intel.com>
Signed-off-by: Xin Li <xin.b.li@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
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 <rusty@rustcorp.com.au>

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

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
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->set_cr4(vcpu, cr4);
+ vcpu->cr4 = cr4;
mutex_lock(&vcpu->kvm->lock);
kvm_mmu_reset_context(vcpu);
mutex_unlock(&vcpu->kvm->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->cr0 & ~X86_CR0_TS;
- kvm_arch_ops->set_cr0(vcpu, cr0);
+ vcpu->cr0 &= ~X86_CR0_TS;
+ kvm_arch_ops->set_cr0(vcpu, vcpu->cr0);
return X86EMUL_CONTINUE;
}

@@ -2228,6 +2227,7 @@ static int kvm_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
kvm_arch_ops->decache_cr4_guest_bits(vcpu);

mmu_reset_needed |= vcpu->cr0 != sregs->cr0;
+ vcpu->cr0 = sregs->cr0;
kvm_arch_ops->set_cr0(vcpu, sregs->cr0);

mmu_reset_needed |= vcpu->cr4 != sregs->cr4;
--
1.5.3

-

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

From: Rusty Russell <rusty@rustcorp.com.au>

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 <rusty@rustcorp.com.au>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
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, &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->unusable = !var->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 <avi@qumranet.com>
---
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 <qing.he@intel.com>

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 <qing.he@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
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->stat.io_exits;
- exit_qualification = vmcs_read64(EXIT_QUALIFICATION);
+ exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
string = (exit_qualification & 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 & 15;
reg = (exit_qualification >> 8) & 15;
switch ((exit_qualification >> 4) & 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 <nitin.a.kamble@intel.com>

Implement the instruction

push imm8
opcode: 0x6a

Signed-off-by: Nitin A Kamble <nitin.a.kamble@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
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->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 <nitin.a.kamble@intel.com>

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

Signed-off-by: Nitin A Kamble <nitin.a.kamble@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
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 <nitin.a.kamble@intel.com>

Implement emulation of instruction
pushf
opcode: 0x9c

Signed-off-by: Nitin A Kamble <nitin.a.kamble@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
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->ss_base, _regs[VCPU_REGS_RSP]);
+ dst.ptr = (void *) register_address(ctxt->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 <avi@qumranet.com>
---
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->vcpu->rip;
+ unsigned long rip = vcpu->rip;
unsigned long rip_linear;

- rip_linear = rip + get_segment_base(ctxt->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->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@...>
Date: Monday, September 17, 2007 - 4:32 am

From: Nitin A Kamble <nitin.a.kamble@intel.com>

Signed-off-by: Nitin A Kamble <nitin.a.kamble@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/x86_emulate.c | 99 ++++++++++++++++++++++-----------------------
1 files changed, 49 insertions(+), 50 deletions(-)

diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index 18c2b2c..e4ce34c 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -978,19 +978,8 @@ push:
dst.val = src.val;
lock_prefix = 1;
break;
- case 0xa0 ... 0xa1: /* mov */
- dst.ptr = (unsigned long *)&_regs[VCPU_REGS_RAX];
- dst.val = src.val;
- _eip += ad_bytes; /* skip src displacement */
- break;
- case 0xa2 ... 0xa3: /* mov */
- dst.val = (unsigned long)_regs[VCPU_REGS_RAX];
- _eip += ad_bytes; /* skip dst displacement */
- break;
case 0x88 ... 0x8b: /* mov */
- case 0xc6 ... 0xc7: /* mov (sole member of Grp11) */
- dst.val = src.val;
- break;
+ goto mov;
case 0x8f: /* pop (sole member of Grp1a) */
/* 64-bit mode: POP always pops a 64-bit operand. */
if (mode == X86EMUL_MODE_PROT64)
@@ -1001,6 +990,15 @@ push:
goto done;
register_address_increment(_regs[VCPU_REGS_RSP], dst.bytes);
break;
+ case 0xa0 ... 0xa1: /* mov */
+ dst.ptr = (unsigned long *)&_regs[VCPU_REGS_RAX];
+ dst.val = src.val;
+ _eip += ad_bytes; /* skip src displacement */
+ break;
+ case 0xa2 ... 0xa3: /* mov */
+ dst.val = (unsigned long)_regs[VCPU_REGS_RAX];
+ _eip += ad_bytes; /* skip dst displacement */
+ break;
case 0xc0 ... 0xc1:
grp2: /* Grp2 */
switch (modrm_reg) {
@@ -1028,6 +1026,10 @@ push:
break;
}
break;
+ case 0xc6 ... 0xc7: /* mov (sole member of Grp11) */
+ mov:
+ dst.val = src.val;
+ break;
case 0xd0 ... 0xd1: /* Grp2 */
src.val = 1;
goto grp2;
@@ -1186,6 +1188,17 @@ special_insn:
dst.ptr = (void *) register_address(
ctxt->ss_base, _regs[VCPU_REGS_RSP]);
break;
+ case 0x58 ...

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

From: Nitin A Kamble <nitin.a.kamble@intel.com>

Implement emulation of instruction:
popf
opcode: 0x9d

Signed-off-by: Nitin A Kamble <nitin.a.kamble@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/x86_emulate.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index 7360a71..9737c3b 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -127,7 +127,7 @@ static u8 opcode_table[256] = {
ByteOp | DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
0, ModRM | DstReg, 0, DstMem | SrcNone | ModRM | Mov,
/* 0x90 - 0x9F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps, ImplicitOps, 0, 0,
/* 0xA0 - 0xA7 */
ByteOp | DstReg | SrcMem | Mov, DstReg | SrcMem | Mov,
ByteOp | DstMem | SrcReg | Mov, DstMem | SrcReg | Mov,
@@ -1293,6 +1293,9 @@ special_insn:
case 0x9c: /* pushf */
src.val = (unsigned long) _eflags;
goto push;
+ case 0x9d: /* popf */
+ dst.ptr = (unsigned long *) &_eflags;
+ goto pop_instruction;
case 0xc3: /* ret */
dst.ptr = &_eip;
goto pop_instruction;
--
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 <nitin.a.kamble@intel.com>

Implement emulation of more jump conditional instructions
jcc shortrel
opcodes: 0x70 - 0x7f

Signed-off-by: Nitin A Kamble <nitin.a.kamble@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/x86_emulate.c | 15 +++++++++++++--
1 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index ba53e59..57f1a5a 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -111,8 +111,12 @@ static u8 opcode_table[256] = {
0, 0, ImplicitOps|Mov, 0,
SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, /* insb, insw/insd */
SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, /* outsb, outsw/outsd */
- /* 0x70 - 0x7F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 0x70 - 0x77 */
+ ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
+ ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
+ /* 0x78 - 0x7F */
+ ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
+ ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
/* 0x80 - 0x87 */
ByteOp | DstMem | SrcImm | ModRM, DstMem | SrcImm | ModRM,
ByteOp | DstMem | SrcImm | ModRM, DstMem | SrcImmByte | ModRM,
@@ -1268,6 +1272,13 @@ special_insn:
) == 0)
return -1;
return 0;
+ case 0x70 ... 0x7f: /* jcc (short) */ {
+ int rel = insn_fetch(s8, 1, _eip);
+
+ if (test_cc(b, _eflags))
+ JMP_REL(rel);
+ break;
+ }
case 0x9c: /* pushf */
src.val = (unsigned long) _eflags;
goto push;
--
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 <nitin.a.kamble@intel.com>

Some operand fetches are less than the machine word size and can result in
stale bits if used together with operands of different sizes.

Signed-off-by: Nitin A Kamble <nitin.a.kamble@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/x86_emulate.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index cf8db67..7360a71 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -827,6 +827,7 @@ done_prefixes:
srcmem_common:
src.type = OP_MEM;
src.ptr = (unsigned long *)cr2;
+ src.val = 0;
if ((rc = ops->read_emulated((unsigned long)src.ptr,
&src.val, src.bytes, ctxt->vcpu)) != 0)
goto done;
@@ -891,6 +892,7 @@ done_prefixes:
dst.type = OP_MEM;
dst.ptr = (unsigned long *)cr2;
dst.bytes = (d & ByteOp) ? 1 : op_bytes;
+ dst.val = 0;
if (d & BitOp) {
unsigned long mask = ~(dst.bytes * 8 - 1);

--
1.5.3

-

To: <kvm-devel@...>
Cc: <linux-kernel@...>, Christian Ehrhardt <ehrhardt@...>
Date: Monday, September 17, 2007 - 4:32 am

From: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>

This patch just renames the current (misnamed) _arch namings to _x86 to
ensure better readability when a real arch layer takes place.

Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/kvm.h | 8 +-
drivers/kvm/kvm_main.c | 160 ++++++++++++++++++++++----------------------
drivers/kvm/mmu.c | 6 +-
drivers/kvm/paging_tmpl.h | 2 +-
drivers/kvm/svm.c | 6 +-
drivers/kvm/vmx.c | 6 +-
drivers/kvm/x86_emulate.c | 4 +-
7 files changed, 96 insertions(+), 96 deletions(-)

diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index 351da40..42bb225 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -441,7 +441,7 @@ struct descriptor_table {
unsigned long base;
} __attribute__((packed));

-struct kvm_arch_ops {
+struct kvm_x86_ops {
int (*cpu_has_kvm_support)(void); /* __init */
int (*disabled_by_bios)(void); /* __init */
void (*hardware_enable)(void *dummy); /* __init */
@@ -499,7 +499,7 @@ struct kvm_arch_ops {
void (*set_irq)(struct kvm_vcpu *vcpu, int vec);
};

-extern struct kvm_arch_ops *kvm_arch_ops;
+extern struct kvm_x86_ops *kvm_x86_ops;

/* The guest did something we don't support. */
#define pr_unimpl(vcpu, fmt, ...) \
@@ -515,9 +515,9 @@ extern struct kvm_arch_ops *kvm_arch_ops;
int kvm_vcpu_init(struct kvm_vcpu *vcpu, struct kvm *kvm, unsigned id);
void kvm_vcpu_uninit(struct kvm_vcpu *vcpu);

-int kvm_init_arch(struct kvm_arch_ops *ops, unsigned int vcpu_size,
+int kvm_init_x86(struct kvm_x86_ops *ops, unsigned int vcpu_size,
struct module *module);
-void kvm_exit_arch(void);
+void kvm_exit_x86(void);

int kvm_mmu_module_init(void);
void kvm_mmu_module_exit(void);
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index c2c8c93..4c3b7ed 100644
--- a/drivers/kvm/kvm_main.c
+++ b/dri...

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

From: Nitin A Kamble <nitin.a.kamble@intel.com>

Implement emulation of instruction:
jump conditional rel
opcodes: 0x0f 0x80 - 0x0f 0x8f

Signed-off-by: Nitin A Kamble <nitin.a.kamble@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/x86_emulate.c | 61 ++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 60 insertions(+), 1 deletions(-)

diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index e4ce34c..ba53e59 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -188,7 +188,10 @@ static u16 twobyte_table[256] = {
/* 0x70 - 0x7F */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 0x80 - 0x8F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
+ ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
+ ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
+ ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
/* 0x90 - 0x9F */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 0xA0 - 0xA7 */
@@ -479,6 +482,41 @@ static int read_descriptor(struct x86_emulate_ctxt *ctxt,
return rc;
}

+static int test_cc(unsigned int condition, unsigned int flags)
+{
+ int rc = 0;
+
+ switch ((condition & 15) >> 1) {
+ case 0: /* o */
+ rc |= (flags & EFLG_OF);
+ break;
+ case 1: /* b/c/nae */
+ rc |= (flags & EFLG_CF);
+ break;
+ case 2: /* z/e */
+ rc |= (flags & EFLG_ZF);
+ break;
+ case 3: /* be/na */
+ rc |= (flags & (EFLG_CF|EFLG_ZF));
+ break;
+ case 4: /* s */
+ rc |= (flags & EFLG_SF);
+ break;
+ case 5: /* p/pe */
+ rc |= (flags & EFLG_PF);
+ break;
+ case 7: /* le/ng */
+ rc |= (flags & EFLG_ZF);
+ /* fall through */
+ case 6: /* l/nge */
+ rc |= (!(flags & EFLG_SF) != !(flags & EFLG_OF));
+ break;
+ }
+
+ /* Odd condition identifiers (lsb == 1) have inverted sense. */
+ return (!!rc ^ (condition & 1));
+}
+
int
x86_emulate_mem...

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

From: Nitin A Kamble <nitin.a.kamble@intel.com>

Implement emulation of instruction
lea r16/r32, m
opcode: 0x8d:

Signed-off-by: Nitin A Kamble <nitin.a.kamble@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/x86_emulate.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index 57f1a5a..4c78a4f 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -125,7 +125,7 @@ static u8 opcode_table[256] = {
/* 0x88 - 0x8F */
ByteOp | DstMem | SrcReg | ModRM | Mov, DstMem | SrcReg | ModRM | Mov,
ByteOp | DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
- 0, 0, 0, DstMem | SrcNone | ModRM | Mov,
+ 0, ModRM | DstReg, 0, DstMem | SrcNone | ModRM | Mov,
/* 0x90 - 0x9F */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps, 0, 0, 0,
/* 0xA0 - 0xA7 */
@@ -1022,6 +1022,9 @@ push:
break;
case 0x88 ... 0x8b: /* mov */
goto mov;
+ case 0x8d: /* lea r16/r32, m */
+ dst.val = modrm_val;
+ break;
case 0x8f: /* pop (sole member of Grp1a) */
/* 64-bit mode: POP always pops a 64-bit operand. */
if (mode == X86EMUL_MODE_PROT64)
--
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 <nitin.a.kamble@intel.com>

Implement emulation of instruction:
jump absolute r/m
opcode: 0xff /4

Signed-off-by: Nitin A Kamble <nitin.a.kamble@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/x86_emulate.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index 4c78a4f..cf8db67 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -1148,6 +1148,12 @@ push:
case 1: /* dec */
emulate_1op("dec", dst, _eflags);
break;
+ case 4: /* jmp abs */
+ if (b == 0xff)
+ _eip = dst.val;
+ else
+ goto cannot_emulate;
+ break;
case 6: /* push */
/* 64-bit mode: PUSH always pushes a 64-bit operand. */
if (mode == X86EMUL_MODE_PROT64) {
--
1.5.3

-

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

This will help moving the main loop to subarch independent code.

Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/vmx.c | 19 ++++++++++---------
1 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index 57a6055..713f78a 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -43,6 +43,7 @@ struct vmcs {
struct vcpu_vmx {
struct kvm_vcpu vcpu;
int launched;
+ u8 fail;
struct kvm_msr_entry *guest_msrs;
struct kvm_msr_entry *host_msrs;
int nmsrs;
@@ -2099,6 +2100,14 @@ static int kvm_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
{
u32 vectoring_info = vmcs_read32(IDT_VECTORING_INFO_FIELD);
u32 exit_reason = vmcs_read32(VM_EXIT_REASON);
+ struct vcpu_vmx *vmx = to_vmx(vcpu);
+
+ if (unlikely(vmx->fail)) {
+ kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY;
+ kvm_run->fail_entry.hardware_entry_failure_reason
+ = vmcs_read32(VM_INSTRUCTION_ERROR);
+ return 0;
+ }

if ( (vectoring_info & VECTORING_INFO_VALID_MASK) &&
exit_reason != EXIT_REASON_EXCEPTION_NMI )
@@ -2208,7 +2217,6 @@ static void vmx_intr_assist(struct kvm_vcpu *vcpu)
static int vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
- u8 fail;
int r;

if (unlikely(vcpu->mp_state == VCPU_MP_STATE_SIPI_RECEIVED)) {
@@ -2352,7 +2360,7 @@ again:
"pop %%ecx; popa \n\t"
#endif
"setbe %0 \n\t"
- : "=q" (fail)
+ : "=q" (vmx->fail)
: "r"(vmx->launched), "d"((unsigned long)HOST_RSP),
"c"(vcpu),
[rax]"i"(offsetof(struct kvm_vcpu, regs[VCPU_REGS_RAX])),
@@ -2387,13 +2395,6 @@ again:

preempt_enable();

- if (unlikely(fail)) {
- kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY;
- kvm_run->fail_entry.hardware_entry_failure_reason
- = vmcs_read32(VM_INSTRUCTION_ERROR);
- r = 0;
- goto out;
- }
/*
* Profile KVM ...

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

From: Laurent Vivier <Laurent.Vivier@bull.net>

The mutex->splinlock convertion alllows us to make some code simplifications.
As we can keep the lock longer, we don't have to release it and then
have to check if the environment has not been modified before re-taking it. We
can remove kvm->busy and kvm->memory_config_version.

Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/kvm.h | 2 --
drivers/kvm/kvm_main.c | 38 +++-----------------------------------
2 files changed, 3 insertions(+), 37 deletions(-)

diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index ee9f8bd..351da40 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -411,8 +411,6 @@ struct kvm {
int n_free_mmu_pages;
struct hlist_head mmu_page_hash[KVM_NUM_MMU_PAGES];
struct kvm_vcpu *vcpus[KVM_MAX_VCPUS];
- int memory_config_version;
- int busy;
unsigned long rmap_overflow;
struct list_head vm_list;
struct file *filp;
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 49a0ff4..c2c8c93 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -679,7 +679,6 @@ static int kvm_vm_ioctl_set_memory_region(struct kvm *kvm,
unsigned long i;
struct kvm_memory_slot *memslot;
struct kvm_memory_slot old, new;
- int memory_config_version;

r = -EINVAL;
/* General sanity checks */
@@ -699,10 +698,8 @@ static int kvm_vm_ioctl_set_memory_region(struct kvm *kvm,
if (!npages)
mem->flags &= ~KVM_MEM_LOG_DIRTY_PAGES;

-raced:
mutex_lock(&kvm->lock);

- memory_config_version = kvm->memory_config_version;
new = old = *memslot;

new.base_gfn = base_gfn;
@@ -725,11 +722,6 @@ raced:
(base_gfn >= s->base_gfn + s->npages)))
goto out_unlock;
}
- /*
- * Do memory allocations outside lock. memory_config_version will
- * detect any races.
- */
- mutex_unlock(&kvm->lock);

/* Deallocate if slot is...

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

Before preempt notifiers, kvm needed to allocate memory with GFP_NOWAIT so
as not to have to enable preemption and take a heavyweight exit. On oom, we'd
fall back to a GFP_KERNEL allocation.

With preemption notifiers, we can do a GFP_KERNEL allocation, and perform
the heavyweight exit only if the kernel decides to put us to sleep.

Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/mmu.c | 34 ++++++++++------------------------
1 files changed, 10 insertions(+), 24 deletions(-)

diff --git a/drivers/kvm/mmu.c b/drivers/kvm/mmu.c
index 7b42c88..6d84d30 100644
--- a/drivers/kvm/mmu.c
+++ b/drivers/kvm/mmu.c
@@ -202,15 +202,14 @@ static void set_shadow_pte(u64 *sptep, u64 spte)
}

static int mmu_topup_memory_cache(struct kvm_mmu_memory_cache *cache,
- struct kmem_cache *base_cache, int min,
- gfp_t gfp_flags)
+ struct kmem_cache *base_cache, int min)
{
void *obj;

if (cache->nobjs >= min)
return 0;
while (cache->nobjs < ARRAY_SIZE(cache->objects)) {
- obj = kmem_cache_zalloc(base_cache, gfp_flags);
+ obj = kmem_cache_zalloc(base_cache, GFP_KERNEL);
if (!obj)
return -ENOMEM;
cache->objects[cache->nobjs++] = obj;
@@ -225,14 +224,14 @@ static void mmu_free_memory_cache(struct kvm_mmu_memory_cache *mc)
}

static int mmu_topup_memory_cache_page(struct kvm_mmu_memory_cache *cache,
- int min, gfp_t gfp_flags)
+ int min)
{
struct page *page;

if (cache->nobjs >= min)
return 0;
while (cache->nobjs < ARRAY_SIZE(cache->objects)) {
- page = alloc_page(gfp_flags);
+ page = alloc_page(GFP_KERNEL);
if (!page)
return -ENOMEM;
set_page_private(page, 0);
@@ -247,41 +246,28 @@ static void mmu_free_memory_cache_page(struct kvm_mmu_memory_cache *mc)
free_page((unsigned long)mc->objects[--mc->nobjs]);
}

-static int __mmu_topup_memory_caches(struct kvm_vcpu *vcpu, gfp_t gfp_flags)
+static int mmu_topup_memory_caches(struct kvm_vcp...

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

From: He, Qing <qing.he@intel.com>

Signed-off-by: Qing He <qing.he@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/kvm.h | 1 +
drivers/kvm/lapic.c | 33 ++++++++++++++++++++++++++++-----
2 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index f8fe87d..dbb929d 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -413,6 +413,7 @@ struct kvm {
struct kvm_io_bus pio_bus;
struct kvm_pic *vpic;
struct kvm_ioapic *vioapic;
+ int round_robin_prev_vcpu;
};

static inline struct kvm_pic *pic_irqchip(struct kvm *kvm)
diff --git a/drivers/kvm/lapic.c b/drivers/kvm/lapic.c
index 01e7696..ca1db38 100644
--- a/drivers/kvm/lapic.c
+++ b/drivers/kvm/lapic.c
@@ -371,12 +371,35 @@ struct kvm_lapic *kvm_apic_round_robin(struct kvm *kvm, u8 vector,
unsigned long bitmap)
{
int vcpu_id;
+ int last;
+ int next;
+ struct kvm_lapic *apic;
+
+ last = kvm->round_robin_prev_vcpu;
+ next = last;
+
+ do {
+ if (++next == KVM_MAX_VCPUS)
+ next = 0;
+ if (kvm->vcpus[next] == NULL || !test_bit(next, &bitmap))
+ continue;
+ apic = kvm->vcpus[next]->apic;
+ if (apic && apic_enabled(apic))
+ break;
+ apic = NULL;
+ } while (next != last);
+ kvm->round_robin_prev_vcpu = next;
+
+ if (!apic) {
+ vcpu_id = ffs(bitmap) - 1;
+ if (vcpu_id < 0) {
+ vcpu_id = 0;
+ printk(KERN_DEBUG "vcpu not ready for apic_round_robin\n");
+ }
+ apic = kvm->vcpus[vcpu_id]->apic;
+ }

- /* TODO for real round robin */
- vcpu_id = fls(bitmap) - 1;
- if (vcpu_id < 0)
- printk(KERN_DEBUG "vcpu not ready for apic_round_robin\n");
- return kvm->vcpus[vcpu_id]->apic;
+ return apic;
}

static void apic_set_eoi(struct kvm_lapic *apic)
--
1.5.3

-

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

From: Eddie Dong <eddie.dong@intel.com>

APIC timer IRQ is set every time when a certain period
expires at host time, but the guest may be descheduled
at that time and thus the irq be overwritten by later fire.
This patch keep track of firing irq numbers and decrease
only when the IRQ is injected to guest or buffered in
APIC.

Signed-off-by: Yaozu (Eddie) Dong <Eddie.Dong@intel.com>
Signed-off-by: Qing He <qing.he@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/irq.c | 13 ++++++++++
drivers/kvm/irq.h | 4 +++
drivers/kvm/kvm_main.c | 2 +
drivers/kvm/lapic.c | 58 +++++++++++++++++++++++++++++++----------------
drivers/kvm/svm.c | 7 ++++-
drivers/kvm/vmx.c | 10 +++++--
6 files changed, 69 insertions(+), 25 deletions(-)

diff --git a/drivers/kvm/irq.c b/drivers/kvm/irq.c
index e09cd65..b88e501 100644
--- a/drivers/kvm/irq.c
+++ b/drivers/kvm/irq.c
@@ -78,3 +78,16 @@ void kvm_vcpu_kick(struct kvm_vcpu *vcpu)
smp_call_function_single(ipi_pcpu, vcpu_kick_intr, vcpu, 0, 0);
}

+void kvm_inject_pending_timer_irqs(struct kvm_vcpu *vcpu)
+{
+ kvm_inject_apic_timer_irqs(vcpu);
+ /* TODO: PIT, RTC etc. */
+}
+EXPORT_SYMBOL_GPL(kvm_inject_pending_timer_irqs);
+
+void kvm_timer_intr_post(struct kvm_vcpu *vcpu, int vec)
+{
+ kvm_apic_timer_intr_post(vcpu, vec);
+ /* TODO: PIT, RTC etc. */
+}
+EXPORT_SYMBOL_GPL(kvm_timer_intr_post);
diff --git a/drivers/kvm/irq.h b/drivers/kvm/irq.h
index 07035e8..87baf7e 100644
--- a/drivers/kvm/irq.h
+++ b/drivers/kvm/irq.h
@@ -154,5 +154,9 @@ int kvm_ioapic_init(struct kvm *kvm);
void kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level);
int kvm_lapic_enabled(struct kvm_vcpu *vcpu);
int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu);
+void kvm_apic_timer_intr_post(struct kvm_vcpu *vcpu, int vec);
+void kvm_timer_intr_post(struct kvm_vcpu *vcpu, int vec);
+void kvm_inject_pending_timer_irqs(struct kvm_vcpu *vcpu);
+void kvm_inj...

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

From: Qing He <qing.he@intel.com>

This patch changes the PIC interrupts delivery. Now it is only delivered
to vcpu0 when either condition is met (on vcpu0):
1. local APIC is hardware disabled
2. LVT0 is unmasked and configured to delivery mode ExtInt

It fixes the 2x faster wall clock on x86_64 and SMP i386 Linux guests

Signed-off-by: Eddie (Yaozu) Dong <eddie.dong@intel.com>
Signed-off-by: Qing He <qing.he@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/irq.c | 15 ++++++++++-----
drivers/kvm/irq.h | 1 +
drivers/kvm/lapic.c | 17 +++++++++++++++++
3 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/drivers/kvm/irq.c b/drivers/kvm/irq.c
index b88e501..7628c7f 100644
--- a/drivers/kvm/irq.c
+++ b/drivers/kvm/irq.c
@@ -33,8 +33,11 @@ int kvm_cpu_has_interrupt(struct kvm_vcpu *v)
struct kvm_pic *s;

if (kvm_apic_has_interrupt(v) == -1) { /* LAPIC */
- s = pic_irqchip(v->kvm); /* PIC */
- return s->output;
+ if (kvm_apic_accept_pic_intr(v)) {
+ s = pic_irqchip(v->kvm); /* PIC */
+ return s->output;
+ } else
+ return 0;
}
return 1;
}
@@ -50,9 +53,11 @@ int kvm_cpu_get_interrupt(struct kvm_vcpu *v)

vector = kvm_get_apic_interrupt(v); /* APIC */
if (vector == -1) {
- s = pic_irqchip(v->kvm);
- s->output = 0; /* PIC */
- vector = kvm_pic_read_irq(s);
+ if (kvm_apic_accept_pic_intr(v)) {
+ s = pic_irqchip(v->kvm);
+ s->output = 0; /* PIC */
+ vector = kvm_pic_read_irq(s);
+ }
}
return vector;
}
diff --git a/drivers/kvm/irq.h b/drivers/kvm/irq.h
index f324cfb..ec46a09 100644
--- a/drivers/kvm/irq.h
+++ b/drivers/kvm/irq.h
@@ -135,6 +135,7 @@ do { \

void kvm_vcpu_kick(struct kvm_vcpu *vcpu);
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_free_a...

To: <kvm-devel@...>
Cc: <linux-kernel@...>, Yang, Sheng <sheng.yang@...>
Date: Monday, September 17, 2007 - 4:31 am

From: Yang, Sheng <sheng.yang@intel.com>

This patch enables TPR shadow of VMX on CR8 access. 64bit Windows using
CR8 access TPR frequently. The TPR shadow can improve the performance of
access TPR by not causing vmexit.

Signed-off-by: Sheng Yang <sheng.yang@intel.com>
Signed-off-by: Yaozu (Eddie) Dong <eddie.dong@intel.com>
Signed-off-by: Qing He <qing.he@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/irq.h | 2 +
drivers/kvm/lapic.c | 17 +++++++++++++
drivers/kvm/vmx.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++---
drivers/kvm/vmx.h | 1 +
4 files changed, 81 insertions(+), 4 deletions(-)

diff --git a/drivers/kvm/irq.h b/drivers/kvm/irq.h
index 24b871f..07035e8 100644
--- a/drivers/kvm/irq.h
+++ b/drivers/kvm/irq.h
@@ -152,5 +152,7 @@ int kvm_apic_set_irq(struct kvm_lapic *apic, u8 vec, u8 trig);
void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu);
int kvm_ioapic_init(struct kvm *kvm);
void kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level);
+int kvm_lapic_enabled(struct kvm_vcpu *vcpu);
+int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu);

#endif
diff --git a/drivers/kvm/lapic.c b/drivers/kvm/lapic.c
index df636bf..68bbbb3 100644
--- a/drivers/kvm/lapic.c
+++ b/drivers/kvm/lapic.c
@@ -170,6 +170,19 @@ static inline int apic_find_highest_irr(struct kvm_lapic *apic)
return result;
}

+int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu)
+{
+ struct kvm_lapic *apic = (struct kvm_lapic *)vcpu->apic;
+ int highest_irr;
+
+ if (!apic)
+ return 0;
+ highest_irr = apic_find_highest_irr(apic);
+
+ return highest_irr;
+}
+EXPORT_SYMBOL_GPL(kvm_lapic_find_highest_irr);
+
int kvm_apic_set_irq(struct kvm_lapic *apic, u8 vec, u8 trig)
{
if (!apic_test_and_set_irr(vec, apic)) {
@@ -483,6 +496,7 @@ static u32 __apic_read(struct kvm_lapic *apic, unsigned int offset)
break;

default:
+ apic_update_ppr(apic);
val = apic_get_reg(apic, offse...

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

From: Eddie Dong <eddie.dong@intel.com>

Because lightweight exits (exits which don't involve userspace) are many
times faster than heavyweight exits, it makes sense to emulate high usage
devices in the kernel. The local APIC is one such device, especially for
Windows and for SMP, so we add an APIC model to kvm.

It also allows in-kernel host-side drivers to inject interrupts without
going through userspace.

[compile fix on i386 from Jindrich Makovicka]

Signed-off-by: Yaozu (Eddie) Dong <Eddie.Dong@intel.com>
Signed-off-by: Qing He <qing.he@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/Makefile | 2 +-
drivers/kvm/irq.c | 53 ++-
drivers/kvm/irq.h | 41 ++-
drivers/kvm/kvm.h | 3 +-
drivers/kvm/kvm_main.c | 52 +++-
drivers/kvm/lapic.c | 933 ++++++++++++++++++++++++++++++++++++++++++++++++
drivers/kvm/svm.c | 6 +
drivers/kvm/vmx.c | 6 +
include/linux/kvm.h | 4 +-
9 files changed, 1067 insertions(+), 33 deletions(-)
create mode 100644 drivers/kvm/lapic.c

diff --git a/drivers/kvm/Makefile b/drivers/kvm/Makefile
index 952dff3..3bf7276 100644
--- a/drivers/kvm/Makefile
+++ b/drivers/kvm/Makefile
@@ -2,7 +2,7 @@
# Makefile for Kernel-based Virtual Machine module
#

-kvm-objs := kvm_main.o mmu.o x86_emulate.o i8259.o irq.o
+kvm-objs := kvm_main.o mmu.o x86_emulate.o i8259.o irq.o lapic.o
obj-$(CONFIG_KVM) += kvm.o
kvm-intel-objs = vmx.o
obj-$(CONFIG_KVM_INTEL) += kvm-intel.o
diff --git a/drivers/kvm/irq.c b/drivers/kvm/irq.c
index b08005c..0b4430a 100644
--- a/drivers/kvm/irq.c
+++ b/drivers/kvm/irq.c
@@ -30,14 +30,13 @@
*/
int kvm_cpu_has_interrupt(struct kvm_vcpu *v)
{
- struct kvm_pic *s = pic_irqchip(v->kvm);
-
- if (s->output) /* PIC */
- return 1;
- /*
- * TODO: APIC
- */
- return 0;
+ struct kvm_pic *s;
+
+ if (kvm_apic_has_interrupt(v) == -1) { /* LAPIC */
+ s = pic_irqchip(v->kvm); /* PIC */
+ return s->output;...

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

From: He, Qing <qing.he@intel.com>

Signed-off-by: Qing He <qing.he@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/kvm_main.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index f4cbd4f..a25dfc9 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -2005,7 +2005,8 @@ static int kvm_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);

/* re-sync apic's tpr */
- set_cr8(vcpu, kvm_run->cr8);
+ if (!irqchip_in_kernel(vcpu->kvm))
+ set_cr8(vcpu, kvm_run->cr8);

if (vcpu->pio.cur_count) {
r = complete_pio(vcpu);
--
1.5.3

-

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

From: Eddie Dong <eddie.dong@intel.com>

This reduces overhead by accessing cachelines from the wrong node, as well
as simplifying locking.

[Qing: fix for inactive or expired one-shot timer]

Signed-off-by: Yaozu (Eddie) Dong <Eddie.Dong@intel.com>
Signed-off-by: Qing He <qing.he@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/irq.h | 1 +
drivers/kvm/lapic.c | 14 ++++++++++++++
drivers/kvm/svm.c | 1 +
drivers/kvm/vmx.c | 4 +++-
4 files changed, 19 insertions(+), 1 deletions(-)

diff --git a/drivers/kvm/irq.h b/drivers/kvm/irq.h
index 87baf7e..f324cfb 100644
--- a/drivers/kvm/irq.h
+++ b/drivers/kvm/irq.h
@@ -158,5 +158,6 @@ void kvm_apic_timer_intr_post(struct kvm_vcpu *vcpu, int vec);
void kvm_timer_intr_post(struct kvm_vcpu *vcpu, int vec);
void kvm_inject_pending_timer_irqs(struct kvm_vcpu *vcpu);
void kvm_inject_apic_timer_irqs(struct kvm_vcpu *vcpu);
+void kvm_migrate_apic_timer(struct kvm_vcpu *vcpu);

#endif
diff --git a/drivers/kvm/lapic.c b/drivers/kvm/lapic.c
index 490d493..2706ec3 100644
--- a/drivers/kvm/lapic.c
+++ b/drivers/kvm/lapic.c
@@ -979,3 +979,17 @@ void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu)
update_divide_count(apic);
start_apic_timer(apic);
}
+
+void kvm_migrate_apic_timer(struct kvm_vcpu *vcpu)
+{
+ struct kvm_lapic *apic = vcpu->apic;
+ struct hrtimer *timer;
+
+ if (!apic)
+ return;
+
+ timer = &apic->timer.dev;
+ if (hrtimer_cancel(timer))
+ hrtimer_start(timer, timer->expires, HRTIMER_MODE_ABS);
+}
+EXPORT_SYMBOL_GPL(kvm_migrate_apic_timer);
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
index 00119ec..3de9ec3 100644
--- a/drivers/kvm/svm.c
+++ b/drivers/kvm/svm.c
@@ -633,6 +633,7 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
delta = vcpu->host_tsc - tsc_this;
svm->vmcb->control.tsc_offset += delta;
vcpu->cpu = cpu;
+ kvm_migrate_apic_timer(vcpu);
}

for (i = 0; i < NR_HO...

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

From: Izik Eidus <izike@qumranet.com>

Needed for mapping memory at 4GB.

Signed-off-by: Izik Eidus <izike@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/kvm.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index 2245bae..a42a6f3 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -39,7 +39,7 @@

#define KVM_MAX_VCPUS 4
#define KVM_ALIAS_SLOTS 4
-#define KVM_MEMORY_SLOTS 4
+#define KVM_MEMORY_SLOTS 8
#define KVM_NUM_MMU_PAGES 1024
#define KVM_MIN_FREE_MMU_PAGES 5
#define KVM_REFILL_PAGES 25
--
1.5.3

-

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

From: Laurent Vivier <Laurent.Vivier@bull.net>

vmx_load_host_state() bundles fs, gs, ldt, and tss reloading into
one in the hope that it is infrequent. With smp guests, fs reloading is
frequent due to fs being used by threads.

Unbundle the reloads so reduce expensive gs reloads.

Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/vmx.c | 22 ++++++++++++----------
1 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index b400668..d63e82e 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -54,7 +54,8 @@ struct vcpu_vmx {
struct {
int loaded;
u16 fs_sel, gs_sel, ldt_sel;
- int fs_gs_ldt_reload_needed;
+ int gs_ldt_reload_needed;
+ int fs_reload_needed;
}host_state;

};
@@ -353,20 +354,21 @@ static void vmx_save_host_state(struct vcpu_vmx *vmx)
* allow segment selectors with cpl > 0 or ti == 1.
*/
vmx->host_state.ldt_sel = read_ldt();
- vmx->host_state.fs_gs_ldt_reload_needed = vmx->host_state.ldt_sel;
+ vmx->host_state.gs_ldt_reload_needed = vmx->host_state.ldt_sel;
vmx->host_state.fs_sel = read_fs();
- if (!(vmx->host_state.fs_sel & 7))
+ if (!(vmx->host_state.fs_sel & 7)) {
vmcs_write16(HOST_FS_SELECTOR, vmx->host_state.fs_sel);
- else {
+ vmx->host_state.fs_reload_needed = 0;
+ } else {
vmcs_write16(HOST_FS_SELECTOR, 0);
- vmx->host_state.fs_gs_ldt_reload_needed = 1;
+ vmx->host_state.fs_reload_needed = 1;
}
vmx->host_state.gs_sel = read_gs();
if (!(vmx->host_state.gs_sel & 7))
vmcs_write16(HOST_GS_SELECTOR, vmx->host_state.gs_sel);
else {
vmcs_write16(HOST_GS_SELECTOR, 0);
- vmx->host_state.fs_gs_ldt_reload_needed = 1;
+ vmx->host_state.gs_ldt_reload_needed = 1;
}

#ifdef CONFIG_X86_64
@@ -396,9 +398,10 @@ static void vmx_load_host_state(struct v...

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

From: Izik Eidus <izike@qumranet.com>

Signed-off-by: Izik Eidus <izike@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/vmx.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index cd999c0..b400668 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -1030,7 +1030,7 @@ static void enter_pmode(struct kvm_vcpu *vcpu)
vmcs_write32(GUEST_CS_AR_BYTES, 0x9b);
}

-static int rmode_tss_base(struct kvm* kvm)
+static gva_t rmode_tss_base(struct kvm* kvm)
{
gfn_t base_gfn = kvm->memslots[0].base_gfn + kvm->memslots[0].npages - 3;
return base_gfn << PAGE_SHIFT;
--
1.5.3

-

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

From: He, Qing <qing.he@intel.com>

This patch adds support for in-kernel ioapic save and restore (to
and from userspace). It uses the same get/set_irqchip ioctl as
in-kernel PIC.

Signed-off-by: Qing He <qing.he@intel.com>
Signed-off-by: Yaozu (Eddie) Dong <eddie.dong@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/irq.h | 9 +++++----
drivers/kvm/kvm.h | 5 +++++
drivers/kvm/kvm_main.c | 10 ++++++++++
include/linux/kvm.h | 29 ++++++++++++++++++++++++++++-
4 files changed, 48 insertions(+), 5 deletions(-)

diff --git a/drivers/kvm/irq.h b/drivers/kvm/irq.h
index e0133e6..30adddc 100644
--- a/drivers/kvm/irq.h
+++ b/drivers/kvm/irq.h
@@ -61,7 +61,7 @@ int kvm_cpu_get_interrupt(struct kvm_vcpu *v);
int kvm_cpu_has_interrupt(struct kvm_vcpu *v);
void kvm_pic_update_irq(struct kvm_pic *s);

-#define IOAPIC_NUM_PINS 24
+#define IOAPIC_NUM_PINS KVM_IOAPIC_NUM_PINS
#define IOAPIC_VERSION_ID 0x11 /* IOAPIC version */
#define IOAPIC_EDGE_TRIG 0
#define IOAPIC_LEVEL_TRIG 1
@@ -80,12 +80,11 @@ void kvm_pic_update_irq(struct kvm_pic *s);
#define IOAPIC_REG_ARB_ID 0x02 /* x86 IOAPIC only */

struct kvm_ioapic {
- struct kvm_io_device dev;
- unsigned long base_address;
- struct kvm *kvm;
+ u64 base_address;
u32 ioregsel;
u32 id;
u32 irr;
+ u32 pad;
union ioapic_redir_entry {
u64 bits;
struct {
@@ -102,6 +101,8 @@ struct kvm_ioapic {
u8 dest_id;
} fields;
} redirtbl[IOAPIC_NUM_PINS];
+ struct kvm_io_device dev;
+ struct kvm *kvm;
};

struct kvm_lapic {
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index f69b482..bb506b7 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -420,6 +420,11 @@ static inline struct kvm_pic *pic_irqchip(struct kvm *kvm)
return kvm->vpic;
}

+static inline struct kvm_ioapic *ioapic_irqchip(struct kvm *kvm)
+{
+ return kvm->vioapic;
+}
+
static inline int irqchip_in_kernel(struct kvm *kvm)
{
return p...

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

From: Eddie Dong <eddie.dong@intel.com>

This allows in-kernel host-side device drivers to raise guest interrupts
without going to userspace.

Signed-off-by: Yaozu (Eddie) Dong <eddie.dong@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/Makefile | 2 +-
drivers/kvm/ioapic.c | 397 ++++++++++++++++++++++++++++++++++++++++++++++++
drivers/kvm/irq.c | 4 -
drivers/kvm/irq.h | 50 ++++++
drivers/kvm/kvm.h | 1 +
drivers/kvm/kvm_main.c | 15 ++-
6 files changed, 461 insertions(+), 8 deletions(-)
create mode 100644 drivers/kvm/ioapic.c

diff --git a/drivers/kvm/Makefile b/drivers/kvm/Makefile
index 3bf7276..e5a8f4d 100644
--- a/drivers/kvm/Makefile
+++ b/drivers/kvm/Makefile
@@ -2,7 +2,7 @@
# Makefile for Kernel-based Virtual Machine module
#

-kvm-objs := kvm_main.o mmu.o x86_emulate.o i8259.o irq.o lapic.o
+kvm-objs := kvm_main.o mmu.o x86_emulate.o i8259.o irq.o lapic.o ioapic.o
obj-$(CONFIG_KVM) += kvm.o
kvm-intel-objs = vmx.o
obj-$(CONFIG_KVM_INTEL) += kvm-intel.o
diff --git a/drivers/kvm/ioapic.c b/drivers/kvm/ioapic.c
new file mode 100644
index 0000000..3ee13c3
--- /dev/null
+++ b/drivers/kvm/ioapic.c
@@ -0,0 +1,397 @@
+/*
+ * Copyright (C) 2001 MandrakeSoft S.A.
+ *
+ * MandrakeSoft S.A.
+ * 43, rue d'Aboukir
+ * 75002 Paris - France
+ * http://www.linux-mandrake.com/
+ * http://www.mandrakesoft.com/
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received...

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

From: Eddie Dong <eddie.dong@intel.com>

This patch adds a new vcpu-based IOCTL to save and restore the local
apic registers for a single vcpu. The kernel only copies the apic page as
a whole, extraction of registers is left to userspace side. On restore, the
APIC timer is restarted from the initial count, this introduces a little
delay, but works fine.

Signed-off-by: Yaozu (Eddie) Dong <eddie.dong@intel.com>
Signed-off-by: Qing He <qing.he@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/irq.h | 1 +
drivers/kvm/kvm_main.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
drivers/kvm/lapic.c | 13 +++++++++++++
include/linux/kvm.h | 8 ++++++++
4 files changed, 68 insertions(+), 0 deletions(-)

diff --git a/drivers/kvm/irq.h b/drivers/kvm/irq.h
index 30adddc..24b871f 100644
--- a/drivers/kvm/irq.h
+++ b/drivers/kvm/irq.h
@@ -149,6 +149,7 @@ int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest);
void kvm_ioapic_update_eoi(struct kvm *kvm, int vector);
int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda);
int kvm_apic_set_irq(struct kvm_lapic *apic, u8 vec, u8 trig);
+void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu);
int kvm_ioapic_init(struct kvm *kvm);
void kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level);

diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 61dff55..a012d70 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -2642,6 +2642,27 @@ static int kvm_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
return 0;
}

+static int kvm_vcpu_ioctl_get_lapic(struct kvm_vcpu *vcpu,
+ struct kvm_lapic_state *s)
+{
+ vcpu_load(vcpu);
+ memcpy(s->regs, vcpu->apic->regs, sizeof *s);
+ vcpu_put(vcpu);
+
+ return 0;
+}
+
+static int kvm_vcpu_ioctl_set_lapic(struct kvm_vcpu *vcpu,
+ struct kvm_lapic_state *s)
+{
+ vcpu_load(vcpu);
+ memcpy(vcpu->apic->regs, s->regs,...

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

From: Eddie Dong <eddie.dong@intel.com>

Signed-off-by: Yaozu (Eddie) Dong <eddie.dong@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/Makefile | 2 +-
drivers/kvm/i8259.c | 442 ++++++++++++++++++++++++++++++++++++++++++++++++
drivers/kvm/irq.c | 61 +++++++
drivers/kvm/irq.h | 64 +++++++
drivers/kvm/kvm.h | 11 ++
drivers/kvm/kvm_main.c | 46 +++++-
drivers/kvm/svm.c | 69 +++++++-
drivers/kvm/vmx.c | 80 ++++++++-
include/linux/kvm.h | 19 ++
9 files changed, 770 insertions(+), 24 deletions(-)
create mode 100644 drivers/kvm/i8259.c
create mode 100644 drivers/kvm/irq.c
create mode 100644 drivers/kvm/irq.h

diff --git a/drivers/kvm/Makefile b/drivers/kvm/Makefile
index c0a789f..952dff3 100644
--- a/drivers/kvm/Makefile
+++ b/drivers/kvm/Makefile
@@ -2,7 +2,7 @@
# Makefile for Kernel-based Virtual Machine module
#

-kvm-objs := kvm_main.o mmu.o x86_emulate.o
+kvm-objs := kvm_main.o mmu.o x86_emulate.o i8259.o irq.o
obj-$(CONFIG_KVM) += kvm.o
kvm-intel-objs = vmx.o
obj-$(CONFIG_KVM_INTEL) += kvm-intel.o
diff --git a/drivers/kvm/i8259.c b/drivers/kvm/i8259.c
new file mode 100644
index 0000000..40ad104
--- /dev/null
+++ b/drivers/kvm/i8259.c
@@ -0,0 +1,442 @@
+/*
+ * 8259 interrupt controller emulation
+ *
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ * Copyright (c) 2007 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions o...

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

From: He, Qing <qing.he@intel.com>

This patch adds two new ioctls to dump and write kernel irqchips for
save/restore and live migration. PIC s/r and l/m is implemented in this
patch.

Signed-off-by: Yaozu (Eddie) Dong <eddie.dong@intel.com>
Signed-off-by: Qing He <qing.he@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/i8259.c | 5 +++
drivers/kvm/irq.h | 1 +
drivers/kvm/kvm_main.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++
include/linux/kvm.h | 36 +++++++++++++++++++++
4 files changed, 124 insertions(+), 0 deletions(-)

diff --git a/drivers/kvm/i8259.c b/drivers/kvm/i8259.c
index ee6030d..a679157 100644
--- a/drivers/kvm/i8259.c
+++ b/drivers/kvm/i8259.c
@@ -119,6 +119,11 @@ static void pic_update_irq(struct kvm_pic *s)
s->irq_request(s->irq_request_opaque, 0);
}

+void kvm_pic_update_irq(struct kvm_pic *s)
+{
+ pic_update_irq(s);
+}
+
void kvm_pic_set_irq(void *opaque, int irq, int level)
{
struct kvm_pic *s = opaque;
diff --git a/drivers/kvm/irq.h b/drivers/kvm/irq.h
index fff5733..e0133e6 100644
--- a/drivers/kvm/irq.h
+++ b/drivers/kvm/irq.h
@@ -59,6 +59,7 @@ void kvm_pic_set_irq(void *opaque, int irq, int level);
int kvm_pic_read_irq(struct kvm_pic *s);
int kvm_cpu_get_interrupt(struct kvm_vcpu *v);
int kvm_cpu_has_interrupt(struct kvm_vcpu *v);
+void kvm_pic_update_irq(struct kvm_pic *s);

#define IOAPIC_NUM_PINS 24
#define IOAPIC_VERSION_ID 0x11 /* IOAPIC version */
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 5063b3a..6e2c5f3 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -897,6 +897,53 @@ out:
return r;
}

+static int kvm_vm_ioctl_get_irqchip(struct kvm *kvm, struct kvm_irqchip *chip)
+{
+ int r;
+
+ r = 0;
+ switch (chip->chip_id) {
+ case KVM_IRQCHIP_PIC_MASTER:
+ memcpy (&chip->chip.pic,
+ &pic_irqchip(kvm)->pics[0],
+ sizeof(struct kvm_pic_state));
+ break;
+ case...

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

From: He, Qing <qing.he@intel.com>

vcpu->irq_pending is saved in get/set_sreg IOCTL, but when in-kernel
local APIC is used, doing this may occasionally overwrite vcpu->apic to
an invalid value, as in the vm restore path.

Signed-off-by: Qing He <qing.he@intel.com>
---
drivers/kvm/kvm_main.c | 22 ++++++++++++++--------
1 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 6e2c5f3..c270e4a 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -2145,8 +2145,12 @@ static int kvm_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
sregs->efer = vcpu->shadow_efer;
sregs->apic_base = kvm_get_apic_base(vcpu);

- memcpy(sregs->interrupt_bitmap, vcpu->irq_pending,
- sizeof sregs->interrupt_bitmap);
+ if (irqchip_in_kernel(vcpu->kvm))
+ memset(sregs->interrupt_bitmap, 0,
+ sizeof sregs->interrupt_bitmap);
+ else
+ memcpy(sregs->interrupt_bitmap, vcpu->irq_pending,
+ sizeof sregs->interrupt_bitmap);

vcpu_put(vcpu);

@@ -2200,12 +2204,14 @@ static int kvm_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
if (mmu_reset_needed)
kvm_mmu_reset_context(vcpu);

- memcpy(vcpu->irq_pending, sregs->interrupt_bitmap,
- sizeof vcpu->irq_pending);
- vcpu->irq_summary = 0;
- for (i = 0; i < ARRAY_SIZE(vcpu->irq_pending); ++i)
- if (vcpu->irq_pending[i])
- __set_bit(i, &vcpu->irq_summary);
+ if (!irqchip_in_kernel(vcpu->kvm)) {
+ memcpy(vcpu->irq_pending, sregs->interrupt_bitmap,
+ sizeof vcpu->irq_pending);
+ vcpu->irq_summary = 0;
+ for (i = 0; i < ARRAY_SIZE(vcpu->irq_pending); ++i)
+ if (vcpu->irq_pending[i])
+ __set_bit(i, &vcpu->irq_summary);
+ }

set_segment(vcpu, &sregs->cs, VCPU_SREG_CS);
set_segment(vcpu, &sregs->ds, VCPU_SREG_DS);
--
1.5.3

-

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

From: Eddie Dong <eddie.dong@intel.com>

By sleeping in the kernel when hlt is executed, we simplify the in-kernel
guest interrupt path considerably.

Signed-off-by: Gregory Haskins <ghaskins@novell.com>
Signed-off-by: Yaozu (Eddie) Dong <eddie.dong@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/i8259.c | 3 +++
drivers/kvm/irq.c | 4 ++++
drivers/kvm/kvm.h | 2 ++
drivers/kvm/kvm_main.c | 41 +++++++++++++++++++++++++++++++++++------
drivers/kvm/svm.c | 9 ++++++---
drivers/kvm/vmx.c | 8 ++++++--
include/linux/kvm.h | 1 +
7 files changed, 57 insertions(+), 11 deletions(-)

diff --git a/drivers/kvm/i8259.c b/drivers/kvm/i8259.c
index 40ad104..ee6030d 100644
--- a/drivers/kvm/i8259.c
+++ b/drivers/kvm/i8259.c
@@ -413,8 +413,11 @@ static void picdev_read(struct kvm_io_device *this,
static void pic_irq_request(void *opaque, int level)
{
struct kvm *kvm = opaque;
+ struct kvm_vcpu *vcpu = kvm->vcpus[0];

pic_irqchip(kvm)->output = level;
+ if (vcpu)
+ kvm_vcpu_kick(vcpu);
}

struct kvm_pic *kvm_create_pic(struct kvm *kvm)
diff --git a/drivers/kvm/irq.c b/drivers/kvm/irq.c
index 5265f82..e09cd65 100644
--- a/drivers/kvm/irq.c
+++ b/drivers/kvm/irq.c
@@ -70,6 +70,10 @@ void kvm_vcpu_kick(struct kvm_vcpu *vcpu)
{
int ipi_pcpu = vcpu->cpu;

+ if (waitqueue_active(&vcpu->wq)) {
+ wake_up_interruptible(&vcpu->wq);
+ ++vcpu->stat.halt_wakeup;
+ }
if (vcpu->guest_mode)
smp_call_function_single(ipi_pcpu, vcpu_kick_intr, vcpu, 0, 0);
}
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index 0a11b0f..f69b482 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -231,6 +231,7 @@ struct kvm_stat {
u32 signal_exits;
u32 irq_window_exits;
u32 halt_exits;
+ u32 halt_wakeup;
u32 request_irq_exits;
u32 irq_exits;
u32 light_exits;
@@ -353,6 +354,7 @@ struct kvm_vcpu {
gva_t mmio_fault_cr2;
struct kvm_pio_r...

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

From: Eddie Dong <eddie.dong@intel.com>

This patch is to wrap APIC base register and CR8 operation which can
provide a unique API for user level irqchip and kernel irqchip.
This is a preparation of merging lapic/ioapic patch.

Signed-off-by: Yaozu (Eddie) Dong <eddie.dong@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/kvm.h | 3 +++
drivers/kvm/kvm_main.c | 32 +++++++++++++++++++++++++-------
drivers/kvm/svm.c | 8 ++++----
drivers/kvm/vmx.c | 14 ++++++++------
4 files changed, 40 insertions(+), 17 deletions(-)

diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index d71712d..e0a2f13 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -568,6 +568,9 @@ void set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0);
void set_cr3(struct kvm_vcpu *vcpu, unsigned long cr0);
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);
+u64 kvm_get_apic_base(struct kvm_vcpu *vcpu);
+void kvm_set_apic_base(struct kvm_vcpu *vcpu, u64 data);
void lmsw(struct kvm_vcpu *vcpu, unsigned long msw);

int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata);
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 09a04bc..f879efb 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -602,6 +602,24 @@ void set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8)
}
EXPORT_SYMBOL_GPL(set_cr8);

+unsigned long get_cr8(struct kvm_vcpu *vcpu)
+{
+ return vcpu->cr8;
+}
+EXPORT_SYMBOL_GPL(get_cr8);
+
+u64 kvm_get_apic_base(struct kvm_vcpu *vcpu)
+{
+ return vcpu->apic_base;
+}
+EXPORT_SYMBOL_GPL(kvm_get_apic_base);
+
+void kvm_set_apic_base(struct kvm_vcpu *vcpu, u64 data)
+{
+ vcpu->apic_base = data;
+}
+EXPORT_SYMBOL_GPL(kvm_set_apic_base);
+
void fx_init(struct kvm_vcpu *vcpu)
{
unsigned after_mxcsr_mask;
@@ -1481,7 +1499,7 @@ int kvm_get_msr_common(struct kvm_vc...

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

From: Eddie Dong <eddie.dong@intel.com>

pio operation and IRQ_LINE kvm_vm_ioctl is not kvm->lock
protected. Add lock to same with IOAPIC MMIO operations.

Signed-off-by: Yaozu (Eddie) Dong <eddie.dong@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/kvm_main.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 4384364..5063b3a 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -1790,6 +1790,7 @@ static void kernel_pio(struct kvm_io_device *pio_dev,
{
/* TODO: String I/O for in kernel device */

+ mutex_lock(&vcpu->kvm->lock);
if (vcpu->pio.in)
kvm_iodevice_read(pio_dev, vcpu->pio.port,
vcpu->pio.size,
@@ -1798,6 +1799,7 @@ static void kernel_pio(struct kvm_io_device *pio_dev,
kvm_iodevice_write(pio_dev, vcpu->pio.port,
vcpu->pio.size,
pd);
+ mutex_unlock(&vcpu->kvm->lock);
}

static void pio_string_write(struct kvm_io_device *pio_dev,
@@ -1807,12 +1809,14 @@ static void pio_string_write(struct kvm_io_device *pio_dev,
void *pd = vcpu->pio_data;
int i;

+ mutex_lock(&vcpu->kvm->lock);
for (i = 0; i < io->cur_count; i++) {
kvm_iodevice_write(pio_dev, io->port,
io->size,
pd);
pd += io->size;
}
+ mutex_unlock(&vcpu->kvm->lock);
}

int kvm_emulate_pio (struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
@@ -2818,6 +2822,7 @@ static long kvm_vm_ioctl(struct file *filp,
if (copy_from_user(&irq_event, argp, sizeof irq_event))
goto out;
if (irqchip_in_kernel(kvm)) {
+ mutex_lock(&kvm->lock);
if (irq_event.irq < 16)
kvm_pic_set_irq(pic_irqchip(kvm),
irq_event.irq,
@@ -2825,6 +2830,7 @@ static long kvm_vm_ioctl(struct file *filp,
kvm_ioapic_set_irq(kvm->vioapic,
irq_event.irq,
irq_event.level);
+ mutex_unlock(&kvm->...

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

From: Nitin A Kamble <nitin.a.kamble@intel.com>

Signed-off-by: Nitin A Kamble <nitin.a.kamble@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/x86_emulate.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index fa7aa27..1036e02 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -148,7 +148,7 @@ static u8 opcode_table[256] = {
/* 0xE0 - 0xE7 */
0, 0, 0, 0, 0, 0, 0, 0,
/* 0xE8 - 0xEF */
- 0, SrcImm|ImplicitOps, 0, 0, 0, 0, 0, 0,
+ 0, SrcImm|ImplicitOps, 0, SrcImmByte|ImplicitOps, 0, 0, 0, 0,
/* 0xF0 - 0xF7 */
0, 0, 0, 0,
ImplicitOps, 0,
@@ -1032,6 +1032,7 @@ done_prefixes:
src.val = _regs[VCPU_REGS_RCX];
goto grp2;
case 0xe9: /* jmp rel */
+ case 0xeb: /* jmp rel short */
JMP_REL(src.val);
no_wb = 1; /* Disable writeback. */
break;
--
1.5.3

-

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

From: Rusty Russell <rusty@rustcorp.com.au>

Changes some svm.c internal function names:
1) io_adress -> io_address (de-germanify the spelling)
2) kvm_reput_irq -> reput_irq (it's not a generic kvm function)
3) kvm_do_inject_irq -> (it's not a generic kvm function)

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/svm.c | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
index 504fb50..cd96673 100644
--- a/drivers/kvm/svm.c
+++ b/drivers/kvm/svm.c
@@ -1060,7 +1060,7 @@ static int io_get_override(struct vcpu_svm *svm,
return 0;
}

-static unsigned long io_adress(struct vcpu_svm *svm, int ins, gva_t *address)
+static unsigned long io_address(struct vcpu_svm *svm, int ins, gva_t *address)
{
unsigned long addr_mask;
unsigned long *reg;
@@ -1124,7 +1124,7 @@ static int io_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
if (string) {
unsigned addr_mask;

- addr_mask = io_adress(svm, in, &address);
+ addr_mask = io_address(svm, in, &address);
if (!addr_mask) {
printk(KERN_DEBUG "%s: get io address failed\n",
__FUNCTION__);
@@ -1419,7 +1419,7 @@ static void pre_svm_run(struct vcpu_svm *svm)
}

-static inline void kvm_do_inject_irq(struct vcpu_svm *svm)
+static inline void inject_irq(struct vcpu_svm *svm)
{
struct vmcb_control_area *control;

@@ -1430,7 +1430,7 @@ static inline void kvm_do_inject_irq(struct vcpu_svm *svm)
((/*control->int_vector >> 4*/ 0xf) << V_INTR_PRIO_SHIFT);
}

-static void kvm_reput_irq(struct vcpu_svm *svm)
+static void reput_irq(struct vcpu_svm *svm)
{
struct vmcb_control_area *control = &svm->vmcb->control;

@@ -1456,7 +1456,7 @@ static void do_interrupt_requests(struct vcpu_svm *svm,
/*
* If interrupts enabled, and not blocked by sti or mov ss. Good.
*/
- kvm_do_inject_i...

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

From: Rusty Russell <rusty@rustcorp.com.au>

This patch converts the vcpus array in "struct kvm" to a pointer
array, and changes the "vcpu_create" and "vcpu_setup" hooks into one
"vcpu_create" call which does the allocation and initialization of the
vcpu (calling back into the kvm_vcpu_init core helper).

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/kvm.h | 12 ++--
drivers/kvm/kvm_main.c | 198 +++++++++++++++++++++++++-----------------------
drivers/kvm/kvm_svm.h | 2 +-
drivers/kvm/svm.c | 177 +++++++++++++++++++++----------------------
drivers/kvm/vmx.c | 65 ++++++++++------
5 files changed, 236 insertions(+), 218 deletions(-)

diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index 954a140..e92c84b 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -300,10 +300,8 @@ 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;
- void *_priv;
struct mutex mutex;
int cpu;
u64 host_tsc;
@@ -404,8 +402,7 @@ struct kvm {
struct list_head active_mmu_pages;
int n_free_mmu_pages;
struct hlist_head mmu_page_hash[KVM_NUM_MMU_PAGES];
- int nvcpus;
- struct kvm_vcpu vcpus[KVM_MAX_VCPUS];
+ struct kvm_vcpu *vcpus[KVM_MAX_VCPUS];
int memory_config_version;
int busy;
unsigned long rmap_overflow;
@@ -428,7 +425,8 @@ struct kvm_arch_ops {
int (*hardware_setup)(void); /* __init */
void (*hardware_unsetup)(void); /* __exit */

- int (*vcpu_create)(struct kvm_vcpu *vcpu);
+ /* 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_load)(struct kvm_vcpu *vcpu);
@@ -470,7 +468,6 @@ struct kvm_arch_ops {
void (*inject_gp)(struct kvm_vcpu *vcpu, unsigned err_code);

int (*run)(struct kvm_vcpu *vcpu, st...

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

From: Laurent Vivier <Laurent.Vivier@bull.net>

Split kvm_setup_pio() into two functions, one to setup in/out pio
(kvm_emulate_pio()) and one to setup ins/outs pio (kvm_emulate_pio_string()).

Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/kvm.h | 8 +++--
drivers/kvm/kvm_main.c | 63 +++++++++++++++++++++++++++-----------------
drivers/kvm/svm.c | 3 +-
drivers/kvm/vmx.c | 3 +-
drivers/kvm/x86_emulate.c | 6 +---
5 files changed, 48 insertions(+), 35 deletions(-)

diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index 6d25826..2245bae 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -539,9 +539,11 @@ int kvm_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data);

struct x86_emulate_ctxt;

-int kvm_setup_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
- int size, unsigned long count, int string, int down,
- gva_t address, int rep, unsigned port);
+int kvm_emulate_pio (struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
+ int size, unsigned port);
+int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
+ int size, unsigned long count, int down,
+ gva_t address, int rep, unsigned port);
void kvm_emulate_cpuid(struct kvm_vcpu *vcpu);
int kvm_emulate_halt(struct kvm_vcpu *vcpu);
int emulate_invlpg(struct kvm_vcpu *vcpu, gva_t address);
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 661d065..d154487 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -1735,8 +1735,39 @@ static void pio_string_write(struct kvm_io_device *pio_dev,
}
}

-int kvm_setup_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
- int size, unsigned long count, int string, int down,
+int kvm_emulate_pio (struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
+ int size, unsigned port)
+{
+ struct kvm_io_device *pio_dev;
+
+ vcpu->run->exit_reason...

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

From: Laurent Vivier <Laurent.Vivier@bull.net>

Line 1809 of kvm_main.c is useless, value is overwritten in line 1815:

1809 now = min(count, PAGE_SIZE / size);
1810
1811 if (!down)
1812 in_page = PAGE_SIZE - offset_in_page(address);
1813 else
1814 in_page = offset_in_page(address) + size;
1815 now = min(count, (unsigned long)in_page / size);
1816 if (!now) {

Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/kvm_main.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)

diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 1b86ab0..62adaee 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -1776,8 +1776,6 @@ int kvm_setup_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
return 1;
}

- now = min(count, PAGE_SIZE / size);
-
if (!down)
in_page = PAGE_SIZE - offset_in_page(address);
else
--
1.5.3

-

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

From: Rusty Russell <rusty@rustcorp.com.au>

All guest-invokable printks should be ratelimited to prevent malicious
guests from flooding logs. This is a start.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/kvm.h | 8 ++++++++
drivers/kvm/kvm_main.c | 18 ++++++++----------
drivers/kvm/svm.c | 4 ++--
drivers/kvm/vmx.c | 2 +-
4 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index cfda3ab..6d25826 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -474,6 +474,14 @@ struct kvm_arch_ops {

extern struct kvm_arch_ops *kvm_arch_ops;

+/* The guest did something we don't support. */
+#define pr_unimpl(vcpu, fmt, ...) \
+ do { \
+ if (printk_ratelimit()) \
+ printk(KERN_ERR "kvm: %i: cpu%i " fmt, \
+ current->tgid, (vcpu)->vcpu_id , ## __VA_ARGS__); \
+ } while(0)
+
#define kvm_printf(kvm, fmt ...) printk(KERN_DEBUG fmt)
#define vcpu_printf(vcpu, fmt...) kvm_printf(vcpu->kvm, fmt)

diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 9de3b1a..1b86ab0 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -962,8 +962,7 @@ static int emulator_write_std(unsigned long addr,
unsigned int bytes,
struct kvm_vcpu *vcpu)
{
- printk(KERN_ERR "emulator_write_std: addr %lx n %d\n",
- addr, bytes);
+ pr_unimpl(vcpu, "emulator_write_std: addr %lx n %d\n", addr, bytes);
return X86EMUL_UNHANDLEABLE;
}

@@ -1138,8 +1137,7 @@ int emulator_get_dr(struct x86_emulate_ctxt* ctxt, int dr, unsigned long *dest)
*dest = kvm_arch_ops->get_dr(vcpu, dr);
return X86EMUL_CONTINUE;
default:
- printk(KERN_DEBUG "%s: unexpected dr %u\n",
- __FUNCTION__, dr);
+ pr_unimpl(vcpu, "%s: unexpected dr %u\n", __FUNCTION__, dr);
return X86EMUL_UNHANDLEABLE;
}
}
@@ -1488,7 +1486,7 @@ int kvm_get_msr_common(s...

To: Avi Kivity <avi@...>
Cc: <kvm-devel@...>, <linux-kernel@...>, Rusty Russell <rusty@...>
Date: Monday, September 17, 2007 - 12:16 pm

This converts all KERN_<level> uses to KERN_ERR.
It seems better to add a <level> argument to kvm_printf.
pr_unimpl is perhaps a poor name choice.
perhaps vcpu_printk_ratelimit(vcpu, level, fmt, ...)

-

To: Joe Perches <joe@...>
Cc: Avi Kivity <avi@...>, <kvm-devel@...>, <linux-kernel@...>
Date: Monday, September 17, 2007 - 7:08 pm

Possibly, but remember that printk() is an admission of failure. It's
only useful to developers, and the only reason for printk over
pr_debug() is for users to report to developers when guests crash.

pr_unimpl() means exactly what it says: the guest asked for something we
don't support. If that turns out to be the last thing in the logs
before a crash, it's a clue. The rest of the printks should probably
move to pr_debug().

Hope that helps,
Rusty.

-

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

From: Rusty Russell <rusty@rustcorp.com.au>

We use kfree in svm.c and vmx.c, and this works, but it could break at
any time. kfree() is supposed to match up with kmalloc().

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/svm.c | 4 ++--
drivers/kvm/vmx.c | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
index 3ec30d7..436bdff 100644
--- a/drivers/kvm/svm.c
+++ b/drivers/kvm/svm.c
@@ -610,7 +610,7 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id)
uninit:
kvm_vcpu_uninit(&svm->vcpu);
free_svm:
- kfree(svm);
+ kmem_cache_free(kvm_vcpu_cache, svm);
out:
return ERR_PTR(err);
}
@@ -621,7 +621,7 @@ static void svm_free_vcpu(struct kvm_vcpu *vcpu)

__free_page(pfn_to_page(svm->vmcb_pa >> PAGE_SHIFT));
kvm_vcpu_uninit(vcpu);
- kfree(svm);
+ kmem_cache_free(kvm_vcpu_cache, svm);
}

static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index ae54d9a..708055a 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -2359,7 +2359,7 @@ static void vmx_free_vcpu(struct kvm_vcpu *vcpu)
kfree(vmx->host_msrs);
kfree(vmx->guest_msrs);
kvm_vcpu_uninit(vcpu);
- kfree(vmx);
+ kmem_cache_free(kvm_vcpu_cache, vmx);
}

static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
@@ -2410,7 +2410,7 @@ free_guest_msrs:
uninit_vcpu:
kvm_vcpu_uninit(&vmx->vcpu);
free_vcpu:
- kfree(vmx);
+ kmem_cache_free(kvm_vcpu_cache, vmx);
return ERR_PTR(err);
}

--
1.5.3

-

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

From: Rusty Russell <rusty@rustcorp.com.au>

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

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/svm.c | 232 +++++++++++++++++++++++++----------------------------
1 files changed, 108 insertions(+), 124 deletions(-)

diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
index c18f0b2..504fb50 100644
--- a/drivers/kvm/svm.c
+++ b/drivers/kvm/svm.c
@@ -98,9 +98,9 @@ static inline u32 svm_has(u32 feat)
return svm_features & feat;
}

-static unsigned get_addr_size(struct kvm_vcpu *vcpu)
+static unsigned get_addr_size(struct vcpu_svm *svm)
{
- struct vmcb_save_area *sa = &to_svm(vcpu)->vmcb->save;
+ struct vmcb_save_area *sa = &svm->vmcb->save;
u16 cs_attrib;

if (!(sa->cr0 & X86_CR0_PE) || (sa->rflags & X86_EFLAGS_VM))
@@ -865,17 +865,15 @@ static void save_host_msrs(struct kvm_vcpu *vcpu)
#endif
}

-static void new_asid(struct kvm_vcpu *vcpu, struct svm_cpu_data *svm_data)
+static void new_asid(struct vcpu_svm *svm, struct svm_cpu_data *svm_data)
{
- struct vcpu_svm *svm = to_svm(vcpu);
-
if (svm_data->next_asid > svm_data->max_asid) {
++svm_data->asid_generation;
svm_data->next_asid = 1;
svm->vmcb->control.tlb_ctl = TLB_CONTROL_FLUSH_ALL_ASID;
}

- vcpu->cpu = svm_data->cpu;
+ svm->vcpu.cpu = svm_data->cpu;
svm->asid_generation = svm_data->asid_generation;
svm->vmcb->control.asid = svm_data->next_asid++;
}
@@ -929,42 +927,43 @@ static void svm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long value,
}
}

-static int pf_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+static int pf_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
{
- struct vcpu_svm *s...

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

From: Rusty Russell <rusty@rustcorp.com.au>

Devices don't need open or release functions.

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

diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 25d76a5..9de3b1a 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -302,11 +302,6 @@ static struct kvm *kvm_create_vm(void)
return kvm;
}

-static int kvm_dev_open(struct inode *inode, struct file *filp)
-{
- return 0;
-}
-
/*
* Free any memory in @free but not in @dont.
*/
@@ -376,11 +371,6 @@ static void kvm_free_vcpus(struct kvm *kvm)

}

-static int kvm_dev_release(struct inode *inode, struct file *filp)
-{
- return 0;
-}
-
static void kvm_destroy_vm(struct kvm *kvm)
{
spin_lock(&kvm_lock);
@@ -2841,8 +2831,6 @@ out:
}

static struct file_operations kvm_chardev_ops = {
- .open = kvm_dev_open,
- .release = kvm_dev_release,
.unlocked_ioctl = kvm_dev_ioctl,
.compat_ioctl = kvm_dev_ioctl,
};
--
1.5.3

-

To: <kvm-devel@...>
Cc: <linux-kernel@...>, Gabriel C <nix.or.die@...>
Date: Monday, September 17, 2007 - 4:31 am

From: Gabriel C <nix.or.die@googlemail.com>

move_msr_up() is used only on X86_64 and generates a warning on !X86_64

Signed-off-by: Gabriel Craciunescu <nix.or.die@googlemail.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/vmx.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index a94eb20..3bf3650 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -544,6 +544,7 @@ static void vmx_inject_gp(struct kvm_vcpu *vcpu, unsigned error_code)
/*
* Swap MSR entry in host/guest MSR entry array.
*/
+#ifdef CONFIG_X86_64
static void move_msr_up(struct vcpu_vmx *vmx, int from, int to)
{
struct kvm_msr_entry tmp;
@@ -555,6 +556,7 @@ static void move_msr_up(struct vcpu_vmx *vmx, int from, int to)
vmx->host_msrs[to] = vmx->host_msrs[from];
vmx->host_msrs[from] = tmp;
}
+#endif

/*
* Set up the vmcs to automatically save and restore system
--
1.5.3

-

To: <avi@...>
Cc: <kvm-devel@...>, <linux-kernel@...>, <nix.or.die@...>
Date: Monday, September 17, 2007 - 12:27 pm

You've got to be kidding me.

104 patches is way over the top, post them in smaller chunks
please instead of killing vger.kernel.org as it has to crunch
out every single one of these 104 patches to several thousand
recipients.
-

To: David Miller <davem@...>
Cc: <kvm-devel@...>, <linux-kernel@...>
Date: Monday, September 17, 2007 - 1:35 pm

I can understand the load on the humans (and will split into several
rounds in the future), but why is vger.kernel.org so badly affected?
Shouldn't the mta throttle itself instead of dying?

Just curious.

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

-

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

From: Rusty Russell <rusty@rustcorp.com.au>

Avi wants the allocations of vcpus centralized again. The easiest way
is to add a "size" arg to kvm_init_arch, and expose the thus-prepared
cache to the modules.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/kvm.h | 4 +++-
drivers/kvm/kvm_main.c | 16 +++++++++++++++-
drivers/kvm/svm.c | 5 +++--
drivers/kvm/vmx.c | 4 ++--
4 files changed, 23 insertions(+), 6 deletions(-)

diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index 030b93b..b362e8f 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -141,6 +141,7 @@ struct kvm_mmu_page {
};

struct kvm_vcpu;
+extern struct kmem_cache *kvm_vcpu_cache;

/*
* x86 supports 3 paging modes (4-level 64-bit, 3-level 64-bit, and 2-level
@@ -483,7 +484,8 @@ extern struct kvm_arch_ops *kvm_arch_ops;
int kvm_vcpu_init(struct kvm_vcpu *vcpu, struct kvm *kvm, unsigned id);
void kvm_vcpu_uninit(struct kvm_vcpu *vcpu);

-int kvm_init_arch(struct kvm_arch_ops *ops, struct module *module);
+int kvm_init_arch(struct kvm_arch_ops *ops, unsigned int vcpu_size,
+ struct module *module);
void kvm_exit_arch(void);

int kvm_mmu_module_init(void);
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 4bbd89e..4166a08 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -53,6 +53,8 @@ static LIST_HEAD(vm_list);
static cpumask_t cpus_hardware_enabled;

struct kvm_arch_ops *kvm_arch_ops;
+struct kmem_cache *kvm_vcpu_cache;
+EXPORT_SYMBOL_GPL(kvm_vcpu_cache);

static __read_mostly struct preempt_ops kvm_preempt_ops;

@@ -3104,7 +3106,8 @@ static void kvm_sched_out(struct preempt_notifier *pn,
kvm_arch_ops->vcpu_put(vcpu);
}

-int kvm_init_arch(struct kvm_arch_ops *ops, struct module *module)
+int kvm_init_arch(struct kvm_arch_ops *ops, unsigned int vcpu_size,
+ struct module *module)
{
int r;

@@ -3142,6 +314...

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

From: Rusty Russell <rusty@rustcorp.com.au>

Now we use a kmem cache for allocating vcpus, we can get the 16-byte
alignment required by fxsave & fxrstor instructions, and avoid
manually aligning the buffer.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/kvm.h | 13 ++++---------
drivers/kvm/kvm_main.c | 45 +++++++++++++++++----------------------------
drivers/kvm/svm.c | 8 ++++----
3 files changed, 25 insertions(+), 41 deletions(-)

diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index b362e8f..7a34706 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -45,10 +45,6 @@
#define KVM_REFILL_PAGES 25
#define KVM_MAX_CPUID_ENTRIES 40

-#define FX_IMAGE_SIZE 512
-#define FX_IMAGE_ALIGN 16
-#define FX_BUF_SIZE (2 * FX_IMAGE_SIZE + FX_IMAGE_ALIGN)
-
#define DE_VECTOR 0
#define NM_VECTOR 7
#define DF_VECTOR 8
@@ -342,9 +338,8 @@ struct kvm_vcpu {

struct kvm_guest_debug guest_debug;

- char fx_buf[FX_BUF_SIZE];
- char *host_fx_image;
- char *guest_fx_image;
+ struct i387_fxsave_struct host_fx_image;
+ struct i387_fxsave_struct guest_fx_image;
int fpu_active;
int guest_fpu_loaded;

@@ -704,12 +699,12 @@ static inline unsigned long read_msr(unsigned long msr)
}
#endif

-static inline void fx_save(void *image)
+static inline void fx_save(struct i387_fxsave_struct *image)
{
asm ("fxsave (%0)":: "r" (image));
}

-static inline void fx_restore(void *image)
+static inline void fx_restore(struct i387_fxsave_struct *image)
{
asm ("fxrstor (%0)":: "r" (image));
}
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 4166a08..bfb1b6d 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -154,8 +154,8 @@ void kvm_load_guest_fpu(struct kvm_vcpu *vcpu)
return;

vcpu->guest_fpu_loaded = 1;
- fx_save(vcpu->host_fx_image);
- fx_restore(vcpu->guest_fx_image);
+ fx_save(&vcpu->host_fx...

To: <kvm-devel@...>
Cc: <linux-kernel@...>, Yang, Sheng <sheng.yang@...>
Date: Monday, September 17, 2007 - 4:31 am

From: Yang, Sheng <sheng.yang@intel.com>

All the physical CPUs on the board should support the same VMX feature
set. Add check_processor_compatibility to kvm_arch_ops for the consistency
check.

Signed-off-by: Sheng Yang <sheng.yang@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/kvm.h | 1 +
drivers/kvm/kvm_main.c | 10 +++++++++
drivers/kvm/svm.c | 6 +++++
drivers/kvm/vmx.c | 51 +++++++++++++++++++++++++++++++----------------
4 files changed, 50 insertions(+), 18 deletions(-)

diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index 7a34706..cfda3ab 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -420,6 +420,7 @@ struct kvm_arch_ops {
int (*disabled_by_bios)(void); /* __init */
void (*hardware_enable)(void *dummy); /* __init */
void (*hardware_disable)(void *dummy);
+ void (*check_processor_compatibility)(void *rtn);
int (*hardware_setup)(void); /* __init */
void (*hardware_unsetup)(void); /* __exit */

diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 5dee302..2be6b1c 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -3102,6 +3102,7 @@ int kvm_init_arch(struct kvm_arch_ops *ops, unsigned int vcpu_size,
struct module *module)
{
int r;
+ int cpu;

if (kvm_arch_ops) {
printk(KERN_ERR "kvm: already loaded the other module\n");
@@ -3123,6 +3124,14 @@ int kvm_init_arch(struct kvm_arch_ops *ops, unsigned int vcpu_size,
if (r < 0)
goto out;

+ for_each_online_cpu(cpu) {
+ smp_call_function_single(cpu,
+ kvm_arch_ops->check_processor_compatibility,
+ &r, 0, 1);
+ if (r < 0)
+ goto out_free_0;
+ }
+
on_each_cpu(hardware_enable, NULL, 0, 1);
r = register_cpu_notifier(&kvm_cpu_notifier);
if (r)
@@ -3169,6 +3178,7 @@ out_free_2:
unregister_cpu_notifier(&kvm_cpu_notifier);
out_free_1:
on_each_cpu(hardware_disable, NULL, 0, 1);
+out_free_0:...

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

From: Rusty Russell <rusty@rustcorp.com.au>

For some reason, mark_page_dirty open-codes __gfn_to_memslot().

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/kvm_main.c | 24 +++++++-----------------
1 files changed, 7 insertions(+), 17 deletions(-)

diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 5dc6017..55639ac 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -916,28 +916,18 @@ struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn)
}
EXPORT_SYMBOL_GPL(gfn_to_page);

+/* WARNING: Does not work on aliased pages. */
void mark_page_dirty(struct kvm *kvm, gfn_t gfn)
{
- int i;
struct kvm_memory_slot *memslot;
- unsigned long rel_gfn;

- for (i = 0; i < kvm->nmemslots; ++i) {
- memslot = &kvm->memslots[i];
+ memslot = __gfn_to_memslot(kvm, gfn);
+ if (memslot && memslot->dirty_bitmap) {
+ unsigned long rel_gfn = gfn - memslot->base_gfn;

- if (gfn >= memslot->base_gfn
- && gfn < memslot->base_gfn + memslot->npages) {
-
- if (!memslot->dirty_bitmap)
- return;
-
- rel_gfn = gfn - memslot->base_gfn;
-
- /* avoid RMW */
- if (!test_bit(rel_gfn, memslot->dirty_bitmap))
- set_bit(rel_gfn, memslot->dirty_bitmap);
- return;
- }
+ /* avoid RMW */
+ if (!test_bit(rel_gfn, memslot->dirty_bitmap))
+ set_bit(rel_gfn, memslot->dirty_bitmap);
}
}

--
1.5.3

-

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

From: Rusty Russell <rusty@rustcorp.com.au>

kvm_vm_ioctl_get_dirty_log scans bitmap to see it it's all zero, but
doesn't use that information.

Avi says:
Looks like it was used to guard kvm_mmu_slot_remove_write_access();
optimizing the case where the guest just leaves the screen alone (which
it usually does, especially in benchmarks).

I'd rather reinstate that optimization. See
90cb0529dd230548a7f0d6b315997be854caea1b where the damage was done.

It's pretty simple: if the bitmap is all zero, we don't need to do anything to
clean it.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/kvm_main.c | 13 ++++++++-----
1 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index bfb1b6d..5dee302 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -803,11 +803,14 @@ static int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
if (copy_to_user(log->dirty_bitmap, memslot->dirty_bitmap, n))
goto out;

- mutex_lock(&kvm->lock);
- kvm_mmu_slot_remove_write_access(kvm, log->slot);
- kvm_flush_remote_tlbs(kvm);
- memset(memslot->dirty_bitmap, 0, n);
- mutex_unlock(&kvm->lock);
+ /* If nothing is dirty, don't bother messing with page tables. */
+ if (any) {
+ mutex_lock(&kvm->lock);
+ kvm_mmu_slot_remove_write_access(kvm, log->slot);
+ kvm_flush_remote_tlbs(kvm);
+ memset(memslot->dirty_bitmap, 0, n);
+ mutex_unlock(&kvm->lock);
+ }

r = 0;

--
1.5.3

-

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

From: Rusty Russell <rusty@rustcorp.com.au>

Now that kvm generally runs with preemption enabled, we need to protect
the fpu intialization sequence.

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

diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 7aeaaba..5b42731 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -693,10 +693,13 @@ void fx_init(struct kvm_vcpu *vcpu)

} *fx_image;

+ /* Initialize guest FPU by resetting ours and saving into guest's */
+ preempt_disable();
fx_save(vcpu->host_fx_image);
fpu_init();
fx_save(vcpu->guest_fx_image);
fx_restore(vcpu->host_fx_image);
+ preempt_enable();

fx_image = (struct fx_image_s *)vcpu->guest_fx_image;
fx_image->mxcsr = 0x1f80;
--
1.5.3

-

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

From: Rusty Russell <rusty@rustcorp.com.au>

sSigned-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/kvm_main.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 2be6b1c..5dc6017 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -579,7 +579,6 @@ void set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
}
}

- vcpu->cr3 = cr3;
mutex_lock(&vcpu->kvm->lock);
/*
* Does the new cr3 value map to physical memory? (Note, we
@@ -592,8 +591,10 @@ void set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
*/
if (unlikely(!gfn_to_memslot(vcpu->kvm, cr3 >> PAGE_SHIFT)))
inject_gp(vcpu);
- else
+ else {
+ vcpu->cr3 = cr3;
vcpu->mmu.new_cr3(vcpu);
+ }
mutex_unlock(&vcpu->kvm->lock);
}
EXPORT_SYMBOL_GPL(set_cr3);
--
1.5.3

-

To: <kvm-devel@...>
Cc: <linux-kernel@...>, Shaohua Li <shaohua.li@...>
Date: Monday, September 17, 2007 - 4:31 am

From: Shaohua Li <shaohua.li@intel.com>

gfn_to_page might sleep with swap support. Move it out of the kmap calls.

Signed-off-by: Shaohua Li <shaohua.li@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/kvm.h | 2 +-
drivers/kvm/kvm_main.c | 7 ++--
drivers/kvm/mmu.c | 2 +-
drivers/kvm/paging_tmpl.h | 80 ++++++++++++++++++++++++++------------------
4 files changed, 52 insertions(+), 39 deletions(-)

diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index cec5f05..57504ae 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -599,7 +599,7 @@ int kvm_write_guest(struct kvm_vcpu *vcpu,
unsigned long segment_base(u16 selector);

void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
- const u8 *old, const u8 *new, int bytes);
+ const u8 *new, int bytes);
int kvm_mmu_unprotect_page_virt(struct kvm_vcpu *vcpu, gva_t gva);
void __kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu);
int kvm_mmu_load(struct kvm_vcpu *vcpu);
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 093cea3..80ee427 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -1076,7 +1076,6 @@ static int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa,
{
struct page *page;
void *virt;
- unsigned offset = offset_in_page(gpa);

if (((gpa + bytes - 1) >> PAGE_SHIFT) != (gpa >> PAGE_SHIFT))
return 0;
@@ -1085,7 +1084,7 @@ static int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa,
return 0;
mark_page_dirty(vcpu->kvm, gpa >> PAGE_SHIFT);
virt = kmap_atomic(page, KM_USER0);
- kvm_mmu_pte_write(vcpu, gpa, virt + offset, val, bytes);
+ kvm_mmu_pte_write(vcpu, gpa, val, bytes);
memcpy(virt + offset_in_page(gpa), val, bytes);
kunmap_atomic(virt, KM_USER0);
return 1;
@@ -1455,7 +1454,7 @@ static int vcpu_register_para(struct kvm_vcpu *vcpu, gpa_t para_state_gpa)

mark_page_dirty(vcpu->kvm, para_state_gpa >> PAGE_SHIFT);
p...

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

From: Rusty Russell <rusty@rustcorp.com.au>

There are several places where hardcoded numbers are used in place of
the easily-available constant, which is poor form.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/kvm_main.c | 2 +-
drivers/kvm/svm.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 5b42731..6ad1b04 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -413,7 +413,7 @@ static void free_pio_guest_pages(struct kvm_vcpu *vcpu)
{
int i;

- for (i = 0; i < 2; ++i)
+ for (i = 0; i < ARRAY_SIZE(vcpu->pio.guest_pages); ++i)
if (vcpu->pio.guest_pages[i]) {
__free_page(vcpu->pio.guest_pages[i]);
vcpu->pio.guest_pages[i] = NULL;
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
index 9a840e0..c18f0b2 100644
--- a/drivers/kvm/svm.c
+++ b/drivers/kvm/svm.c
@@ -241,7 +241,7 @@ static void skip_emulated_instruction(struct kvm_vcpu *vcpu)
printk(KERN_DEBUG "%s: NOP\n", __FUNCTION__);
return;
}
- if (svm->next_rip - svm->vmcb->save.rip > 15) {
+ if (svm->next_rip - svm->vmcb->save.rip > MAX_INST_SIZE) {
printk(KERN_ERR "%s: ip 0x%llx next 0x%llx\n",
__FUNCTION__,
svm->vmcb->save.rip,
--
1.5.3

-

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

From: Aurelien Jarno <aurelien@aurel32.net>

The writeback fixes (02c03a326a5df825cc01de426f72e160db2b9538) let
some dead code in the cmpxchg instruction emulation. Remove it.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/x86_emulate.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)

diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index ef7518a..2136da5 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -1278,8 +1278,6 @@ twobyte_insn:
src.orig_val = src.val;
src.val = _regs[VCPU_REGS_RAX];
emulate_2op_SrcV("cmp", src, dst, _eflags);
- /* Always write back. The question is: where to? */
- d |= Mov;
if (_eflags & EFLG_ZF) {
/* Success: write back to memory. */
dst.val = src.orig_val;
--
1.5.3

-

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

From: Jeff Dike <jdike@addtoit.com>

Add the hypercall number to kvm_run and initialize it. This changes the ABI,
but as this particular ABI was unusable before this no users are affected.

Signed-off-by: Jeff Dike <jdike@linux.intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/kvm_main.c | 1 +
include/linux/kvm.h | 1 +
2 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 69d9ab4..2094746 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -1378,6 +1378,7 @@ int kvm_hypercall(struct kvm_vcpu *vcpu, struct kvm_run *run)
}
switch (nr) {
default:
+ run->hypercall.nr = nr;
run->hypercall.args[0] = a0;
run->hypercall.args[1] = a1;
run->hypercall.args[2] = a2;
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 8db01a9..91a446f 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -99,6 +99,7 @@ struct kvm_run {
} mmio;
/* KVM_EXIT_HYPERCALL */
struct {
+ __u64 nr;
__u64 args[6];
__u64 ret;
__u32 longmode;
--
1.5.3

-

To: <kvm-devel@...>
Cc: <linux-kernel@...>, Shaohua Li <shaohua.li@...>
Date: Monday, September 17, 2007 - 4:31 am

From: Shaohua Li <shaohua.li@intel.com>

vmx_cpu_run doesn't handle error correctly and kvm_mmu_reload might
sleep with mutex changes, so I move it above.

Signed-off-by: Shaohua Li <shaohua.li@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/vmx.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index 2c4f01b..79674a7 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -1999,16 +1999,16 @@ preempted:
kvm_guest_debug_pre(vcpu);

again:
+ r = kvm_mmu_reload(vcpu);
+ if (unlikely(r))
+ goto out;
+
if (!vcpu->mmio_read_completed)
do_interrupt_requests(vcpu, kvm_run);

vmx_save_host_state(vcpu);
kvm_load_guest_fpu(vcpu);

- r = kvm_mmu_reload(vcpu);
- if (unlikely(r))
- goto out;
-
/*
* Loading guest fpu may have cleared host cr0.ts
*/
--
1.5.3

-

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

Right now, the bug is harmless as we never emulate one-byte 0xb6 or 0xb7.
But things may change.

Noted by the mysterious Gabriel C.

Signed-off-by: Avi Kivity <avi@qumranet.com>
---
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 82b4ea6..ef7518a 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -819,7 +819,7 @@ done_prefixes:
case DstReg:
dst.type = OP_REG;
if ((d & ByteOp)
- && !(twobyte_table && (b == 0xb6 || b == 0xb7))) {
+ && !(twobyte && (b == 0xb6 || b == 0xb7))) {
dst.ptr = decode_register(modrm_reg, _regs,
(rex_prefix == 0));
dst.val = *(u8 *) dst.ptr;
--
1.5.3

-

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

From: Rusty Russell <rusty@rustcorp.com.au>

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

Also spell out definition of CR0_RESEVED_BITS (no code change) and fix typo.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/kvm.h | 19 +++++--------------
drivers/kvm/kvm_main.c | 15 +++++++++------
drivers/kvm/mmu.c | 2 +-
drivers/kvm/svm.c | 20 ++++++++++----------
drivers/kvm/vmx.c | 22 +++++++++++-----------
5 files changed, 36 insertions(+), 42 deletions(-)

diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index b629a83..7117c3b 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -19,15 +19,6 @@
#include <linux/kvm.h>
#include <linux/kvm_para.h>

-#define CR0_PE_MASK (1ULL << 0)
-#define CR0_MP_MASK (1ULL << 1)
-#define CR0_TS_MASK (1ULL << 3)
-#define CR0_NE_MASK (1ULL << 5)
-#define CR0_WP_MASK (1ULL << 16)
-#define CR0_NW_MASK (1ULL << 29)
-#define CR0_CD_MASK (1ULL << 30)
-#define CR0_PG_MASK (1ULL << 31)
-
#define CR3_WPT_MASK (1ULL << 3)
#define CR3_PCD_MASK (1ULL << 4)

@@ -42,11 +33,11 @@
#define CR4_VMXE_MASK (1ULL << 13)

#define KVM_GUEST_CR0_MASK \
- (CR0_PG_MASK | CR0_PE_MASK | CR0_WP_MASK | CR0_NE_MASK \
- | CR0_NW_MASK | CR0_CD_MASK)
+ (X86_CR0_PG | X86_CR0_PE | X86_CR0_WP | X86_CR0_NE \
+ | X86_CR0_NW | X86_CR0_CD)
#define KVM_VM_CR0_ALWAYS_ON \
- (CR0_PG_MASK | CR0_PE_MASK | CR0_WP_MASK | CR0_NE_MASK | CR0_TS_MASK \
- | CR0_MP_MASK)
+ (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)
@@ -667,7 +658,7 @@ static inline int is_pse(struct kvm_vcpu *vcpu)

static inline int is_paging(struc...

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

From: Rusty Russell <rusty@rustcorp.com.au>

Creating one's own BITMAP macro seems suboptimal: if we use manual
arithmetic in the one place exposed to userspace, we can use standard
macros elsewhere.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/kvm.h | 3 +--
drivers/kvm/kvm_main.c | 2 +-
include/linux/kvm.h | 10 ++--------
3 files changed, 4 insertions(+), 11 deletions(-)

diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index 25439a5..cec5f05 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -324,8 +324,7 @@ struct kvm_vcpu {
int guest_mode;
unsigned long requests;
unsigned long irq_summary; /* bit vector: 1 per word in irq_pending */
-#define NR_IRQ_WORDS KVM_IRQ_BITMAP_SIZE(unsigned long)
- unsigned long irq_pending[NR_IRQ_WORDS];
+ DECLARE_BITMAP(irq_pending, KVM_NR_INTERRUPTS);
unsigned long regs[NR_VCPU_REGS]; /* for rsp: vcpu_load_rsp_rip() */
unsigned long rip; /* needs vcpu_load_rsp_rip() */

diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index af02320..fc63de2 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -2130,7 +2130,7 @@ static int kvm_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
memcpy(vcpu->irq_pending, sregs->interrupt_bitmap,
sizeof vcpu->irq_pending);
vcpu->irq_summary = 0;
- for (i = 0; i < NR_IRQ_WORDS; ++i)
+ for (i = 0; i < ARRAY_SIZE(vcpu->irq_pending); ++i)
if (vcpu->irq_pending[i])
__set_bit(i, &vcpu->irq_summary);

diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 68ecced..8db01a9 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -12,14 +12,8 @@

#define KVM_API_VERSION 12

-/*
- * Architectural interrupt line count, and the size of the bitmap needed
- * to hold them.
- */
+/* Architectural interrupt line count. */
#define KVM_NR_INTERRUPTS 256
-#define KVM_IRQ_BITMAP_SIZE_BYTES ((KVM_NR...

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

From: Rusty Russell <rusty@rustcorp.com.au>

Don't pre-declare hardware_disable: shuffle the reboot hook down.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/kvm_main.c | 40 +++++++++++++++++++---------------------
1 files changed, 19 insertions(+), 21 deletions(-)

diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 1be510b..326fa79 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -54,8 +54,6 @@ static cpumask_t cpus_hardware_enabled;

struct kvm_arch_ops *kvm_arch_ops;

-static void hardware_disable(void *ignored);
-
#define STAT_OFFSET(x) offsetof(struct kvm_vcpu, stat.x)

static struct kvm_stats_debugfs_item {
@@ -2924,25 +2922,6 @@ static struct miscdevice kvm_dev = {
&kvm_chardev_ops,
};

-static int kvm_reboot(struct notifier_block *notifier, unsigned long val,
- void *v)
-{
- if (val == SYS_RESTART) {
- /*
- * Some (well, at least mine) BIOSes hang on reboot if
- * in vmx root mode.
- */
- printk(KERN_INFO "kvm: exiting hardware virtualization\n");
- on_each_cpu(hardware_disable, NULL, 0, 1);
- }
- return NOTIFY_OK;
-}
-
-static struct notifier_block kvm_reboot_notifier = {
- .notifier_call = kvm_reboot,
- .priority = 0,
-};
-
/*
* Make sure that a cpu that is being hot-unplugged does not have any vcpus
* cached on it.
@@ -3025,6 +3004,25 @@ static int kvm_cpu_hotplug(struct notifier_block *notifier, unsigned long val,
return NOTIFY_OK;
}

+static int kvm_reboot(struct notifier_block *notifier, unsigned long val,
+ void *v)
+{
+ if (val == SYS_RESTART) {
+ /*
+ * Some (well, at least mine) BIOSes hang on reboot if
+ * in vmx root mode.
+ */
+ printk(KERN_INFO "kvm: exiting hardware virtualization\n");
+ on_each_cpu(hardware_disable, NULL, 0, 1);
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block kvm_reboot_notifier = {
+ .not...

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

From: Rusty Russell <rusty@rustcorp.com.au>

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/x86_emulate.h | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)

diff --git a/drivers/kvm/x86_emulate.h b/drivers/kvm/x86_emulate.h
index ea3407d..2847d67 100644
--- a/drivers/kvm/x86_emulate.h
+++ b/drivers/kvm/x86_emulate.h
@@ -112,8 +112,6 @@ struct x86_emulate_ops {

};

-struct cpu_user_regs;
-
struct x86_emulate_ctxt {
/* Register state before/after emulation. */
struct kvm_vcpu *vcpu;
--
1.5.3

-

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

From: Rusty Russell <rusty@rustcorp.com.au>

I have shied away from touching x86_emulate.c (it could definitely use
some love, but it is forked from the Xen code, and it would be more
productive to cross-merge fixes).

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/x86_emulate.c | 9 +++++++--
drivers/kvm/x86_emulate.h | 8 --------
2 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index 4b8a0cc..f5e4644 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -443,8 +443,13 @@ struct operand {
(((reg) + _inc) & ((1UL << (ad_bytes << 3)) - 1)); \
} while (0)

-void *decode_register(u8 modrm_reg, unsigned long *regs,
- int highbyte_regs)
+/*
+ * Given the 'reg' portion of a ModRM byte, and a register block, return a
+ * pointer into the block that addresses the relevant register.
+ * @highbyte_regs specifies whether to decode AH,CH,DH,BH.
+ */
+static void *decode_register(u8 modrm_reg, unsigned long *regs,
+ int highbyte_regs)
{
void *p;

diff --git a/drivers/kvm/x86_emulate.h b/drivers/kvm/x86_emulate.h
index 2847d67..574cca7 100644
--- a/drivers/kvm/x86_emulate.h
+++ b/drivers/kvm/x86_emulate.h
@@ -152,12 +152,4 @@ struct x86_emulate_ctxt {
int x86_emulate_memop(struct x86_emulate_ctxt *ctxt,
struct x86_emulate_ops *ops);

-/*
- * Given the 'reg' portion of a ModRM byte, and a register block, return a
- * pointer into the block that addresses the relevant register.
- * @highbyte_regs specifies whether to decode AH,CH,DH,BH.
- */
-void *decode_register(u8 modrm_reg, unsigned long *regs,
- int highbyte_regs);
-
#endif /* __X86_EMULATE_H__ */
--
1.5.3

-

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

From: Rusty Russell <rusty@rustcorp.com.au>

KVM interface is no longer experimental.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
include/linux/kvm.h | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index b9a4b7c..68ecced 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -4,8 +4,7 @@
/*
* Userspace interface for /dev/kvm - kernel based virtual machine
*
- * Note: this interface is considered experimental and may change without
- * notice.
+ * Note: you must update KVM_API_VERSION if you change this interface.
*/

#include <asm/types.h>
--
1.5.3

-

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

From: Eddie Dong <eddie.dong@intel.com>

Add string pio write support to support some version of Windows.

Signed-off-by: Yaozu (Eddie) Dong <eddie.dong@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/kvm_main.c | 48 +++++++++++++++++++++++++++++++++++++-----------
1 files changed, 37 insertions(+), 11 deletions(-)

diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index df9c05e..1be510b 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -1760,18 +1760,35 @@ static int complete_pio(struct kvm_vcpu *vcpu)
return 0;
}

-void kernel_pio(struct kvm_io_device *pio_dev, struct kvm_vcpu *vcpu)
+static void kernel_pio(struct kvm_io_device *pio_dev,
+ struct kvm_vcpu *vcpu,
+ void *pd)
{
/* TODO: String I/O for in kernel device */

if (vcpu->pio.in)
kvm_iodevice_read(pio_dev, vcpu->pio.port,
vcpu->pio.size,
- vcpu->pio_data);
+ pd);
else
kvm_iodevice_write(pio_dev, vcpu->pio.port,
vcpu->pio.size,
- vcpu->pio_data);
+ pd);
+}
+
+static void pio_string_write(struct kvm_io_device *pio_dev,
+ struct kvm_vcpu *vcpu)
+{
+ struct kvm_pio_request *io = &vcpu->pio;
+ void *pd = vcpu->pio_data;
+ int i;
+
+ for (i = 0; i < io->cur_count; i++) {
+ kvm_iodevice_write(pio_dev, io->port,
+ io->size,
+ pd);
+ pd += io->size;
+ }
}

int kvm_setup_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
@@ -1779,7 +1796,7 @@ int kvm_setup_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
gva_t address, int rep, unsigned port)
{
unsigned now, in_page;
- int i;
+ int i, ret = 0;
int nr_pages = 1;
struct page *page;
struct kvm_io_device *pio_dev;
@@ -1806,15 +1823,12 @@ int kvm_setup_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
memcpy(vcpu->pio_data, &vcpu->regs[VCPU_REGS_RAX], 4);
kvm_arch_ops->decache_regs(vcpu);
...

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

Note that as the size of struct kvm_run is not part of the ABI, we can add
things at the end.

Signed-off-by: Avi Kivity <avi@qumranet.com>
---
include/linux/kvm.h | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index e6edca8..b9a4b7c 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -111,6 +111,8 @@ struct kvm_run {
__u32 longmode;
__u32 pad;
} hypercall;
+ /* Fix the size of the union. */
+ char padding[256];
};
};

--
1.5.3

-

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

From: Qing He <qing.he@intel.com>

This patch adds a `vcpu_id' field in `struct vcpu', so we can
differentiate BSP and APs without pointer comparison or arithmetic.

Signed-off-by: Qing He <qing.he@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/kvm.h | 1 +
drivers/kvm/kvm_main.c | 1 +
drivers/kvm/svm.c | 2 +-
drivers/kvm/vmx.c | 2 +-
4 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index 336be86..b629a83 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -328,6 +328,7 @@ void kvm_io_bus_register_dev(struct kvm_io_bus *bus,

struct kvm_vcpu {
struct kvm *kvm;
+ int vcpu_id;
union {
struct vmcs *vmcs;
struct vcpu_svm *svm;
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 36a458f..df9c05e 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -2355,6 +2355,7 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, int n)
goto out;

vcpu = &kvm->vcpus[n];
+ vcpu->vcpu_id = n;

mutex_lock(&vcpu->mutex);

diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
index bc818cc..52a11cc 100644
--- a/drivers/kvm/svm.c
+++ b/drivers/kvm/svm.c
@@ -591,7 +591,7 @@ static int svm_create_vcpu(struct kvm_vcpu *vcpu)
fx_init(vcpu);
vcpu->fpu_active = 1;
vcpu->apic_base = 0xfee00000 | MSR_IA32_APICBASE_ENABLE;
- if (vcpu == &vcpu->kvm->vcpus[0])
+ if (vcpu->vcpu_id == 0)
vcpu->apic_base |= MSR_IA32_APICBASE_BSP;

return 0;
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index 80628f6..7fa62c7 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -1253,7 +1253,7 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu)
vcpu->regs[VCPU_REGS_RDX] = get_rdx_init_val();
vcpu->cr8 = 0;
vcpu->apic_base = 0xfee00000 | MSR_IA32_APICBASE_ENABLE;
- if (vcpu == &vcpu->kvm->vcpus[0])
+ if (vcpu->vcpu_id == 0)
vcpu->apic_ba...

To: <kvm-devel@...>
Cc: <linux-kernel@...>, Nguyen Anh Quynh <aquynh@...>
Date: Monday, September 17, 2007 - 4:30 am

From: Nguyen Anh Quynh <aquynh@gmail.com>

*nopage() in kvm_main.c should only store the type of mmap() fault if
the pointers are not NULL. This patch fixes the problem.

Signed-off-by: Nguyen Anh Quynh <aquynh@gmail.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
drivers/kvm/kvm_main.c | 8 ++++++--
1 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index cd05579..36a458f 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -2285,7 +2285,6 @@ static struct page *kvm_vcpu_nopage(struct vm_area_struct *vma,
unsigned long pgoff;
struct page *page;

- *type = VM_FAULT_MINOR;
pgoff = ((address - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
if (pgoff == 0)
page = virt_to_page(vcpu->run);
@@ -2294,6 +2293,9 @@ static struct page *kvm_vcpu_nopage(struct vm_area_struct *vma,
else
return NOPAGE_SIGBUS;
get_page(page);
+ if (type != NULL)
+ *type = VM_FAULT_MINOR;
+
return page;
}

@@ -2768,12 +2770,14 @@ static struct page *kvm_vm_nopage(struct vm_area_struct *vma,
unsigned long pgoff;
struct page *page;

- *type = VM_FAULT_MINOR;
pgoff = ((address - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
page = gfn_to_page(kvm, pgoff);
if (!page)
return NOPAGE_SIGBUS;
get_page(page);
+ if (type != NULL)
+ *type = VM_FAULT_MINOR;
+
return page;
}

--
1.5.3

-

To: Avi Kivity <avi@...>
Cc: <kvm-devel@...>, <linux-kernel@...>, Nguyen Anh Quynh <aquynh@...>
Date: Monday, September 17, 2007 - 5:13 am

Care to convert it to ->faul while you're at it?
-

To: Christoph Hellwig <hch@...>, Avi Kivity <avi@...>, <kvm-devel@...>, <linux-kernel@...>, Nguyen Anh Quynh <aquynh@...>
Date: Monday, September 17, 2007 - 5:15 am

I'll add this to my todo, though not sure It'll be in time for .24. If
someone sends a patch I'll apply it.

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

-

To: Christoph Hellwig <hch@...>, Avi Kivity <avi@...>, <kvm-devel@...>, <linux-kernel@...>, Nguyen Anh Quynh <aquynh@...>
Date: Monday, September 17, 2007 - 5:18 am

I should mention that the converting to use ->fault() is a 15-minute
change; the tricky part is adding backwards compatibility for the
external module package.

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

-

To: Avi Kivity <avi@...>
Cc: Christoph Hellwig <hch@...>, <kvm-devel@...>, <linux-kernel@...>, Nguyen Anh Quynh <aquynh@...>
Date: Sunday, September 16, 2007 - 5:29 pm

It should be mostly possible to ifdef a nopage() handler, which is
just a wrapper function to translate arguments then call your new
->fault() handler. With luck, fault would mostly inline into nopage,
and do some constant folding to make it cheaper...

I'm planning to go through and convert the rest of the in-tree users
at some point soon, so if you do get a chance to convert your
upstream code before I try, it would nice ;)

Thanks,
Nick
-

To: Nick Piggin <nickpiggin@...>
Cc: Christoph Hellwig <hch@...>, <kvm-devel@...>, <linux-kernel@...>, Nguyen Anh Quynh <aquynh@...>
Date: Monday, September 17, 2007 - 2:19 pm

In kvm I don't add compatibility #ifdefs to mainline, instead I have an
awk script that massages the sources into something that all kernels can
grok.

It isn't pretty but it works.

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

-

To: Avi Kivity <avi@...>
Cc: Christoph Hellwig <hch@...>, <kvm-devel@...>, <linux-kernel@...>, Nguyen Anh Quynh <aquynh@...>
Date: Monday, September 17, 2007 - 1:17 pm

Sure, but my suggestion is just a way to make it possible without having
to maintain a lot of duplicated code. The point is simply that we'll be
getting rid of nopage from mainline sooner or later, and it will probably

It is pretty for mainline :) I appreciate you going out of your way to make
the code nicer rather than just make your life easier.
-

To: Nick Piggin <nickpiggin@...>
Cc: Christoph Hellwig <hch@...>, <kvm-devel@...>, <linux-kernel@...>, Nguyen Anh Quynh <aquynh@...>
Date: Tuesday, September 18, 2007 - 6:44 am

Certainly it's best done by someone familiar with the kvm external
module hackery. I'll do it during 2.6.24 if no one beats me to it.

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

-

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)