From: Peter Dinda Date: Mon, 26 May 2014 21:15:24 +0000 (-0500) Subject: Convert shadow paging to use 32 PAE (VMX) X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=a7cacea293dbc2fbbbe36421054eff95f88390d4 Convert shadow paging to use 32 PAE (VMX) This changes shadow paging to use, at minimum, 32PAE shadow page tables. This makes it possible to place a guest using shadow paging anywhere in host physical memory instead of just the first 4 GB This patch adds support to VMX for this functionality: - cr4 is read-shadowed to the shadow pager's guest cr4 - PAE is forced on - vmx assist does not overwrite cr4 control, just masks it - cleaner activation of passthrough PTs Note that this is able to boot a BOCHS BIOS and a Linux guest. It fails to boot the SEABIOS (Trap 0x8), but then that bug is confirmed to be independent of these patches. --- diff --git a/palacios/src/palacios/vmcs.c b/palacios/src/palacios/vmcs.c index 2e4dcf3..4262aa8 100644 --- a/palacios/src/palacios/vmcs.c +++ b/palacios/src/palacios/vmcs.c @@ -228,7 +228,7 @@ int v3_vmx_save_vmcs(struct guest_info * info) { check_vmcs_read(VMCS_CR0_READ_SHDW, &(info->shdw_pg_state.guest_cr0)); check_vmcs_read(VMCS_GUEST_CR3, &(info->ctrl_regs.cr3)); check_vmcs_read(VMCS_GUEST_CR4, &(info->ctrl_regs.cr4)); - check_vmcs_read(VMCS_CR4_READ_SHDW, &(vmx_info->guest_cr4)); + check_vmcs_read(VMCS_CR4_READ_SHDW, &(info->shdw_pg_state.guest_cr4)); check_vmcs_read(VMCS_GUEST_DR7, &(info->dbg_regs.dr7)); check_vmcs_read(VMCS_GUEST_RFLAGS, &(info->ctrl_regs.rflags)); diff --git a/palacios/src/palacios/vmx.c b/palacios/src/palacios/vmx.c index de81dfc..aba80c7 100644 --- a/palacios/src/palacios/vmx.c +++ b/palacios/src/palacios/vmx.c @@ -270,16 +270,19 @@ static int init_vmcs_bios(struct guest_info * core, struct vmx_data * vmx_state) // Cause VM_EXIT whenever CR4.VMXE or CR4.PAE bits are written - vmx_ret |= check_vmcs_write(VMCS_CR4_MASK, CR4_VMXE | CR4_PAE); + vmx_ret |= check_vmcs_write(VMCS_CR4_MASK, CR4_VMXE | CR4_PAE ); - core->ctrl_regs.cr3 = core->direct_map_pt; + v3_activate_passthrough_pt(core); // vmx_state->pinbased_ctrls |= NMI_EXIT; /* Add CR exits */ vmx_state->pri_proc_ctrls.cr3_ld_exit = 1; vmx_state->pri_proc_ctrls.cr3_str_exit = 1; - + + // Note that we intercept cr4.pae writes + // and we have cr4 read-shadowed to the shadow pager's cr4 + vmx_state->pri_proc_ctrls.invlpg_exit = 1; /* Add page fault exits */ diff --git a/palacios/src/palacios/vmx_assist.c b/palacios/src/palacios/vmx_assist.c index 3e1f7a7..fa67d97 100644 --- a/palacios/src/palacios/vmx_assist.c +++ b/palacios/src/palacios/vmx_assist.c @@ -248,10 +248,10 @@ int v3_vmxassist_init(struct guest_info * core, struct vmx_data * vmx_state) { core->vm_regs.rsp = 0x80000; ((struct rflags *)&(core->ctrl_regs.rflags))->rsvd1 = 1; -#define GUEST_CR0 0x80010031 -#define GUEST_CR4 0x00002010 - core->ctrl_regs.cr0 = GUEST_CR0; - core->ctrl_regs.cr4 = GUEST_CR4; +#define GUEST_CR0_MASK 0x80010031 +#define GUEST_CR4_MASK 0x00002010 + core->ctrl_regs.cr0 |= GUEST_CR0_MASK; + core->ctrl_regs.cr4 |= GUEST_CR4_MASK; ((struct cr0_32 *)&(core->shdw_pg_state.guest_cr0))->pe = 1; ((struct cr0_32 *)&(core->shdw_pg_state.guest_cr0))->wp = 1;