ia64/xen-unstable
changeset 9428:951ed0cd0480
Merged.
author | emellor@leeni.uk.xensource.com |
---|---|
date | Thu Mar 23 12:59:50 2006 +0100 (2006-03-23) |
parents | da24df1ea484 0c6534a2e396 |
children | a594a5b2407c |
files |
line diff
1.1 --- a/xen/arch/x86/hvm/vmx/vmx.c Thu Mar 23 12:59:43 2006 +0100 1.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c Thu Mar 23 12:59:50 2006 +0100 1.3 @@ -1308,7 +1308,8 @@ static int vmx_set_cr0(unsigned long val 1.4 vm_entry_value |= VM_ENTRY_CONTROLS_IA32E_MODE; 1.5 __vmwrite(VM_ENTRY_CONTROLS, vm_entry_value); 1.6 1.7 - if ( !shadow_set_guest_paging_levels(v->domain, 4) ) { 1.8 + if ( !shadow_set_guest_paging_levels(v->domain, PAGING_L4) ) 1.9 + { 1.10 printk("Unsupported guest paging levels\n"); 1.11 domain_crash_synchronous(); /* need to take a clean path */ 1.12 } 1.13 @@ -1317,9 +1318,26 @@ static int vmx_set_cr0(unsigned long val 1.14 #endif /* __x86_64__ */ 1.15 { 1.16 #if CONFIG_PAGING_LEVELS >= 3 1.17 - if ( !shadow_set_guest_paging_levels(v->domain, 2) ) { 1.18 - printk("Unsupported guest paging levels\n"); 1.19 - domain_crash_synchronous(); /* need to take a clean path */ 1.20 + /* seems it's a 32-bit or 32-bit PAE guest */ 1.21 + 1.22 + if ( test_bit(VMX_CPU_STATE_PAE_ENABLED, 1.23 + &v->arch.hvm_vmx.cpu_state) ) 1.24 + { 1.25 + /* The guest enables PAE first and then it enables PG, it is 1.26 + * really a PAE guest */ 1.27 + if ( !shadow_set_guest_paging_levels(v->domain, PAGING_L3) ) 1.28 + { 1.29 + printk("Unsupported guest paging levels\n"); 1.30 + domain_crash_synchronous(); 1.31 + } 1.32 + } 1.33 + else 1.34 + { 1.35 + if ( !shadow_set_guest_paging_levels(v->domain, PAGING_L2) ) 1.36 + { 1.37 + printk("Unsupported guest paging levels\n"); 1.38 + domain_crash_synchronous(); /* need to take a clean path */ 1.39 + } 1.40 } 1.41 #endif 1.42 } 1.43 @@ -1399,6 +1417,12 @@ static int vmx_set_cr0(unsigned long val 1.44 return 0; /* do not update eip! */ 1.45 } 1.46 } 1.47 + else if ( (value & (X86_CR0_PE | X86_CR0_PG)) == X86_CR0_PE ) 1.48 + { 1.49 + /* we should take care of this kind of situation */ 1.50 + clear_all_shadow_status(v->domain); 1.51 + __vmwrite(GUEST_CR3, pagetable_get_paddr(v->domain->arch.phys_table)); 1.52 + } 1.53 1.54 return 1; 1.55 } 1.56 @@ -1528,11 +1552,11 @@ static int mov_to_cr(int gp, int cr, str 1.57 1.58 if ( vmx_pgbit_test(v) ) 1.59 { 1.60 - /* The guest is 32 bit. */ 1.61 + /* The guest is a 32-bit PAE guest. */ 1.62 #if CONFIG_PAGING_LEVELS >= 4 1.63 unsigned long mfn, old_base_mfn; 1.64 1.65 - if( !shadow_set_guest_paging_levels(v->domain, 3) ) 1.66 + if( !shadow_set_guest_paging_levels(v->domain, PAGING_L3) ) 1.67 { 1.68 printk("Unsupported guest paging levels\n"); 1.69 domain_crash_synchronous(); /* need to take a clean path */ 1.70 @@ -1572,12 +1596,31 @@ static int mov_to_cr(int gp, int cr, str 1.71 } 1.72 else 1.73 { 1.74 - /* The guest is 64 bit. */ 1.75 + /* The guest is a 64 bit or 32-bit PAE guest. */ 1.76 #if CONFIG_PAGING_LEVELS >= 4 1.77 - if ( !shadow_set_guest_paging_levels(v->domain, 4) ) 1.78 + if ( (v->domain->arch.ops != NULL) && 1.79 + v->domain->arch.ops->guest_paging_levels == PAGING_L2) 1.80 { 1.81 - printk("Unsupported guest paging levels\n"); 1.82 - domain_crash_synchronous(); /* need to take a clean path */ 1.83 + /* Seems the guest first enables PAE without enabling PG, 1.84 + * it must enable PG after that, and it is a 32-bit PAE 1.85 + * guest */ 1.86 + 1.87 + if ( !shadow_set_guest_paging_levels(v->domain, 1.88 + PAGING_L3) ) 1.89 + { 1.90 + printk("Unsupported guest paging levels\n"); 1.91 + /* need to take a clean path */ 1.92 + domain_crash_synchronous(); 1.93 + } 1.94 + } 1.95 + else 1.96 + { 1.97 + if ( !shadow_set_guest_paging_levels(v->domain, 1.98 + PAGING_L4) ) 1.99 + { 1.100 + printk("Unsupported guest paging levels\n"); 1.101 + domain_crash_synchronous(); 1.102 + } 1.103 } 1.104 #endif 1.105 }