From: Avi Kivity <avi@redhat.com>
To: linux-kernel@vger.kernel.org
Cc: kvm@vger.kernel.org
Subject: [PATCH 11/35] KVM: Xen PV-on-HVM guest support
Date: Thu, 19 Nov 2009 15:34:47 +0200 [thread overview]
Message-ID: <1258637711-11674-12-git-send-email-avi@redhat.com> (raw)
In-Reply-To: <1258637711-11674-1-git-send-email-avi@redhat.com>
From: Ed Swierk <eswierk@aristanetworks.com>
Support for Xen PV-on-HVM guests can be implemented almost entirely in
userspace, except for handling one annoying MSR that maps a Xen
hypercall blob into guest address space.
A generic mechanism to delegate MSR writes to userspace seems overkill
and risks encouraging similar MSR abuse in the future. Thus this patch
adds special support for the Xen HVM MSR.
I implemented a new ioctl, KVM_XEN_HVM_CONFIG, that lets userspace tell
KVM which MSR the guest will write to, as well as the starting address
and size of the hypercall blobs (one each for 32-bit and 64-bit) that
userspace has loaded from files. When the guest writes to the MSR, KVM
copies one page of the blob from userspace to the guest.
I've tested this patch with a hacked-up version of Gerd's userspace
code, booting a number of guests (CentOS 5.3 i386 and x86_64, and
FreeBSD 8.0-RC1 amd64) and exercising PV network and block devices.
[jan: fix i386 build warning]
[avi: future proof abi with a flags field]
Signed-off-by: Ed Swierk <eswierk@aristanetworks.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
---
Documentation/kvm/api.txt | 24 ++++++++++++++++++++
arch/x86/include/asm/kvm.h | 1 +
arch/x86/include/asm/kvm_host.h | 2 +
arch/x86/kvm/x86.c | 46 +++++++++++++++++++++++++++++++++++++++
include/linux/kvm.h | 16 +++++++++++++
5 files changed, 89 insertions(+), 0 deletions(-)
diff --git a/Documentation/kvm/api.txt b/Documentation/kvm/api.txt
index 5a4bc8c..3e8684e 100644
--- a/Documentation/kvm/api.txt
+++ b/Documentation/kvm/api.txt
@@ -593,6 +593,30 @@ struct kvm_irqchip {
} chip;
};
+4.27 KVM_XEN_HVM_CONFIG
+
+Capability: KVM_CAP_XEN_HVM
+Architectures: x86
+Type: vm ioctl
+Parameters: struct kvm_xen_hvm_config (in)
+Returns: 0 on success, -1 on error
+
+Sets the MSR that the Xen HVM guest uses to initialize its hypercall
+page, and provides the starting address and size of the hypercall
+blobs in userspace. When the guest writes the MSR, kvm copies one
+page of a blob (32- or 64-bit, depending on the vcpu mode) to guest
+memory.
+
+struct kvm_xen_hvm_config {
+ __u32 flags;
+ __u32 msr;
+ __u64 blob_addr_32;
+ __u64 blob_addr_64;
+ __u8 blob_size_32;
+ __u8 blob_size_64;
+ __u8 pad2[30];
+};
+
5. The kvm_run structure
Application code obtains a pointer to the kvm_run structure by
diff --git a/arch/x86/include/asm/kvm.h b/arch/x86/include/asm/kvm.h
index f02e87a..ef9b4b7 100644
--- a/arch/x86/include/asm/kvm.h
+++ b/arch/x86/include/asm/kvm.h
@@ -19,6 +19,7 @@
#define __KVM_HAVE_MSIX
#define __KVM_HAVE_MCE
#define __KVM_HAVE_PIT_STATE2
+#define __KVM_HAVE_XEN_HVM
/* Architectural interrupt line count. */
#define KVM_NR_INTERRUPTS 256
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 179a919..36f3b53 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -410,6 +410,8 @@ struct kvm_arch{
unsigned long irq_sources_bitmap;
u64 vm_init_tsc;
+
+ struct kvm_xen_hvm_config xen_hvm_config;
};
struct kvm_vm_stat {
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 5d450cc..bb842db 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -857,6 +857,38 @@ static int set_msr_mce(struct kvm_vcpu *vcpu, u32 msr, u64 data)
return 0;
}
+static int xen_hvm_config(struct kvm_vcpu *vcpu, u64 data)
+{
+ struct kvm *kvm = vcpu->kvm;
+ int lm = is_long_mode(vcpu);
+ u8 *blob_addr = lm ? (u8 *)(long)kvm->arch.xen_hvm_config.blob_addr_64
+ : (u8 *)(long)kvm->arch.xen_hvm_config.blob_addr_32;
+ u8 blob_size = lm ? kvm->arch.xen_hvm_config.blob_size_64
+ : kvm->arch.xen_hvm_config.blob_size_32;
+ u32 page_num = data & ~PAGE_MASK;
+ u64 page_addr = data & PAGE_MASK;
+ u8 *page;
+ int r;
+
+ r = -E2BIG;
+ if (page_num >= blob_size)
+ goto out;
+ r = -ENOMEM;
+ page = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ if (!page)
+ goto out;
+ r = -EFAULT;
+ if (copy_from_user(page, blob_addr + (page_num * PAGE_SIZE), PAGE_SIZE))
+ goto out_free;
+ if (kvm_write_guest(kvm, page_addr, page, PAGE_SIZE))
+ goto out_free;
+ r = 0;
+out_free:
+ kfree(page);
+out:
+ return r;
+}
+
int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
{
switch (msr) {
@@ -972,6 +1004,8 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
"0x%x data 0x%llx\n", msr, data);
break;
default:
+ if (msr && (msr == vcpu->kvm->arch.xen_hvm_config.msr))
+ return xen_hvm_config(vcpu, data);
if (!ignore_msrs) {
pr_unimpl(vcpu, "unhandled wrmsr: 0x%x data %llx\n",
msr, data);
@@ -1246,6 +1280,7 @@ int kvm_dev_ioctl_check_extension(long ext)
case KVM_CAP_PIT2:
case KVM_CAP_PIT_STATE2:
case KVM_CAP_SET_IDENTITY_MAP_ADDR:
+ case KVM_CAP_XEN_HVM:
r = 1;
break;
case KVM_CAP_COALESCED_MMIO:
@@ -2441,6 +2476,17 @@ long kvm_arch_vm_ioctl(struct file *filp,
r = 0;
break;
}
+ case KVM_XEN_HVM_CONFIG: {
+ r = -EFAULT;
+ if (copy_from_user(&kvm->arch.xen_hvm_config, argp,
+ sizeof(struct kvm_xen_hvm_config)))
+ goto out;
+ r = -EINVAL;
+ if (kvm->arch.xen_hvm_config.flags)
+ goto out;
+ r = 0;
+ break;
+ }
default:
;
}
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index f8f8900..b694c1d 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -436,6 +436,9 @@ struct kvm_ioeventfd {
#endif
#define KVM_CAP_IOEVENTFD 36
#define KVM_CAP_SET_IDENTITY_MAP_ADDR 37
+#ifdef __KVM_HAVE_XEN_HVM
+#define KVM_CAP_XEN_HVM 38
+#endif
#ifdef KVM_CAP_IRQ_ROUTING
@@ -488,6 +491,18 @@ struct kvm_x86_mce {
};
#endif
+#ifdef KVM_CAP_XEN_HVM
+struct kvm_xen_hvm_config {
+ __u32 flags;
+ __u32 msr;
+ __u64 blob_addr_32;
+ __u64 blob_addr_64;
+ __u8 blob_size_32;
+ __u8 blob_size_64;
+ __u8 pad2[30];
+};
+#endif
+
#define KVM_IRQFD_FLAG_DEASSIGN (1 << 0)
struct kvm_irqfd {
@@ -546,6 +561,7 @@ struct kvm_irqfd {
#define KVM_CREATE_PIT2 _IOW(KVMIO, 0x77, struct kvm_pit_config)
#define KVM_SET_BOOT_CPU_ID _IO(KVMIO, 0x78)
#define KVM_IOEVENTFD _IOW(KVMIO, 0x79, struct kvm_ioeventfd)
+#define KVM_XEN_HVM_CONFIG _IOW(KVMIO, 0x7a, struct kvm_xen_hvm_config)
/*
* ioctls for vcpu fds
--
1.6.5.2
next prev parent reply other threads:[~2009-11-19 13:35 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-11-19 13:34 [PATCH 00/35] KVM updates for the 2.6.33 merge window (batch 2/2) Avi Kivity
2009-11-19 13:34 ` [PATCH 01/35] KVM: SVM: Add tracepoint for #vmexit because intr pending Avi Kivity
2009-11-19 13:34 ` [PATCH 02/35] KVM: SVM: Add tracepoint for invlpga instruction Avi Kivity
2009-11-19 13:34 ` [PATCH 03/35] KVM: SVM: Add tracepoint for skinit instruction Avi Kivity
2009-11-19 13:34 ` [PATCH 04/35] KVM: SVM: Remove nsvm_printk debugging code Avi Kivity
2009-11-19 13:34 ` [PATCH 05/35] KVM: introduce kvm_vcpu_on_spin Avi Kivity
2009-11-19 13:34 ` [PATCH 06/35] KVM: VMX: Add support for Pause-Loop Exiting Avi Kivity
2009-11-19 13:34 ` [PATCH 07/35] KVM: SVM: Support Pause Filter in AMD processors Avi Kivity
2009-11-19 13:34 ` [PATCH 08/35] KVM: x86: Harden against cpufreq Avi Kivity
2009-11-19 13:34 ` [PATCH 09/35] KVM: VMX: fix handle_pause declaration Avi Kivity
2009-11-19 13:34 ` [PATCH 10/35] KVM: x86: Drop unneeded CONFIG_HAS_IOMEM check Avi Kivity
2009-11-19 13:34 ` Avi Kivity [this message]
2009-11-19 13:34 ` [PATCH 12/35] KVM: x86: Fix guest single-stepping while interruptible Avi Kivity
2009-11-19 13:34 ` [PATCH 13/35] KVM: SVM: Cleanup NMI singlestep Avi Kivity
2009-11-19 13:34 ` [PATCH 14/35] KVM: fix irq_source_id size verification Avi Kivity
2009-11-19 13:34 ` [PATCH 15/35] KVM: allow userspace to adjust kvmclock offset Avi Kivity
2010-01-29 13:32 ` Alexander Graf
2010-02-01 18:54 ` Marcelo Tosatti
2010-02-01 21:42 ` patch kvm-allow-userspace-to-adjust-kvmclock-offset.patch added to 2.6.32-stable tree gregkh
2009-11-19 13:34 ` [PATCH 16/35] KVM: Enable 32bit dirty log pointers on 64bit host Avi Kivity
2009-11-19 13:34 ` [PATCH 17/35] KVM: VMX: Use macros instead of hex value on cr0 initialization Avi Kivity
2009-11-19 13:34 ` [PATCH 18/35] KVM: SVM: Reset cr0 properly on vcpu reset Avi Kivity
2009-11-19 13:34 ` [PATCH 19/35] KVM: SVM: init_vmcb(): remove redundant save->cr0 initialization Avi Kivity
2009-11-19 13:34 ` [PATCH 20/35] KVM: VMX: Move MSR_KERNEL_GS_BASE out of the vmx autoload msr area Avi Kivity
2009-11-19 13:34 ` [PATCH 21/35] KVM: x86 shared msr infrastructure Avi Kivity
2009-11-19 13:34 ` [PATCH 22/35] KVM: VMX: Use " Avi Kivity
2009-11-19 13:34 ` [PATCH 23/35] KVM: powerpc: Fix BUILD_BUG_ON condition Avi Kivity
2009-11-19 13:35 ` [PATCH 24/35] KVM: remove duplicated task_switch check Avi Kivity
2009-11-19 13:35 ` [PATCH 25/35] KVM: VMX: move CR3/PDPTR update to vmx_set_cr3 Avi Kivity
2009-11-19 13:35 ` [PATCH 26/35] KVM: MMU: update invlpg handler comment Avi Kivity
2009-11-19 13:35 ` [PATCH 27/35] KVM: VMX: Remove vmx->msr_offset_efer Avi Kivity
2009-11-19 13:35 ` [PATCH 28/35] KVM: x86: disallow multiple KVM_CREATE_IRQCHIP Avi Kivity
2009-11-19 13:35 ` [PATCH 29/35] KVM: x86: disallow KVM_{SET,GET}_LAPIC without allocated in-kernel lapic Avi Kivity
2009-11-19 13:35 ` [PATCH 30/35] KVM: only clear irq_source_id if irqchip is present Avi Kivity
2009-11-19 13:35 ` [PATCH 31/35] KVM: x86: Polish exception injection via KVM_SET_GUEST_DEBUG Avi Kivity
2009-11-19 13:35 ` [PATCH 32/35] KVM: Reorder IOCTLs in main kvm.h Avi Kivity
2009-11-19 13:35 ` [PATCH 33/35] KVM: Allow internal errors reported to userspace to carry extra data Avi Kivity
2009-11-19 13:35 ` [PATCH 34/35] KVM: VMX: Report unexpected simultaneous exceptions as internal errors Avi Kivity
2009-11-19 13:35 ` [PATCH 35/35] KVM: x86: Add KVM_GET/SET_VCPU_EVENTS Avi Kivity
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1258637711-11674-12-git-send-email-avi@redhat.com \
--to=avi@redhat.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox