target-i386: fix kernel accesses with SMAP and CPL = 3
With SMAP, implicit kernel accesses from user mode always behave as if AC=0. To do this, kernel mode is not anymore a separate MMU mode. Instead, KERNEL_IDX is renamed to KSMAP_IDX and the kernel mode accessors wrap KSMAP_IDX and KNOSMAP_IDX. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
81cf8d8adc
commit
8a201bd47e
@ -1153,17 +1153,24 @@ static inline CPUX86State *cpu_init(const char *cpu_model)
|
|||||||
#define cpudef_setup x86_cpudef_setup
|
#define cpudef_setup x86_cpudef_setup
|
||||||
|
|
||||||
/* MMU modes definitions */
|
/* MMU modes definitions */
|
||||||
#define MMU_MODE0_SUFFIX _kernel
|
#define MMU_MODE0_SUFFIX _ksmap
|
||||||
#define MMU_MODE1_SUFFIX _user
|
#define MMU_MODE1_SUFFIX _user
|
||||||
#define MMU_MODE2_SUFFIX _knosmap /* SMAP disabled or CPL<3 && AC=1 */
|
#define MMU_MODE2_SUFFIX _knosmap /* SMAP disabled or CPL<3 && AC=1 */
|
||||||
#define MMU_KERNEL_IDX 0
|
#define MMU_KSMAP_IDX 0
|
||||||
#define MMU_USER_IDX 1
|
#define MMU_USER_IDX 1
|
||||||
#define MMU_KNOSMAP_IDX 2
|
#define MMU_KNOSMAP_IDX 2
|
||||||
static inline int cpu_mmu_index (CPUX86State *env)
|
static inline int cpu_mmu_index(CPUX86State *env)
|
||||||
{
|
{
|
||||||
return (env->hflags & HF_CPL_MASK) == 3 ? MMU_USER_IDX :
|
return (env->hflags & HF_CPL_MASK) == 3 ? MMU_USER_IDX :
|
||||||
((env->hflags & HF_SMAP_MASK) && (env->eflags & AC_MASK))
|
((env->hflags & HF_SMAP_MASK) && (env->eflags & AC_MASK))
|
||||||
? MMU_KNOSMAP_IDX : MMU_KERNEL_IDX;
|
? MMU_KNOSMAP_IDX : MMU_KSMAP_IDX;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int cpu_mmu_index_kernel(CPUX86State *env)
|
||||||
|
{
|
||||||
|
return !(env->hflags & HF_SMAP_MASK) ? MMU_KNOSMAP_IDX :
|
||||||
|
((env->hflags & HF_CPL_MASK) < 3 && (env->eflags & AC_MASK))
|
||||||
|
? MMU_KNOSMAP_IDX : MMU_KSMAP_IDX;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CC_DST (env->cc_dst)
|
#define CC_DST (env->cc_dst)
|
||||||
|
@ -648,7 +648,7 @@ int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MMU_KERNEL_IDX:
|
case MMU_KSMAP_IDX:
|
||||||
if (is_write1 != 2 && (env->cr[4] & CR4_SMAP_MASK) &&
|
if (is_write1 != 2 && (env->cr[4] & CR4_SMAP_MASK) &&
|
||||||
(ptep & PG_USER_MASK)) {
|
(ptep & PG_USER_MASK)) {
|
||||||
goto do_fault_protect;
|
goto do_fault_protect;
|
||||||
@ -710,7 +710,7 @@ int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MMU_KERNEL_IDX:
|
case MMU_KSMAP_IDX:
|
||||||
if (is_write1 != 2 && (env->cr[4] & CR4_SMAP_MASK) &&
|
if (is_write1 != 2 && (env->cr[4] & CR4_SMAP_MASK) &&
|
||||||
(ptep & PG_USER_MASK)) {
|
(ptep & PG_USER_MASK)) {
|
||||||
goto do_fault_protect;
|
goto do_fault_protect;
|
||||||
@ -765,7 +765,7 @@ int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MMU_KERNEL_IDX:
|
case MMU_KSMAP_IDX:
|
||||||
if (is_write1 != 2 && (env->cr[4] & CR4_SMAP_MASK) &&
|
if (is_write1 != 2 && (env->cr[4] & CR4_SMAP_MASK) &&
|
||||||
(pde & PG_USER_MASK)) {
|
(pde & PG_USER_MASK)) {
|
||||||
goto do_fault_protect;
|
goto do_fault_protect;
|
||||||
@ -822,7 +822,7 @@ int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MMU_KERNEL_IDX:
|
case MMU_KSMAP_IDX:
|
||||||
if (is_write1 != 2 && (env->cr[4] & CR4_SMAP_MASK) &&
|
if (is_write1 != 2 && (env->cr[4] & CR4_SMAP_MASK) &&
|
||||||
(ptep & PG_USER_MASK)) {
|
(ptep & PG_USER_MASK)) {
|
||||||
goto do_fault_protect;
|
goto do_fault_protect;
|
||||||
|
@ -34,6 +34,24 @@
|
|||||||
# define LOG_PCALL_STATE(cpu) do { } while (0)
|
# define LOG_PCALL_STATE(cpu) do { } while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
#define CPU_MMU_INDEX (cpu_mmu_index_kernel(env))
|
||||||
|
#define MEMSUFFIX _kernel
|
||||||
|
#define DATA_SIZE 1
|
||||||
|
#include "exec/cpu_ldst_template.h"
|
||||||
|
|
||||||
|
#define DATA_SIZE 2
|
||||||
|
#include "exec/cpu_ldst_template.h"
|
||||||
|
|
||||||
|
#define DATA_SIZE 4
|
||||||
|
#include "exec/cpu_ldst_template.h"
|
||||||
|
|
||||||
|
#define DATA_SIZE 8
|
||||||
|
#include "exec/cpu_ldst_template.h"
|
||||||
|
#undef CPU_MMU_INDEX
|
||||||
|
#undef MEMSUFFIX
|
||||||
|
#endif
|
||||||
|
|
||||||
/* return non zero if error */
|
/* return non zero if error */
|
||||||
static inline int load_segment(CPUX86State *env, uint32_t *e1_ptr,
|
static inline int load_segment(CPUX86State *env, uint32_t *e1_ptr,
|
||||||
uint32_t *e2_ptr, int selector)
|
uint32_t *e2_ptr, int selector)
|
||||||
|
Loading…
Reference in New Issue
Block a user