From: Arun Sharma <arun.sharma@intel.com>
To: Ian Pratt <Ian.Pratt@cl.cam.ac.uk>,
Keir Fraser <Keir.Fraser@cl.cam.ac.uk>
Cc: xen-devel@lists.xensource.com
Subject: [PATCH] vmx-worldswitch-1-to-1.patch
Date: Fri, 27 May 2005 12:35:25 -0700 [thread overview]
Message-ID: <20050527193525.GA13773@intel.com> (raw)
Fix VMX world switch to use 1:1 page tables when the guest has paging
disabled. Also do a printk instead of VMX_DBG_LOG() anytime we crash
a domain.
Signed-off-by: Arun Sharma <arun.sharma@intel.com>
--- 1.27/tools/libxc/xc_vmx_build.c 2005-05-24 13:32:29 -07:00
+++ edited/tools/libxc/xc_vmx_build.c 2005-05-27 12:02:08 -07:00
@@ -10,7 +10,7 @@
#include <zlib.h>
#include "linux_boot_params.h"
-#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
+#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER)
#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
#define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
===== xen/arch/x86/domain.c 1.200 vs edited =====
--- 1.200/xen/arch/x86/domain.c 2005-05-25 03:36:57 -07:00
+++ edited/xen/arch/x86/domain.c 2005-05-27 12:02:09 -07:00
@@ -339,7 +339,6 @@
}
ed->arch.schedule_tail = arch_vmx_do_launch;
- clear_bit(VMX_CPU_STATE_PG_ENABLED, &ed->arch.arch_vmx.cpu_state);
#if defined (__i386)
ed->arch.arch_vmx.vmx_platform.real_mode_data =
===== xen/arch/x86/vmx.c 1.58 vs edited =====
--- 1.58/xen/arch/x86/vmx.c 2005-05-26 19:36:15 -07:00
+++ edited/xen/arch/x86/vmx.c 2005-05-27 12:27:13 -07:00
@@ -122,7 +122,6 @@
static int vmx_do_page_fault(unsigned long va, struct cpu_user_regs *regs)
{
- struct exec_domain *ed = current;
unsigned long eip;
l1_pgentry_t gpte;
unsigned long gpa; /* FIXME: PAE */
@@ -137,15 +136,8 @@
}
#endif
- /*
- * If vpagetable is zero, then we are still emulating 1:1 page tables,
- * and we should have never gotten here.
- */
- if ( !test_bit(VMX_CPU_STATE_PG_ENABLED, &ed->arch.arch_vmx.cpu_state) )
- {
- printk("vmx_do_page_fault while running on 1:1 page table\n");
- return 0;
- }
+ if (!vmx_paging_enabled(current))
+ handle_mmio(va, va);
gpte = gva_to_gpte(va);
if (!(l1e_get_flags(gpte) & _PAGE_PRESENT) )
@@ -399,7 +391,7 @@
vio = (vcpu_iodata_t *) d->arch.arch_vmx.vmx_platform.shared_page_va;
if (vio == 0) {
- VMX_DBG_LOG(DBG_LEVEL_1, "bad shared page: %lx", (unsigned long) vio);
+ printk("bad shared page: %lx", (unsigned long) vio);
domain_crash_synchronous();
}
p = &vio->vp_ioreq;
@@ -423,7 +415,10 @@
laddr = (p->dir == IOREQ_WRITE) ? regs->esi : regs->edi;
}
p->pdata_valid = 1;
- p->u.pdata = (void *) gva_to_gpa(laddr);
+
+ p->u.data = laddr;
+ if (vmx_paging_enabled(d))
+ p->u.pdata = (void *) gva_to_gpa(p->u.data);
p->df = (eflags & X86_EFLAGS_DF) ? 1 : 0;
if (test_bit(5, &exit_qualification)) /* "rep" prefix */
@@ -481,7 +476,7 @@
return 0;
}
- mfn = phys_to_machine_mapping(l1e_get_pfn(gva_to_gpte(laddr)));
+ mfn = phys_to_machine_mapping(laddr >> PAGE_SHIFT);
addr = map_domain_mem((mfn << PAGE_SHIFT) | (laddr & ~PAGE_MASK));
if (dir == COPY_IN)
@@ -570,6 +565,12 @@
error |= __vmwrite(CR0_READ_SHADOW, c->cr0);
+ if (!vmx_paging_enabled(d)) {
+ VMX_DBG_LOG(DBG_LEVEL_VMMU, "switching to vmxassist. use phys table");
+ __vmwrite(GUEST_CR3, pagetable_val(d->domain->arch.phys_table));
+ goto skip_cr3;
+ }
+
if (c->cr3 == d->arch.arch_vmx.cpu_cr3) {
/*
* This is simple TLB flush, implying the guest has
@@ -578,7 +579,7 @@
*/
mfn = phys_to_machine_mapping(c->cr3 >> PAGE_SHIFT);
if ((mfn << PAGE_SHIFT) != pagetable_val(d->arch.guest_table)) {
- VMX_DBG_LOG(DBG_LEVEL_VMMU, "Invalid CR3 value=%lx", c->cr3);
+ printk("Invalid CR3 value=%lx", c->cr3);
domain_crash_synchronous();
return 0;
}
@@ -590,7 +591,7 @@
*/
VMX_DBG_LOG(DBG_LEVEL_VMMU, "CR3 c->cr3 = %lx", c->cr3);
if ((c->cr3 >> PAGE_SHIFT) > d->domain->max_pages) {
- VMX_DBG_LOG(DBG_LEVEL_VMMU, "Invalid CR3 value=%lx", c->cr3);
+ printk("Invalid CR3 value=%lx", c->cr3);
domain_crash_synchronous();
return 0;
}
@@ -605,6 +606,8 @@
__vmwrite(GUEST_CR3, pagetable_val(d->arch.shadow_table));
}
+skip_cr3:
+
error |= __vmread(CR4_READ_SHADOW, &old_cr4);
error |= __vmwrite(GUEST_CR4, (c->cr4 | X86_CR4_VMXE));
error |= __vmwrite(CR4_READ_SHADOW, c->cr4);
@@ -731,18 +734,18 @@
struct exec_domain *d = current;
unsigned long old_base_mfn, mfn;
unsigned long eip;
+ int paging_enabled;
/*
* CR0: We don't want to lose PE and PG.
*/
+ paging_enabled = vmx_paging_enabled(d);
__vmwrite(GUEST_CR0, (value | X86_CR0_PE | X86_CR0_PG));
+ __vmwrite(CR0_READ_SHADOW, value);
- if (value & (X86_CR0_PE | X86_CR0_PG) &&
- !test_bit(VMX_CPU_STATE_PG_ENABLED, &d->arch.arch_vmx.cpu_state)) {
- /*
- * Enable paging
- */
- set_bit(VMX_CPU_STATE_PG_ENABLED, &d->arch.arch_vmx.cpu_state);
+ VMX_DBG_LOG(DBG_LEVEL_VMMU, "Update CR0 value = %lx\n", value);
+ if ((value & X86_CR0_PE) && (value & X86_CR0_PG)
+ && !paging_enabled) {
/*
* The guest CR3 must be pointing to the guest physical.
*/
@@ -750,8 +753,7 @@
d->arch.arch_vmx.cpu_cr3 >> PAGE_SHIFT)) ||
!get_page(pfn_to_page(mfn), d->domain) )
{
- VMX_DBG_LOG(DBG_LEVEL_VMMU, "Invalid CR3 value = %lx",
- d->arch.arch_vmx.cpu_cr3);
+ printk("Invalid CR3 value = %lx", d->arch.arch_vmx.cpu_cr3);
domain_crash_synchronous(); /* need to take a clean path */
}
old_base_mfn = pagetable_get_pfn(d->arch.guest_table);
@@ -776,8 +778,7 @@
} else {
if ((value & X86_CR0_PE) == 0) {
__vmread(GUEST_EIP, &eip);
- VMX_DBG_LOG(DBG_LEVEL_1,
- "Disabling CR0.PE at %%eip 0x%lx", eip);
+ VMX_DBG_LOG(DBG_LEVEL_1, "Disabling CR0.PE at %%eip 0x%lx\n", eip);
if (vmx_assist(d, VMX_ASSIST_INVOKE)) {
set_bit(VMX_CPU_STATE_ASSIST_ENABLED,
&d->arch.arch_vmx.cpu_state);
@@ -838,7 +839,6 @@
switch(cr) {
case 0:
{
- __vmwrite(CR0_READ_SHADOW, value);
return vmx_set_cr0(value);
}
case 3:
@@ -848,7 +848,7 @@
/*
* If paging is not enabled yet, simply copy the value to CR3.
*/
- if (!test_bit(VMX_CPU_STATE_PG_ENABLED, &d->arch.arch_vmx.cpu_state)) {
+ if (!vmx_paging_enabled(d)) {
d->arch.arch_vmx.cpu_cr3 = value;
break;
}
@@ -876,8 +876,7 @@
!VALID_MFN(mfn = phys_to_machine_mapping(value >> PAGE_SHIFT)) ||
!get_page(pfn_to_page(mfn), d->domain) )
{
- VMX_DBG_LOG(DBG_LEVEL_VMMU,
- "Invalid CR3 value=%lx", value);
+ printk("Invalid CR3 value=%lx", value);
domain_crash_synchronous(); /* need to take a clean path */
}
old_base_mfn = pagetable_get_pfn(d->arch.guest_table);
@@ -1133,6 +1131,7 @@
VMX_DBG_LOG(DBG_LEVEL_0, "exit reason = %x", exit_reason);
if (exit_reason & VMX_EXIT_REASONS_FAILED_VMENTRY) {
+ printk("Failed vm entry\n");
domain_crash_synchronous();
return;
}
===== xen/arch/x86/vmx_io.c 1.24 vs edited =====
--- 1.24/xen/arch/x86/vmx_io.c 2005-05-16 01:41:48 -07:00
+++ edited/xen/arch/x86/vmx_io.c 2005-05-27 12:02:09 -07:00
@@ -430,7 +430,7 @@
void vmx_do_resume(struct exec_domain *d)
{
vmx_stts();
- if ( test_bit(VMX_CPU_STATE_PG_ENABLED, &d->arch.arch_vmx.cpu_state) )
+ if ( vmx_paging_enabled(d) )
__vmwrite(GUEST_CR3, pagetable_val(d->arch.shadow_table));
else
// paging is not enabled in the guest
===== xen/arch/x86/vmx_platform.c 1.19 vs edited =====
--- 1.19/xen/arch/x86/vmx_platform.c 2005-05-26 20:16:05 -07:00
+++ edited/xen/arch/x86/vmx_platform.c 2005-05-27 12:02:09 -07:00
@@ -418,8 +418,12 @@
}
if ((guest_eip & PAGE_MASK) == ((guest_eip + inst_len) & PAGE_MASK)) {
- gpte = gva_to_gpte(guest_eip);
- mfn = phys_to_machine_mapping(l1e_get_pfn(gpte));
+ if (vmx_paging_enabled(current)) {
+ gpte = gva_to_gpte(guest_eip);
+ mfn = phys_to_machine_mapping(l1e_get_pfn(gpte));
+ } else {
+ mfn = phys_to_machine_mapping(guest_eip >> PAGE_SHIFT);
+ }
ma = (mfn << PAGE_SHIFT) | (guest_eip & (PAGE_SIZE - 1));
inst_start = (unsigned char *)map_domain_mem(ma);
@@ -509,7 +513,7 @@
} else
p->count = 1;
- if (pvalid)
+ if ((pvalid) && vmx_paging_enabled(current))
p->u.pdata = (void *) gva_to_gpa(p->u.data);
#if 0
===== xen/arch/x86/vmx_vmcs.c 1.25 vs edited =====
--- 1.25/xen/arch/x86/vmx_vmcs.c 2005-05-20 15:28:11 -07:00
+++ edited/xen/arch/x86/vmx_vmcs.c 2005-05-27 12:27:14 -07:00
@@ -291,7 +291,7 @@
/* Initally PG, PE are not set*/
shadow_cr = host_env->cr0;
- shadow_cr &= ~(X86_CR0_PE | X86_CR0_PG);
+ shadow_cr &= ~X86_CR0_PG;
error |= __vmwrite(CR0_READ_SHADOW, shadow_cr);
/* CR3 is set in vmx_final_setup_guest */
error |= __vmwrite(GUEST_CR4, host_env->cr4);
===== xen/arch/x86/x86_32/traps.c 1.27 vs edited =====
--- 1.27/xen/arch/x86/x86_32/traps.c 2005-05-21 03:41:05 -07:00
+++ edited/xen/arch/x86/x86_32/traps.c 2005-05-27 12:02:09 -07:00
@@ -20,8 +20,9 @@
unsigned long ss, ds, es, fs, gs, cs;
unsigned long eip, esp, eflags;
const char *context;
-
#ifdef CONFIG_VMX
+ unsigned long cr0, cr3;
+
if ( VMX_DOMAIN(current) && (regs->eflags == 0) )
{
__vmread(GUEST_EIP, &eip);
@@ -33,6 +34,8 @@
__vmread(GUEST_FS_SELECTOR, &fs);
__vmread(GUEST_GS_SELECTOR, &gs);
__vmread(GUEST_CS_SELECTOR, &cs);
+ __vmread(CR0_READ_SHADOW, &cr0);
+ __vmread(GUEST_CR3, &cr3);
context = "vmx guest";
}
else
@@ -77,6 +80,9 @@
printk("ds: %04lx es: %04lx fs: %04lx gs: %04lx "
"ss: %04lx cs: %04lx\n",
ds, es, fs, gs, ss, cs);
+#ifdef CONFIG_VMX
+ printk("cr0: %08lx cr3: %08lx\n", cr0, cr3);
+#endif
if ( GUEST_MODE(regs) )
show_guest_stack();
===== xen/include/asm-x86/shadow.h 1.97 vs edited =====
--- 1.97/xen/include/asm-x86/shadow.h 2005-05-25 10:29:18 -07:00
+++ edited/xen/include/asm-x86/shadow.h 2005-05-27 12:02:11 -07:00
@@ -31,6 +31,9 @@
#include <asm/processor.h>
#include <asm/domain_page.h>
#include <public/dom0_ops.h>
+#ifdef CONFIG_VMX
+#include <asm/vmx.h>
+#endif
/* Shadow PT operation mode : shadow-mode variable in arch_domain. */
@@ -1672,8 +1675,8 @@
#ifdef CONFIG_VMX
if ( VMX_DOMAIN(ed) )
- paging_enabled =
- test_bit(VMX_CPU_STATE_PG_ENABLED, &ed->arch.arch_vmx.cpu_state);
+ paging_enabled = vmx_paging_enabled(ed);
+
else
#endif
// HACK ALERT: there's currently no easy way to figure out if a domU
===== xen/include/asm-x86/vmx.h 1.8 vs edited =====
--- 1.8/xen/include/asm-x86/vmx.h 2005-05-17 15:28:11 -07:00
+++ edited/xen/include/asm-x86/vmx.h 2005-05-27 12:02:11 -07:00
@@ -294,5 +294,14 @@
if (!(cr0 & X86_CR0_TS))
__vm_set_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_NM);
}
-
+
+/* Works only for ed == current */
+static inline int vmx_paging_enabled(struct exec_domain *ed)
+{
+ unsigned long cr0;
+
+ __vmread(CR0_READ_SHADOW, &cr0);
+ return (cr0 & X86_CR0_PE) && (cr0 & X86_CR0_PG);
+}
+
#endif /* __ASM_X86_VMX_H__ */
===== xen/include/asm-x86/vmx_vmcs.h 1.11 vs edited =====
--- 1.11/xen/include/asm-x86/vmx_vmcs.h 2005-05-26 20:16:05 -07:00
+++ edited/xen/include/asm-x86/vmx_vmcs.h 2005-05-27 12:02:11 -07:00
@@ -29,7 +29,6 @@
void vmx_enter_scheduler(void);
-#define VMX_CPU_STATE_PG_ENABLED 0
#define VMX_CPU_STATE_ASSIST_ENABLED 1
struct vmcs_struct {
reply other threads:[~2005-05-27 19:35 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=20050527193525.GA13773@intel.com \
--to=arun.sharma@intel.com \
--cc=Ian.Pratt@cl.cam.ac.uk \
--cc=Keir.Fraser@cl.cam.ac.uk \
--cc=xen-devel@lists.xensource.com \
/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.