From: "Yang, Sheng" <sheng.yang@intel.com>
To: Avi Kivity <avi@qumranet.com>
Cc: kvm-devel@lists.sourceforge.net
Subject: Re: [PATCH 6/6] kvm: qemu: Enable EPT support for real mode
Date: Thu, 24 Apr 2008 14:59:09 +0800 [thread overview]
Message-ID: <200804241459.09523.sheng.yang@intel.com> (raw)
In-Reply-To: <480DBB09.5070801@qumranet.com>
[-- Attachment #1: Type: text/plain, Size: 6016 bytes --]
On Tuesday 22 April 2008 18:16:41 Avi Kivity wrote:
> Yang, Sheng wrote:
> > From 73c33765f3d879001818cd0719038c78a0c65561 Mon Sep 17 00:00:00 2001
> > From: Sheng Yang <sheng.yang@intel.com>
> > Date: Fri, 18 Apr 2008 17:15:39 +0800
> > Subject: [PATCH] kvm: qemu: Enable EPT support for real mode
> >
> > This patch build a identity page table on the last page of VGA bios, and
> > use it as the guest page table in nonpaging mode for EPT.
>
> Doing this in qemu means older versions of qemu can't work with an
> ept-enabled kernel. Also, placing the table in the vga bios might
> conflict with video card assignment to a guest.
>
> Suggest placing this near the realmode tss (see vmx.c:init_rmode_tss())
> which serves a similar function.
Something like this? (along with one page reserved in e820 table)
I put the page it into 0xfffbc000 now. But I think the following implement is
not very elegant... Too complex compared to the qemu one.
BTW: The S/R and live migration problem was fixed.
From b1836738e82ed416c8fb43cffd85b3d17ab10260 Mon Sep 17 00:00:00 2001
From: Sheng Yang <sheng.yang@intel.com>
Date: Thu, 24 Apr 2008 14:23:50 +0800
Subject: [PATCH] KVM: VMX: Perpare a identity page table for EPT in real mode
Signed-off-by: Sheng Yang <sheng.yang@intel.com>
---
arch/x86/kvm/vmx.c | 75
++++++++++++++++++++++++++++++++++++++++++--
arch/x86/kvm/vmx.h | 3 ++
include/asm-x86/kvm_host.h | 3 ++
3 files changed, 78 insertions(+), 3 deletions(-)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 588b9ea..b19b2b2 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -87,7 +87,7 @@ static inline struct vcpu_vmx *to_vmx(struct kvm_vcpu *vcpu)
return container_of(vcpu, struct vcpu_vmx, vcpu);
}
-static int init_rmode_tss(struct kvm *kvm);
+static int init_rmode(struct kvm *kvm);
static DEFINE_PER_CPU(struct vmcs *, vmxarea);
static DEFINE_PER_CPU(struct vmcs *, current_vmcs);
@@ -1345,7 +1345,7 @@ static void enter_rmode(struct kvm_vcpu *vcpu)
fix_rmode_seg(VCPU_SREG_FS, &vcpu->arch.rmode.fs);
kvm_mmu_reset_context(vcpu);
- init_rmode_tss(vcpu->kvm);
+ init_rmode(vcpu->kvm);
}
#ifdef CONFIG_X86_64
@@ -1707,6 +1707,37 @@ out:
return ret;
}
+static int init_rmode_identity_map(struct kvm *kvm)
+{
+ int i, r, ret;
+ pfn_t identity_map_pfn;
+ u32 table[PT32_ENT_PER_PAGE];
+
+ if (kvm->arch.ept_identity_pagetable_done)
+ return 1;
+ ret = 0;
+ identity_map_pfn = VMX_EPT_IDENTITY_PAGETABLE_ADDR >> PAGE_SHIFT;
+ r = kvm_clear_guest_page(kvm, identity_map_pfn, 0, PAGE_SIZE);
+ if (r < 0)
+ goto out;
+ /*
+ * Set up identity-mapping pagetable for EPT in real mode, also verify
+ * the contain of page
+ * 0xe7 = _PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED |
+ * _PAGE_DIRTY | _PAGE_PSE
+ */
+ for (i = 0; i < PT32_ENT_PER_PAGE; i++)
+ table[i] = (i << 22) + 0xe7;
+ r = kvm_write_guest_page(kvm, identity_map_pfn,
+ table, 0, PAGE_SIZE);
+ if (r < 0)
+ goto out;
+ kvm->arch.ept_identity_pagetable_done = true;
+ ret = 1;
+out:
+ return ret;
+}
+
static void seg_setup(int seg)
{
struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
@@ -1741,6 +1772,31 @@ out:
return r;
}
+static int alloc_identity_pagetable(struct kvm *kvm)
+{
+ struct kvm_userspace_memory_region kvm_userspace_mem;
+ int r = 0;
+
+ down_write(&kvm->slots_lock);
+ if (kvm->arch.ept_identity_pagetable)
+ 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.memory_size = PAGE_SIZE;
+ r = __kvm_set_memory_region(kvm, &kvm_userspace_mem, 0);
+ if (r)
+ goto out;
+
+ down_read(¤t->mm->mmap_sem);
+ kvm->arch.ept_identity_pagetable = gfn_to_page(kvm,
+ VMX_EPT_IDENTITY_PAGETABLE_ADDR >> PAGE_SHIFT);
+ up_read(¤t->mm->mmap_sem);
+out:
+ up_write(&kvm->slots_lock);
+ return r;
+}
+
static void allocate_vpid(struct vcpu_vmx *vmx)
{
int vpid;
@@ -1904,6 +1960,15 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
return 0;
}
+static int init_rmode(struct kvm *kvm)
+{
+ if (!init_rmode_tss(kvm))
+ return 0;
+ if (!init_rmode_identity_map(kvm))
+ return 0;
+ return 1;
+}
+
static int vmx_vcpu_reset(struct kvm_vcpu *vcpu)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
@@ -1911,7 +1976,7 @@ static int vmx_vcpu_reset(struct kvm_vcpu *vcpu)
int ret;
down_read(&vcpu->kvm->slots_lock);
- if (!init_rmode_tss(vmx->vcpu.kvm)) {
+ if (!init_rmode(vmx->vcpu.kvm)) {
ret = -ENOMEM;
goto out;
}
@@ -2967,6 +3032,10 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm
*kvm, unsigned int id)
if (alloc_apic_access_page(kvm) != 0)
goto free_vmcs;
+ if (vm_need_ept())
+ if (alloc_identity_pagetable(kvm) != 0)
+ goto free_vmcs;
+
return &vmx->vcpu;
free_vmcs:
diff --git a/arch/x86/kvm/vmx.h b/arch/x86/kvm/vmx.h
index 8f662e3..469a107 100644
--- a/arch/x86/kvm/vmx.h
+++ b/arch/x86/kvm/vmx.h
@@ -340,6 +340,7 @@ enum vmcs_field {
#define MSR_IA32_FEATURE_CONTROL_VMXON_ENABLED 0x4
#define APIC_ACCESS_PAGE_PRIVATE_MEMSLOT 9
+#define IDENTITY_PAGETABLE_PRIVATE_MEMSLOT 10
#define VMX_NR_VPIDS (1 << 16)
#define VMX_VPID_EXTENT_SINGLE_CONTEXT 1
@@ -362,4 +363,6 @@ enum vmcs_field {
#define VMX_EPT_FAKE_ACCESSED_MASK (1ul << 62)
#define VMX_EPT_FAKE_DIRTY_MASK (1ul << 63)
+#define VMX_EPT_IDENTITY_PAGETABLE_ADDR 0xfffbc000ul
+
#endif
diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h
index 003bc0e..69afbab 100644
--- a/include/asm-x86/kvm_host.h
+++ b/include/asm-x86/kvm_host.h
@@ -314,6 +314,9 @@ struct kvm_arch{
struct page *apic_access_page;
gpa_t wall_clock;
+
+ struct page *ept_identity_pagetable;
+ bool ept_identity_pagetable_done;
};
struct kvm_vm_stat {
--
1.5.4.5
[-- Attachment #2: 0001-KVM-VMX-Perpare-a-identity-page-table-for-EPT-in-r.patch --]
[-- Type: text/x-diff, Size: 5005 bytes --]
From b1836738e82ed416c8fb43cffd85b3d17ab10260 Mon Sep 17 00:00:00 2001
From: Sheng Yang <sheng.yang@intel.com>
Date: Thu, 24 Apr 2008 14:23:50 +0800
Subject: [PATCH] KVM: VMX: Perpare a identity page table for EPT in real mode
Signed-off-by: Sheng Yang <sheng.yang@intel.com>
---
arch/x86/kvm/vmx.c | 75 ++++++++++++++++++++++++++++++++++++++++++--
arch/x86/kvm/vmx.h | 3 ++
include/asm-x86/kvm_host.h | 3 ++
3 files changed, 78 insertions(+), 3 deletions(-)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 588b9ea..b19b2b2 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -87,7 +87,7 @@ static inline struct vcpu_vmx *to_vmx(struct kvm_vcpu *vcpu)
return container_of(vcpu, struct vcpu_vmx, vcpu);
}
-static int init_rmode_tss(struct kvm *kvm);
+static int init_rmode(struct kvm *kvm);
static DEFINE_PER_CPU(struct vmcs *, vmxarea);
static DEFINE_PER_CPU(struct vmcs *, current_vmcs);
@@ -1345,7 +1345,7 @@ static void enter_rmode(struct kvm_vcpu *vcpu)
fix_rmode_seg(VCPU_SREG_FS, &vcpu->arch.rmode.fs);
kvm_mmu_reset_context(vcpu);
- init_rmode_tss(vcpu->kvm);
+ init_rmode(vcpu->kvm);
}
#ifdef CONFIG_X86_64
@@ -1707,6 +1707,37 @@ out:
return ret;
}
+static int init_rmode_identity_map(struct kvm *kvm)
+{
+ int i, r, ret;
+ pfn_t identity_map_pfn;
+ u32 table[PT32_ENT_PER_PAGE];
+
+ if (kvm->arch.ept_identity_pagetable_done)
+ return 1;
+ ret = 0;
+ identity_map_pfn = VMX_EPT_IDENTITY_PAGETABLE_ADDR >> PAGE_SHIFT;
+ r = kvm_clear_guest_page(kvm, identity_map_pfn, 0, PAGE_SIZE);
+ if (r < 0)
+ goto out;
+ /*
+ * Set up identity-mapping pagetable for EPT in real mode, also verify
+ * the contain of page
+ * 0xe7 = _PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED |
+ * _PAGE_DIRTY | _PAGE_PSE
+ */
+ for (i = 0; i < PT32_ENT_PER_PAGE; i++)
+ table[i] = (i << 22) + 0xe7;
+ r = kvm_write_guest_page(kvm, identity_map_pfn,
+ table, 0, PAGE_SIZE);
+ if (r < 0)
+ goto out;
+ kvm->arch.ept_identity_pagetable_done = true;
+ ret = 1;
+out:
+ return ret;
+}
+
static void seg_setup(int seg)
{
struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
@@ -1741,6 +1772,31 @@ out:
return r;
}
+static int alloc_identity_pagetable(struct kvm *kvm)
+{
+ struct kvm_userspace_memory_region kvm_userspace_mem;
+ int r = 0;
+
+ down_write(&kvm->slots_lock);
+ if (kvm->arch.ept_identity_pagetable)
+ 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.memory_size = PAGE_SIZE;
+ r = __kvm_set_memory_region(kvm, &kvm_userspace_mem, 0);
+ if (r)
+ goto out;
+
+ down_read(¤t->mm->mmap_sem);
+ kvm->arch.ept_identity_pagetable = gfn_to_page(kvm,
+ VMX_EPT_IDENTITY_PAGETABLE_ADDR >> PAGE_SHIFT);
+ up_read(¤t->mm->mmap_sem);
+out:
+ up_write(&kvm->slots_lock);
+ return r;
+}
+
static void allocate_vpid(struct vcpu_vmx *vmx)
{
int vpid;
@@ -1904,6 +1960,15 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
return 0;
}
+static int init_rmode(struct kvm *kvm)
+{
+ if (!init_rmode_tss(kvm))
+ return 0;
+ if (!init_rmode_identity_map(kvm))
+ return 0;
+ return 1;
+}
+
static int vmx_vcpu_reset(struct kvm_vcpu *vcpu)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
@@ -1911,7 +1976,7 @@ static int vmx_vcpu_reset(struct kvm_vcpu *vcpu)
int ret;
down_read(&vcpu->kvm->slots_lock);
- if (!init_rmode_tss(vmx->vcpu.kvm)) {
+ if (!init_rmode(vmx->vcpu.kvm)) {
ret = -ENOMEM;
goto out;
}
@@ -2967,6 +3032,10 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
if (alloc_apic_access_page(kvm) != 0)
goto free_vmcs;
+ if (vm_need_ept())
+ if (alloc_identity_pagetable(kvm) != 0)
+ goto free_vmcs;
+
return &vmx->vcpu;
free_vmcs:
diff --git a/arch/x86/kvm/vmx.h b/arch/x86/kvm/vmx.h
index 8f662e3..469a107 100644
--- a/arch/x86/kvm/vmx.h
+++ b/arch/x86/kvm/vmx.h
@@ -340,6 +340,7 @@ enum vmcs_field {
#define MSR_IA32_FEATURE_CONTROL_VMXON_ENABLED 0x4
#define APIC_ACCESS_PAGE_PRIVATE_MEMSLOT 9
+#define IDENTITY_PAGETABLE_PRIVATE_MEMSLOT 10
#define VMX_NR_VPIDS (1 << 16)
#define VMX_VPID_EXTENT_SINGLE_CONTEXT 1
@@ -362,4 +363,6 @@ enum vmcs_field {
#define VMX_EPT_FAKE_ACCESSED_MASK (1ul << 62)
#define VMX_EPT_FAKE_DIRTY_MASK (1ul << 63)
+#define VMX_EPT_IDENTITY_PAGETABLE_ADDR 0xfffbc000ul
+
#endif
diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h
index 003bc0e..69afbab 100644
--- a/include/asm-x86/kvm_host.h
+++ b/include/asm-x86/kvm_host.h
@@ -314,6 +314,9 @@ struct kvm_arch{
struct page *apic_access_page;
gpa_t wall_clock;
+
+ struct page *ept_identity_pagetable;
+ bool ept_identity_pagetable_done;
};
struct kvm_vm_stat {
--
1.5.4.5
[-- Attachment #3: Type: text/plain, Size: 320 bytes --]
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
[-- Attachment #4: Type: text/plain, Size: 158 bytes --]
_______________________________________________
kvm-devel mailing list
kvm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-devel
next prev parent reply other threads:[~2008-04-24 6:59 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-04-18 9:30 [PATCH 6/6] kvm: qemu: Enable EPT support for real mode Yang, Sheng
2008-04-22 10:16 ` Avi Kivity
2008-04-24 6:59 ` Yang, Sheng [this message]
2008-04-24 7:15 ` Avi Kivity
2008-04-24 7:29 ` Yang, Sheng
2008-04-24 7:37 ` Avi Kivity
2008-04-24 7:57 ` Yang, Sheng
2008-04-24 7:59 ` Avi Kivity
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200804241459.09523.sheng.yang@intel.com \
--to=sheng.yang@intel.com \
--cc=avi@qumranet.com \
--cc=kvm-devel@lists.sourceforge.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.