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
|
||||
|
||||
/* MMU modes definitions */
|
||||
#define MMU_MODE0_SUFFIX _kernel
|
||||
#define MMU_MODE0_SUFFIX _ksmap
|
||||
#define MMU_MODE1_SUFFIX _user
|
||||
#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_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 :
|
||||
((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)
|
||||
|
@ -648,7 +648,7 @@ int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
|
||||
}
|
||||
break;
|
||||
|
||||
case MMU_KERNEL_IDX:
|
||||
case MMU_KSMAP_IDX:
|
||||
if (is_write1 != 2 && (env->cr[4] & CR4_SMAP_MASK) &&
|
||||
(ptep & PG_USER_MASK)) {
|
||||
goto do_fault_protect;
|
||||
@ -710,7 +710,7 @@ int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
|
||||
}
|
||||
break;
|
||||
|
||||
case MMU_KERNEL_IDX:
|
||||
case MMU_KSMAP_IDX:
|
||||
if (is_write1 != 2 && (env->cr[4] & CR4_SMAP_MASK) &&
|
||||
(ptep & PG_USER_MASK)) {
|
||||
goto do_fault_protect;
|
||||
@ -765,7 +765,7 @@ int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
|
||||
}
|
||||
break;
|
||||
|
||||
case MMU_KERNEL_IDX:
|
||||
case MMU_KSMAP_IDX:
|
||||
if (is_write1 != 2 && (env->cr[4] & CR4_SMAP_MASK) &&
|
||||
(pde & PG_USER_MASK)) {
|
||||
goto do_fault_protect;
|
||||
@ -822,7 +822,7 @@ int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
|
||||
}
|
||||
break;
|
||||
|
||||
case MMU_KERNEL_IDX:
|
||||
case MMU_KSMAP_IDX:
|
||||
if (is_write1 != 2 && (env->cr[4] & CR4_SMAP_MASK) &&
|
||||
(ptep & PG_USER_MASK)) {
|
||||
goto do_fault_protect;
|
||||
|
@ -34,6 +34,24 @@
|
||||
# define LOG_PCALL_STATE(cpu) do { } while (0)
|
||||
#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 */
|
||||
static inline int load_segment(CPUX86State *env, uint32_t *e1_ptr,
|
||||
uint32_t *e2_ptr, int selector)
|
||||
|
Loading…
Reference in New Issue
Block a user