From patchwork Thu Oct 15 05:41: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: 53932 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 n9F5jWZH013639 for ; Thu, 15 Oct 2009 05:45:32 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933004AbZJOFmm (ORCPT ); Thu, 15 Oct 2009 01:42:42 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S933001AbZJOFml (ORCPT ); Thu, 15 Oct 2009 01:42:41 -0400 Received: from mail-qy0-f172.google.com ([209.85.221.172]:44221 "EHLO mail-qy0-f172.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932976AbZJOFmk (ORCPT ); Thu, 15 Oct 2009 01:42:40 -0400 Received: by qyk2 with SMTP id 2so435534qyk.21 for ; Wed, 14 Oct 2009 22:42:04 -0700 (PDT) Received: by 10.224.98.149 with SMTP id q21mr7859010qan.229.1255585324029; Wed, 14 Oct 2009 22:42:04 -0700 (PDT) Received: from ?192.168.254.106? (c-98-248-44-54.hsd1.ca.comcast.net [98.248.44.54]) by mx.google.com with ESMTPS id 22sm3162142qyk.2.2009.10.14.22.42.02 (version=SSLv3 cipher=RC4-MD5); Wed, 14 Oct 2009 22:42:03 -0700 (PDT) Subject: [PATCH] Xen PV-on-HVM guest support (v2) From: Ed Swierk To: kvm@vger.kernel.org Cc: Jan Kiszka , Gerd Hoffmann Date: Wed, 14 Oct 2009 22:41:58 -0700 Message-Id: <1255585318.12773.14.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 Index: kvm-kmod/include/asm-x86/kvm.h =================================================================== --- kvm-kmod.orig/include/asm-x86/kvm.h +++ kvm-kmod/include/asm-x86/kvm.h @@ -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 Index: kvm-kmod/include/linux/kvm.h =================================================================== --- kvm-kmod.orig/include/linux/kvm.h +++ kvm-kmod/include/linux/kvm.h @@ -476,6 +476,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 @@ -528,6 +531,15 @@ struct kvm_x86_mce { }; #endif +#ifdef KVM_CAP_XEN_HVM +struct kvm_xen_hvm_config { + __u32 msr; + __u8 pad[2]; + __u8 blob_size[2]; + __u64 blob_addr[2]; +}; +#endif + #define KVM_IRQFD_FLAG_DEASSIGN (1 << 0) struct kvm_irqfd { @@ -586,6 +598,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 Index: kvm-kmod/include/linux/kvm_host.h =================================================================== --- kvm-kmod.orig/include/linux/kvm_host.h +++ kvm-kmod/include/linux/kvm_host.h @@ -236,6 +236,10 @@ struct kvm { 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. */ Index: kvm-kmod/x86/x86.c =================================================================== --- kvm-kmod.orig/x86/x86.c +++ kvm-kmod/x86/x86.c @@ -875,6 +875,35 @@ static int set_msr_mce(struct kvm_vcpu * 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; + + 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; + if (kvm_write_guest(vcpu->kvm, paddr, page, PAGE_SIZE)) + goto out_free; + printk(KERN_DEBUG "kvm: copied xen hvm blob %d page %d to 0x%llx\n", + blob, pnum, paddr); + 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 +1019,10 @@ int kvm_set_msr_common(struct kvm_vcpu * "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 +2486,17 @@ long kvm_arch_vm_ioctl(struct file *filp r = 0; break; } +#ifdef KVM_CAP_XEN_HVM + case KVM_XEN_HVM_CONFIG: { + r = -EFAULT; + if (copy_from_user(&kvm->xen_hvm_config, argp, + sizeof(struct kvm_xen_hvm_config))) + goto out; + printk(KERN_DEBUG "kvm: configured xen hvm\n"); + r = 0; + break; + } +#endif default: ; }