[PATCH 2/2][v2] kvm: allow qemu to set EPT identity mapping address

Sheng Yang
2009-07-21T02:43:10Z

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