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_DIRTY_MASK (1 << PG_DIRTY_BIT)
|
||||||
#define PG_PSE_MASK (1 << PG_PSE_BIT)
|
#define PG_PSE_MASK (1 << PG_PSE_BIT)
|
||||||
#define PG_GLOBAL_MASK (1 << PG_GLOBAL_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_NX_MASK (1LL << PG_NX_BIT)
|
||||||
|
|
||||||
#define PG_ERROR_W_BIT 1
|
#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))
|
if (!(pml4e & PG_PRESENT_MASK))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
pdpe_addr = ((pml4e & ~0xfff) + (((addr >> 30) & 0x1ff) << 3)) &
|
pdpe_addr = ((pml4e & ~0xfff & ~(PG_NX_MASK | PG_HI_USER_MASK)) +
|
||||||
env->a20_mask;
|
(((addr >> 30) & 0x1ff) << 3)) & env->a20_mask;
|
||||||
pdpe = ldq_phys(pdpe_addr);
|
pdpe = ldq_phys(pdpe_addr);
|
||||||
if (!(pdpe & PG_PRESENT_MASK))
|
if (!(pdpe & PG_PRESENT_MASK))
|
||||||
return -1;
|
return -1;
|
||||||
@ -900,8 +900,8 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pde_addr = ((pdpe & ~0xfff) + (((addr >> 21) & 0x1ff) << 3)) &
|
pde_addr = ((pdpe & ~0xfff & ~(PG_NX_MASK | PG_HI_USER_MASK)) +
|
||||||
env->a20_mask;
|
(((addr >> 21) & 0x1ff) << 3)) & env->a20_mask;
|
||||||
pde = ldq_phys(pde_addr);
|
pde = ldq_phys(pde_addr);
|
||||||
if (!(pde & PG_PRESENT_MASK)) {
|
if (!(pde & PG_PRESENT_MASK)) {
|
||||||
return -1;
|
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 */
|
pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
|
||||||
} else {
|
} else {
|
||||||
/* 4 KB page */
|
/* 4 KB page */
|
||||||
pte_addr = ((pde & ~0xfff) + (((addr >> 12) & 0x1ff) << 3)) &
|
pte_addr = ((pde & ~0xfff & ~(PG_NX_MASK | PG_HI_USER_MASK)) +
|
||||||
env->a20_mask;
|
(((addr >> 12) & 0x1ff) << 3)) & env->a20_mask;
|
||||||
page_size = 4096;
|
page_size = 4096;
|
||||||
pte = ldq_phys(pte_addr);
|
pte = ldq_phys(pte_addr);
|
||||||
}
|
}
|
||||||
|
pte &= ~(PG_NX_MASK | PG_HI_USER_MASK);
|
||||||
if (!(pte & PG_PRESENT_MASK))
|
if (!(pte & PG_PRESENT_MASK))
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user