diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2014-06-05 21:06:13 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2014-06-05 21:06:14 +0100 |
commit | 31e25e3e5701607a2a88b5b6c5fb1057b20941fd (patch) | |
tree | 757e835a8cef83a5e28f5e99704854836ca5df62 /target-i386/seg_helper.c | |
parent | 9d48d3f01cf3f67d54cd7e2c7834e97a57cea0b8 (diff) | |
parent | 16b96f82cdfcb185560c2f8ebfc731711e2ccb2d (diff) |
Merge remote-tracking branch 'remotes/bonzini/softmmu-smap' into staging
* remotes/bonzini/softmmu-smap: (33 commits)
target-i386: cleanup x86_cpu_get_phys_page_debug
target-i386: fix protection bits in the TLB for SMEP
target-i386: support long addresses for 4MB pages (PSE-36)
target-i386: raise page fault for reserved bits in large pages
target-i386: unify reserved bits and NX bit check
target-i386: simplify pte/vaddr calculation
target-i386: raise page fault for reserved physical address bits
target-i386: test reserved PS bit on PML4Es
target-i386: set correct error code for reserved bit access
target-i386: introduce support for 1 GB pages
target-i386: introduce do_check_protect label
target-i386: tweak handling of PG_NX_MASK
target-i386: commonize checks for PAE and non-PAE
target-i386: commonize checks for 4MB and 4KB pages
target-i386: commonize checks for 2MB and 4KB pages
target-i386: fix coding standards in x86_cpu_handle_mmu_fault
target-i386: simplify SMAP handling in MMU_KSMAP_IDX
target-i386: fix kernel accesses with SMAP and CPL = 3
target-i386: move check_io helpers to seg_helper.c
target-i386: rename KSMAP to KNOSMAP
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target-i386/seg_helper.c')
-rw-r--r-- | target-i386/seg_helper.c | 65 |
1 files changed, 61 insertions, 4 deletions
diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c index 51c2833ea5..2d970d0cb9 100644 --- a/target-i386/seg_helper.c +++ b/target-i386/seg_helper.c @@ -21,13 +21,10 @@ #include "cpu.h" #include "qemu/log.h" #include "exec/helper-proto.h" +#include "exec/cpu_ldst.h" //#define DEBUG_PCALL -#if !defined(CONFIG_USER_ONLY) -#include "exec/softmmu_exec.h" -#endif /* !defined(CONFIG_USER_ONLY) */ - #ifdef DEBUG_PCALL # define LOG_PCALL(...) qemu_log_mask(CPU_LOG_PCALL, ## __VA_ARGS__) # define LOG_PCALL_STATE(cpu) \ @@ -37,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) @@ -2471,3 +2486,45 @@ void cpu_x86_load_seg(CPUX86State *env, int seg_reg, int selector) } } #endif + +/* check if Port I/O is allowed in TSS */ +static inline void check_io(CPUX86State *env, int addr, int size) +{ + int io_offset, val, mask; + + /* TSS must be a valid 32 bit one */ + if (!(env->tr.flags & DESC_P_MASK) || + ((env->tr.flags >> DESC_TYPE_SHIFT) & 0xf) != 9 || + env->tr.limit < 103) { + goto fail; + } + io_offset = cpu_lduw_kernel(env, env->tr.base + 0x66); + io_offset += (addr >> 3); + /* Note: the check needs two bytes */ + if ((io_offset + 1) > env->tr.limit) { + goto fail; + } + val = cpu_lduw_kernel(env, env->tr.base + io_offset); + val >>= (addr & 7); + mask = (1 << size) - 1; + /* all bits must be zero to allow the I/O */ + if ((val & mask) != 0) { + fail: + raise_exception_err(env, EXCP0D_GPF, 0); + } +} + +void helper_check_iob(CPUX86State *env, uint32_t t0) +{ + check_io(env, t0, 1); +} + +void helper_check_iow(CPUX86State *env, uint32_t t0) +{ + check_io(env, t0, 2); +} + +void helper_check_iol(CPUX86State *env, uint32_t t0) +{ + check_io(env, t0, 4); +} |