mirror of
https://github.com/qemu/qemu.git
synced 2024-11-23 19:03:38 +08:00
target-i386: Mask NX bit from cpu_get_phys_page_debug result
This was a long pending bug, now revealed by the assert in phys_page_find that stumbled over the large page index returned by cpu_get_phys_page_debug for NX-marked pages: We need to mask out NX and all user-definable bits 52..62 from PDEs and the final PTE to avoid corrupting physical addresses. Reviewed-by: Avi Kivity <avi@redhat.com> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
This commit is contained in:
parent
dac6b1b22c
commit
3f2cbf0d1a
@ -241,6 +241,7 @@
|
||||
#define PG_DIRTY_MASK (1 << PG_DIRTY_BIT)
|
||||
#define PG_PSE_MASK (1 << PG_PSE_BIT)
|
||||
#define PG_GLOBAL_MASK (1 << PG_GLOBAL_BIT)
|
||||
#define PG_HI_USER_MASK 0x7ff0000000000000LL
|
||||
#define PG_NX_MASK (1LL << PG_NX_BIT)
|
||||
|
||||
#define PG_ERROR_W_BIT 1
|
||||
|
@ -885,8 +885,8 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
|
||||
if (!(pml4e & PG_PRESENT_MASK))
|
||||
return -1;
|
||||
|
||||
pdpe_addr = ((pml4e & ~0xfff) + (((addr >> 30) & 0x1ff) << 3)) &
|
||||
env->a20_mask;
|
||||
pdpe_addr = ((pml4e & ~0xfff & ~(PG_NX_MASK | PG_HI_USER_MASK)) +
|
||||
(((addr >> 30) & 0x1ff) << 3)) & env->a20_mask;
|
||||
pdpe = ldq_phys(pdpe_addr);
|
||||
if (!(pdpe & PG_PRESENT_MASK))
|
||||
return -1;
|
||||
@ -900,8 +900,8 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
|
||||
return -1;
|
||||
}
|
||||
|
||||
pde_addr = ((pdpe & ~0xfff) + (((addr >> 21) & 0x1ff) << 3)) &
|
||||
env->a20_mask;
|
||||
pde_addr = ((pdpe & ~0xfff & ~(PG_NX_MASK | PG_HI_USER_MASK)) +
|
||||
(((addr >> 21) & 0x1ff) << 3)) & env->a20_mask;
|
||||
pde = ldq_phys(pde_addr);
|
||||
if (!(pde & PG_PRESENT_MASK)) {
|
||||
return -1;
|
||||
@ -912,11 +912,12 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
|
||||
pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
|
||||
} else {
|
||||
/* 4 KB page */
|
||||
pte_addr = ((pde & ~0xfff) + (((addr >> 12) & 0x1ff) << 3)) &
|
||||
env->a20_mask;
|
||||
pte_addr = ((pde & ~0xfff & ~(PG_NX_MASK | PG_HI_USER_MASK)) +
|
||||
(((addr >> 12) & 0x1ff) << 3)) & env->a20_mask;
|
||||
page_size = 4096;
|
||||
pte = ldq_phys(pte_addr);
|
||||
}
|
||||
pte &= ~(PG_NX_MASK | PG_HI_USER_MASK);
|
||||
if (!(pte & PG_PRESENT_MASK))
|
||||
return -1;
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user