From patchwork Wed Oct 14 04:52:58 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ed Swierk X-Patchwork-Id: 53581 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n9E59GQR027561 for ; Wed, 14 Oct 2009 05:09:16 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754069AbZJNFCV (ORCPT ); Wed, 14 Oct 2009 01:02:21 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1753894AbZJNFCV (ORCPT ); Wed, 14 Oct 2009 01:02:21 -0400 Received: from qw-out-2122.google.com ([74.125.92.27]:25322 "EHLO qw-out-2122.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753849AbZJNFCU (ORCPT ); Wed, 14 Oct 2009 01:02:20 -0400 Received: by qw-out-2122.google.com with SMTP id 9so1120669qwb.37 for ; Tue, 13 Oct 2009 22:01:14 -0700 (PDT) Received: by 10.224.58.201 with SMTP id i9mr6723603qah.8.1255495984524; Tue, 13 Oct 2009 21:53:04 -0700 (PDT) Received: from ?192.168.254.105? (c-98-248-44-54.hsd1.ca.comcast.net [98.248.44.54]) by mx.google.com with ESMTPS id 21sm2556862qyk.12.2009.10.13.21.53.02 (version=SSLv3 cipher=RC4-MD5); Tue, 13 Oct 2009 21:53:03 -0700 (PDT) Subject: [PATCH][RFC] Xen PV-on-HVM guest support From: Ed Swierk To: kvm@vger.kernel.org, Gerd Hoffmann Date: Tue, 13 Oct 2009 21:52:58 -0700 Message-Id: <1255495978.26053.37.camel@localhost.localdomain> Mime-Version: 1.0 X-Mailer: Evolution 2.26.3 (2.26.3-1.fc11) Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org diff -BurN a/include/asm-x86/kvm.h b/include/asm-x86/kvm.h --- a/include/asm-x86/kvm.h 2009-10-13 20:40:55.000000000 -0700 +++ b/include/asm-x86/kvm.h 2009-10-13 20:21:07.000000000 -0700 @@ -59,6 +59,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 -BurN a/include/linux/kvm.h b/include/linux/kvm.h --- a/include/linux/kvm.h 2009-10-13 20:40:55.000000000 -0700 +++ b/include/linux/kvm.h 2009-10-13 20:21:26.000000000 -0700 @@ -476,6 +476,9 @@ #endif #define KVM_CAP_IOEVENTFD 36 #define KVM_CAP_SET_IDENTITY_MAP_ADDR 37 +#ifdef __KVM_HAVE_XEN_HVM +#define KVM_CAP_XEN_HVM 90 +#endif #ifdef KVM_CAP_IRQ_ROUTING @@ -528,6 +531,14 @@ }; #endif +#ifdef KVM_CAP_XEN_HVM +struct kvm_xen_hvm_config { + __u32 msr; + __u64 blob_addr[2]; + __u8 blob_size[2]; +}; +#endif + #define KVM_IRQFD_FLAG_DEASSIGN (1 << 0) struct kvm_irqfd { @@ -586,6 +597,7 @@ #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, 0xa1, struct kvm_xen_hvm_config) /* * ioctls for vcpu fds diff -BurN a/include/linux/kvm_host.h b/include/linux/kvm_host.h --- a/include/linux/kvm_host.h 2009-10-13 20:40:55.000000000 -0700 +++ b/include/linux/kvm_host.h 2009-10-13 20:27:03.000000000 -0700 @@ -236,6 +236,10 @@ unsigned long mmu_notifier_seq; long mmu_notifier_count; #endif + +#ifdef KVM_CAP_XEN_HVM + struct kvm_xen_hvm_config xen_hvm_config; +#endif }; /* The guest did something we don't support. */ diff -BurN a/x86/x86.c b/x86/x86.c --- a/x86/x86.c 2009-10-13 20:40:58.000000000 -0700 +++ b/x86/x86.c 2009-10-13 20:33:49.000000000 -0700 @@ -875,6 +875,33 @@ return 0; } +#ifdef KVM_CAP_XEN_HVM +static int xen_hvm_config(struct kvm_vcpu *vcpu, u64 data) +{ + int blob = !!(vcpu->arch.shadow_efer & EFER_LME); + u32 pnum = data & ~PAGE_MASK; + u64 paddr = data & PAGE_MASK; + u8 *page; + int r = 1; + printk(KERN_INFO "kvm: loading xen hvm blob %d page %d at %llx\n", + blob, pnum, paddr); + if (pnum >= vcpu->kvm->xen_hvm_config.blob_size[blob]) + goto out; + page = kzalloc(PAGE_SIZE, GFP_KERNEL); + if (!page) + goto out; + if (copy_from_user(page, (u8 *)vcpu->kvm->xen_hvm_config.blob_addr[blob] + + pnum * PAGE_SIZE, PAGE_SIZE)) + goto out_free; + kvm_write_guest(vcpu->kvm, paddr, page, PAGE_SIZE); + r = 0; +out_free: + kfree(page); +out: + return r; +} +#endif + int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) { switch (msr) { @@ -990,6 +1017,10 @@ "0x%x data 0x%llx\n", msr, data); break; default: +#ifdef KVM_CAP_XEN_HVM + if (msr && (msr == vcpu->kvm->xen_hvm_config.msr)) + return xen_hvm_config(vcpu, data); +#endif if (!ignore_msrs) { pr_unimpl(vcpu, "unhandled wrmsr: 0x%x data %llx\n", msr, data); @@ -2453,6 +2484,17 @@ r = 0; break; } +#ifdef KVM_CAP_XEN_HVM + case KVM_XEN_HVM_CONFIG: { + r = -EFAULT; + printk(KERN_INFO "kvm: configuring xen hvm\n"); + if (copy_from_user(&kvm->xen_hvm_config, argp, + sizeof(struct kvm_xen_hvm_config))) + goto out; + r = 0; + break; + } +#endif default: ; }