public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2][v2] KVM: Introduce KVM_SET_IDENTITY_MAP_ADDR ioctl
@ 2009-07-21  2:42 Sheng Yang
  2009-07-21  2:42 ` [PATCH 2/2][v2] kvm: allow qemu to set EPT identity mapping address Sheng Yang
  2009-07-21 16:50 ` [PATCH 1/2][v2] KVM: Introduce KVM_SET_IDENTITY_MAP_ADDR ioctl Marcelo Tosatti
  0 siblings, 2 replies; 3+ messages in thread
From: Sheng Yang @ 2009-07-21  2:42 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: kvm, Avi Kivity, Sheng Yang

Now KVM allow guest to modify guest's physical address of EPT's identity mapping page.

(change from v1, discard unnecessary check, change ioctl to accept parameter
address rather than value)

Signed-off-by: Sheng Yang <sheng@linux.intel.com>
---
 arch/x86/include/asm/kvm_host.h |    1 +
 arch/x86/kvm/vmx.c              |   13 +++++++++----
 arch/x86/kvm/x86.c              |   19 +++++++++++++++++++
 include/linux/kvm.h             |    2 ++
 4 files changed, 31 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..6fdfc17 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,13 @@ 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,
+					      u64 ident_addr)
+{
+	kvm->arch.ept_identity_map_addr = ident_addr;
+	return 0;
+}
+
 static int kvm_vm_ioctl_set_nr_mmu_pages(struct kvm *kvm,
 					  u32 kvm_nr_mmu_pages)
 {
@@ -2171,6 +2179,17 @@ long kvm_arch_vm_ioctl(struct file *filp,
 		if (r < 0)
 			goto out;
 		break;
+	case KVM_SET_IDENTITY_MAP_ADDR: {
+		u64 ident_addr;
+
+		r = -EFAULT;
+		if (copy_from_user(&ident_addr, argp, sizeof ident_addr))
+			goto out;
+		r = kvm_vm_ioctl_set_identity_map_addr(kvm, ident_addr);
+		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..f8f8900 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 _IOW(KVMIO, 0x48, __u64)
 /* Device model IOC */
 #define KVM_CREATE_IRQCHIP	  _IO(KVMIO,  0x60)
 #define KVM_IRQ_LINE		  _IOW(KVMIO, 0x61, struct kvm_irq_level)
-- 
1.5.4.5


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 2/2][v2] kvm: allow qemu to set EPT identity mapping address
  2009-07-21  2:42 [PATCH 1/2][v2] KVM: Introduce KVM_SET_IDENTITY_MAP_ADDR ioctl Sheng Yang
@ 2009-07-21  2:42 ` Sheng Yang
  2009-07-21 16:50 ` [PATCH 1/2][v2] KVM: Introduce KVM_SET_IDENTITY_MAP_ADDR ioctl Marcelo Tosatti
  1 sibling, 0 replies; 3+ messages in thread
From: Sheng Yang @ 2009-07-21  2:42 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: kvm, Avi Kivity, Sheng Yang

If we use larger BIOS image than current 256KB, we would need move reserved
TSS and EPT identity mapping pages. Currently TSS support this, but not
EPT.

(change from v1, use parameter address instead of value for ioctl)

Signed-off-by: Sheng Yang <sheng@linux.intel.com>
---
 kvm/include/linux/kvm.h |    2 ++
 qemu-kvm-x86.c          |   45 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 47 insertions(+), 0 deletions(-)

diff --git a/kvm/include/linux/kvm.h b/kvm/include/linux/kvm.h
index 790601d..079df62 100644
--- a/kvm/include/linux/kvm.h
+++ b/kvm/include/linux/kvm.h
@@ -465,6 +465,7 @@ struct kvm_trace_rec {
 #define KVM_CAP_JOIN_MEMORY_REGIONS_WORKS 30
 #define KVM_CAP_PIT2 33
 #define KVM_CAP_PIT_STATE2 35
+#define KVM_CAP_SET_IDENTITY_MAP_ADDR 37
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -513,6 +514,7 @@ struct kvm_irq_routing {
 #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 _IOW(KVMIO, 0x48, __u64)
 /*
  * KVM_CREATE_VCPU receives as a parameter the vcpu slot, and returns
  * a vcpu fd.
diff --git a/qemu-kvm-x86.c b/qemu-kvm-x86.c
index daf60b6..0e17ac8 100644
--- a/qemu-kvm-x86.c
+++ b/qemu-kvm-x86.c
@@ -74,6 +74,47 @@ static int kvm_init_tss(kvm_context_t kvm)
 	return 0;
 }
 
+static int kvm_set_identity_map_addr(kvm_context_t kvm, unsigned long addr)
+{
+#ifdef KVM_CAP_SET_IDENTITY_MAP_ADDR
+	int r;
+
+	r = ioctl(kvm->fd, KVM_CHECK_EXTENSION, KVM_CAP_SET_IDENTITY_MAP_ADDR);
+	if (r > 0) {
+		r = ioctl(kvm->vm_fd, KVM_SET_IDENTITY_MAP_ADDR, &addr);
+		if (r == -1) {
+			fprintf(stderr, "kvm_set_identity_map_addr: %m\n");
+			return -errno;
+		}
+		return 0;
+	}
+#endif
+	return -ENOSYS;
+}
+
+static int kvm_init_identity_map_page(kvm_context_t kvm)
+{
+#ifdef KVM_CAP_SET_IDENTITY_MAP_ADDR
+	int r;
+
+	r = ioctl(kvm->fd, KVM_CHECK_EXTENSION, KVM_CAP_SET_IDENTITY_MAP_ADDR);
+	if (r > 0) {
+		/*
+		 * this address is 4 pages before the bios, and the bios should present
+		 * as unavaible memory
+		 */
+		r = kvm_set_identity_map_addr(kvm, 0xfffbc000);
+		if (r < 0) {
+			fprintf(stderr, "kvm_init_identity_map_page: "
+				"unable to set identity mapping addr\n");
+			return r;
+		}
+
+	}
+#endif
+	return 0;
+}
+
 static int kvm_create_pit(kvm_context_t kvm)
 {
 #ifdef KVM_CAP_PIT
@@ -105,6 +146,10 @@ int kvm_arch_create(kvm_context_t kvm, unsigned long phys_mem_bytes,
 	if (r < 0)
 		return r;
 
+	r = kvm_init_identity_map_page(kvm);
+	if (r < 0)
+		return r;
+
 	r = kvm_create_pit(kvm);
 	if (r < 0)
 		return r;
-- 
1.5.4.5


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH 1/2][v2] KVM: Introduce KVM_SET_IDENTITY_MAP_ADDR ioctl
  2009-07-21  2:42 [PATCH 1/2][v2] KVM: Introduce KVM_SET_IDENTITY_MAP_ADDR ioctl Sheng Yang
  2009-07-21  2:42 ` [PATCH 2/2][v2] kvm: allow qemu to set EPT identity mapping address Sheng Yang
@ 2009-07-21 16:50 ` Marcelo Tosatti
  1 sibling, 0 replies; 3+ messages in thread
From: Marcelo Tosatti @ 2009-07-21 16:50 UTC (permalink / raw)
  To: Sheng Yang; +Cc: kvm, Avi Kivity

On Tue, Jul 21, 2009 at 10:42:48AM +0800, Sheng Yang wrote:
> Now KVM allow guest to modify guest's physical address of EPT's identity mapping page.
> 
> (change from v1, discard unnecessary check, change ioctl to accept parameter
> address rather than value)
> 
> Signed-off-by: Sheng Yang <sheng@linux.intel.com>
> ---
>  arch/x86/include/asm/kvm_host.h |    1 +
>  arch/x86/kvm/vmx.c              |   13 +++++++++----
>  arch/x86/kvm/x86.c              |   19 +++++++++++++++++++
>  include/linux/kvm.h             |    2 ++
>  4 files changed, 31 insertions(+), 4 deletions(-)

Applied both, thanks.


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2009-07-21 17:11 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-07-21  2:42 [PATCH 1/2][v2] KVM: Introduce KVM_SET_IDENTITY_MAP_ADDR ioctl Sheng Yang
2009-07-21  2:42 ` [PATCH 2/2][v2] kvm: allow qemu to set EPT identity mapping address Sheng Yang
2009-07-21 16:50 ` [PATCH 1/2][v2] KVM: Introduce KVM_SET_IDENTITY_MAP_ADDR ioctl Marcelo Tosatti

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox