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)
 | 
			
		||||
{
 | 
			
		||||
    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