From patchwork Fri Jul 17 08:11:12 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sheng Yang X-Patchwork-Id: 35992 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 n6H8BT2W014313 for ; Fri, 17 Jul 2009 08:11:29 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934205AbZGQIL0 (ORCPT ); Fri, 17 Jul 2009 04:11:26 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S934203AbZGQIL0 (ORCPT ); Fri, 17 Jul 2009 04:11:26 -0400 Received: from mga01.intel.com ([192.55.52.88]:42977 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934196AbZGQILZ (ORCPT ); Fri, 17 Jul 2009 04:11:25 -0400 Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga101.fm.intel.com with ESMTP; 17 Jul 2009 00:56:11 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.42,416,1243839600"; d="scan'208";a="708639772" Received: from syang10-desktop.sh.intel.com (HELO syang10-desktop) ([10.239.13.29]) by fmsmga001.fm.intel.com with ESMTP; 17 Jul 2009 01:14:39 -0700 Received: from yasker by syang10-desktop with local (Exim 4.69) (envelope-from ) id 1MRiXB-0007k0-IR; Fri, 17 Jul 2009 16:11:13 +0800 From: Sheng Yang To: Marcelo Tosatti Cc: kvm@vger.kernel.org, jordan.l.justen@intel.com, Sheng Yang Subject: [PATCH 1/2] KVM: Introduce KVM_SET_IDENTITY_MAP_ADDR ioctl Date: Fri, 17 Jul 2009 16:11:12 +0800 Message-Id: <1247818273-29737-1-git-send-email-sheng@linux.intel.com> X-Mailer: git-send-email 1.6.0.4 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Now KVM allow guest to modify guest's physical address of EPT's identity mapping page. Signed-off-by: Sheng Yang --- arch/x86/include/asm/kvm_host.h | 1 + arch/x86/kvm/vmx.c | 13 +++++++++---- arch/x86/kvm/x86.c | 16 ++++++++++++++++ include/linux/kvm.h | 2 ++ 4 files changed, 28 insertions(+), 4 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 08732d7..e210b21 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -411,6 +411,7 @@ struct kvm_arch{ struct page *ept_identity_pagetable; bool ept_identity_pagetable_done; + gpa_t ept_identity_map_addr; unsigned long irq_sources_bitmap; unsigned long irq_states[KVM_IOAPIC_NUM_PINS]; diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 3a75db3..4ffc4c3 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -1719,7 +1719,7 @@ static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) eptp = construct_eptp(cr3); vmcs_write64(EPT_POINTER, eptp); guest_cr3 = is_paging(vcpu) ? vcpu->arch.cr3 : - VMX_EPT_IDENTITY_PAGETABLE_ADDR; + vcpu->kvm->arch.ept_identity_map_addr; } vmx_flush_tlb(vcpu); @@ -2122,7 +2122,7 @@ static int init_rmode_identity_map(struct kvm *kvm) if (likely(kvm->arch.ept_identity_pagetable_done)) return 1; ret = 0; - identity_map_pfn = VMX_EPT_IDENTITY_PAGETABLE_ADDR >> PAGE_SHIFT; + identity_map_pfn = kvm->arch.ept_identity_map_addr >> PAGE_SHIFT; r = kvm_clear_guest_page(kvm, identity_map_pfn, 0, PAGE_SIZE); if (r < 0) goto out; @@ -2191,7 +2191,8 @@ static int alloc_identity_pagetable(struct kvm *kvm) goto out; kvm_userspace_mem.slot = IDENTITY_PAGETABLE_PRIVATE_MEMSLOT; kvm_userspace_mem.flags = 0; - kvm_userspace_mem.guest_phys_addr = VMX_EPT_IDENTITY_PAGETABLE_ADDR; + kvm_userspace_mem.guest_phys_addr = + kvm->arch.ept_identity_map_addr; kvm_userspace_mem.memory_size = PAGE_SIZE; r = __kvm_set_memory_region(kvm, &kvm_userspace_mem, 0); if (r) @@ -3814,9 +3815,13 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id) if (alloc_apic_access_page(kvm) != 0) goto free_vmcs; - if (enable_ept) + if (enable_ept) { + if (!kvm->arch.ept_identity_map_addr) + kvm->arch.ept_identity_map_addr = + VMX_EPT_IDENTITY_PAGETABLE_ADDR; if (alloc_identity_pagetable(kvm) != 0) goto free_vmcs; + } return &vmx->vcpu; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 48567fa..29beaec 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1208,6 +1208,7 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_IOEVENTFD: case KVM_CAP_PIT2: case KVM_CAP_PIT_STATE2: + case KVM_CAP_SET_IDENTITY_MAP_ADDR: r = 1; break; case KVM_CAP_COALESCED_MMIO: @@ -1908,6 +1909,16 @@ static int kvm_vm_ioctl_set_tss_addr(struct kvm *kvm, unsigned long addr) return ret; } +static int kvm_vm_ioctl_set_identity_map_addr(struct kvm *kvm, + unsigned long addr) +{ + if (addr > (unsigned int)(-4 * PAGE_SIZE)) + return -1; + kvm->arch.ept_identity_map_addr = addr; + + return 0; +} + static int kvm_vm_ioctl_set_nr_mmu_pages(struct kvm *kvm, u32 kvm_nr_mmu_pages) { @@ -2171,6 +2182,11 @@ long kvm_arch_vm_ioctl(struct file *filp, if (r < 0) goto out; break; + case KVM_SET_IDENTITY_MAP_ADDR: + r = kvm_vm_ioctl_set_identity_map_addr(kvm, arg); + if (r < 0) + goto out; + break; case KVM_SET_MEMORY_REGION: { struct kvm_memory_region kvm_mem; struct kvm_userspace_memory_region kvm_userspace_mem; diff --git a/include/linux/kvm.h b/include/linux/kvm.h index 230a91a..4266b0a 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -435,6 +435,7 @@ struct kvm_ioeventfd { #define KVM_CAP_PIT_STATE2 35 #endif #define KVM_CAP_IOEVENTFD 36 +#define KVM_CAP_SET_IDENTITY_MAP_ADDR 37 #ifdef KVM_CAP_IRQ_ROUTING @@ -512,6 +513,7 @@ struct kvm_irqfd { #define KVM_SET_USER_MEMORY_REGION _IOW(KVMIO, 0x46,\ struct kvm_userspace_memory_region) #define KVM_SET_TSS_ADDR _IO(KVMIO, 0x47) +#define KVM_SET_IDENTITY_MAP_ADDR _IO(KVMIO, 0x48) /* Device model IOC */ #define KVM_CREATE_IRQCHIP _IO(KVMIO, 0x60) #define KVM_IRQ_LINE _IOW(KVMIO, 0x61, struct kvm_irq_level)