From: Andrew Cooper Date: Tue, 19 Jul 2016 13:51:30 +0000 (+0100) Subject: hvm: Honour test_wants_user_mappings X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=340f141f6ba8ca3a8c8ed69d371d631b77170833;p=xtf.git hvm: Honour test_wants_user_mappings Fewer tests overall need user mappings, so construct the identity pagetables without _PAGE_USER set in leaf entries by default. Before loading paging settings, check whether a test has opted-in to user mappings, and re-add _PAGE_USER to the l1 and l2 pagetable entries. Signed-off-by: Andrew Cooper --- diff --git a/arch/x86/boot/head_hvm.S b/arch/x86/boot/head_hvm.S index 3288216..1ffd918 100644 --- a/arch/x86/boot/head_hvm.S +++ b/arch/x86/boot/head_hvm.S @@ -29,6 +29,21 @@ GLOBAL(_start) /* HVM common setup. */ # error Bad paging mode #endif + /* Set _PAGE_USER on leaf mappings if a test wants them. */ + cmpb $0, test_wants_user_mappings + je .Lskip_user + + mov $l1_identmap, %edx + mov $l2_identmap_end, %ecx + sub %edx, %ecx + shr $PTE_ORDER, %ecx + add $PTE_SIZE, %edx /* Avoid setting _PAGE_USER in the NULL entry. */ +.Lnext_pte: + orb $_PAGE_USER, (%edx) + add $PTE_SIZE, %edx + loop .Lnext_pte +.Lskip_user: + mov %eax, %cr4 mov %ebx, %cr3 #endif /* CONFIG_PAGING_LEVELS > 0 */ diff --git a/arch/x86/hvm/pagetables.S b/arch/x86/hvm/pagetables.S index ffb94dc..44e3825 100644 --- a/arch/x86/hvm/pagetables.S +++ b/arch/x86/hvm/pagetables.S @@ -9,7 +9,9 @@ .type sym, STT_OBJECT; \ SIZE(sym) -#define PAGE_COMMON _PAGE_DIRTY + _PAGE_ACCESSED + _PAGE_USER + _PAGE_RW + _PAGE_PRESENT +#define _PAGE_LEAF (_PAGE_AD + _PAGE_RW + _PAGE_PRESENT) +#define _PAGE_SUPER (_PAGE_PSE + _PAGE_LEAF) +#define _PAGE_NONLEAF (_PAGE_USER + _PAGE_LEAF) #define PAE_IDX(sym) ((. - (sym)) / PAE_PTE_SIZE) #define PSE_IDX(sym) ((. - (sym)) / PSE_PTE_SIZE) @@ -21,25 +23,26 @@ PAGETABLE_START(pae_l1_identmap) .long 0, 0 /* Unmap page at 0 to catch errors with NULL pointers. */ .rept PAE_L1_PT_ENTRIES - 1 - .long (PAE_IDX(pae_l1_identmap) << PAE_L1_PT_SHIFT) + PAGE_COMMON + .long (PAE_IDX(pae_l1_identmap) << PAE_L1_PT_SHIFT) + _PAGE_LEAF .long 0 .endr PAGETABLE_END(pae_l1_identmap) /* PAE mappings up to 4G, mostly in 2M superpages. Uses 4x 4k pages. */ PAGETABLE_START(pae_l2_identmap) - .long pae_l1_identmap + PAGE_COMMON + .long pae_l1_identmap + _PAGE_NONLEAF .long 0 .rept (4 * PAE_L2_PT_ENTRIES) - 1 - .long (PAE_IDX(pae_l2_identmap) << PAE_L2_PT_SHIFT) + _PAGE_PSE + PAGE_COMMON + .long (PAE_IDX(pae_l2_identmap) << PAE_L2_PT_SHIFT) + _PAGE_SUPER .long 0 .endr PAGETABLE_END(pae_l2_identmap) +.Lpae_l2_identmap_end: /* PAE l3 pagetable. Maps 4x l2 tables. */ PAGETABLE_START(pae_l3_identmap) .rept 4 - .long pae_l2_identmap + (PAE_IDX(pae_l3_identmap) << PAGE_SHIFT) + PAGE_COMMON + .long pae_l2_identmap + (PAE_IDX(pae_l3_identmap) << PAGE_SHIFT) + _PAGE_NONLEAF .long 0 .endr .fill PAE_L3_PT_ENTRIES - 4, 8, 0 @@ -47,7 +50,7 @@ PAGETABLE_END(pae_l3_identmap) /* PAE l4 pagetable. Maps 1x l3 table. */ PAGETABLE_START(pae_l4_identmap) - .long pae_l3_identmap + PAGE_COMMON + .long pae_l3_identmap + _PAGE_NONLEAF .long 0 .fill PAE_L4_PT_ENTRIES - 1, 8, 0 PAGETABLE_END(pae_l4_identmap) @@ -56,17 +59,18 @@ PAGETABLE_END(pae_l4_identmap) PAGETABLE_START(pse_l1_identmap) .long 0 /* Unmap page at 0 to catch errors with NULL pointers. */ .rept PSE_L1_PT_ENTRIES - 1 - .long (PSE_IDX(pse_l1_identmap) << PSE_L1_PT_SHIFT) + PAGE_COMMON + .long (PSE_IDX(pse_l1_identmap) << PSE_L1_PT_SHIFT) + _PAGE_LEAF .endr PAGETABLE_END(pse_l1_identmap) /* PSE mappings up to 4G, mostly in 4M superpages. Uses 1x 4k page. */ PAGETABLE_START(pse_l2_identmap) - .long pse_l1_identmap + PAGE_COMMON + .long pse_l1_identmap + _PAGE_NONLEAF .rept PSE_L2_PT_ENTRIES - 1 - .long (PSE_IDX(pse_l2_identmap) << PSE_L2_PT_SHIFT) + _PAGE_PSE + PAGE_COMMON + .long (PSE_IDX(pse_l2_identmap) << PSE_L2_PT_SHIFT) + _PAGE_SUPER .endr PAGETABLE_END(pse_l2_identmap) +.Lpse_l2_identmap_end: /* PAE l3 32bit quad. Contains 4 64bit entries. */ PAGETABLE_START(pae32_l3_identmap) @@ -81,12 +85,15 @@ PAGETABLE_END(pae32_l3_identmap) #if CONFIG_PAGING_LEVELS >= 3 .set l1_identmap, pae_l1_identmap .set l2_identmap, pae_l2_identmap + .set l2_identmap_end, .Lpae_l2_identmap_end #else .set l1_identmap, pse_l1_identmap .set l2_identmap, pse_l2_identmap + .set l2_identmap_end, .Lpse_l2_identmap_end #endif .global l1_identmap .global l2_identmap + .global l2_identmap_end /* * Local variables: