From d76b9c6f07a2981a44887e1d61d51e016d45417c Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 14 May 2021 10:13:41 -0500 Subject: target/i386: Move helper_check_io to sysemu MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The we never allow i/o from user-only, and the tss check that helper_check_io does will always fail. Use an ifdef within gen_check_io and return false, indicating that an exception is known to be raised. Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Paolo Bonzini Message-Id: <20210514151342.384376-50-richard.henderson@linaro.org> Signed-off-by: Richard Henderson --- target/i386/helper.h | 2 +- target/i386/tcg/seg_helper.c | 28 ---------------------------- target/i386/tcg/sysemu/seg_helper.c | 29 +++++++++++++++++++++++++++++ target/i386/tcg/translate.c | 11 ++++++++++- 4 files changed, 40 insertions(+), 30 deletions(-) (limited to 'target') diff --git a/target/i386/helper.h b/target/i386/helper.h index 47d0d67699..3fd0253298 100644 --- a/target/i386/helper.h +++ b/target/i386/helper.h @@ -86,7 +86,6 @@ DEF_HELPER_1(rdtsc, void, env) DEF_HELPER_1(rdtscp, void, env) DEF_HELPER_FLAGS_1(rdpmc, TCG_CALL_NO_WG, noreturn, env) -DEF_HELPER_FLAGS_3(check_io, TCG_CALL_NO_WG, void, env, i32, i32) DEF_HELPER_3(outb, void, env, i32, i32) DEF_HELPER_2(inb, tl, env, i32) DEF_HELPER_3(outw, void, env, i32, i32) @@ -95,6 +94,7 @@ DEF_HELPER_3(outl, void, env, i32, i32) DEF_HELPER_2(inl, tl, env, i32) #ifndef CONFIG_USER_ONLY +DEF_HELPER_FLAGS_3(check_io, TCG_CALL_NO_WG, void, env, i32, i32) DEF_HELPER_FLAGS_4(bpt_io, TCG_CALL_NO_WG, void, env, i32, i32, tl) DEF_HELPER_2(svm_check_intercept, void, env, i32) DEF_HELPER_4(svm_check_io, void, env, i32, i32, i32) diff --git a/target/i386/tcg/seg_helper.c b/target/i386/tcg/seg_helper.c index 69d6e8f602..2f6cdc8239 100644 --- a/target/i386/tcg/seg_helper.c +++ b/target/i386/tcg/seg_helper.c @@ -2416,31 +2416,3 @@ void helper_verw(CPUX86State *env, target_ulong selector1) } CC_SRC = eflags | CC_Z; } - -/* check if Port I/O is allowed in TSS */ -void helper_check_io(CPUX86State *env, uint32_t addr, uint32_t size) -{ - uintptr_t retaddr = GETPC(); - uint32_t 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_ra(env, env->tr.base + 0x66, retaddr); - io_offset += (addr >> 3); - /* Note: the check needs two bytes */ - if ((io_offset + 1) > env->tr.limit) { - goto fail; - } - val = cpu_lduw_kernel_ra(env, env->tr.base + io_offset, retaddr); - 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_ra(env, EXCP0D_GPF, 0, retaddr); - } -} diff --git a/target/i386/tcg/sysemu/seg_helper.c b/target/i386/tcg/sysemu/seg_helper.c index e0d7b32b82..82c0856c41 100644 --- a/target/i386/tcg/sysemu/seg_helper.c +++ b/target/i386/tcg/sysemu/seg_helper.c @@ -23,6 +23,7 @@ #include "exec/helper-proto.h" #include "exec/cpu_ldst.h" #include "tcg/helper-tcg.h" +#include "../seg_helper.h" #ifdef TARGET_X86_64 void helper_syscall(CPUX86State *env, int next_eip_addend) @@ -123,3 +124,31 @@ void x86_cpu_do_interrupt(CPUState *cs) env->old_exception = -1; } } + +/* check if Port I/O is allowed in TSS */ +void helper_check_io(CPUX86State *env, uint32_t addr, uint32_t size) +{ + uintptr_t retaddr = GETPC(); + uint32_t 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_ra(env, env->tr.base + 0x66, retaddr); + io_offset += (addr >> 3); + /* Note: the check needs two bytes */ + if ((io_offset + 1) > env->tr.limit) { + goto fail; + } + val = cpu_lduw_kernel_ra(env, env->tr.base + io_offset, retaddr); + 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_ra(env, EXCP0D_GPF, 0, retaddr); + } +} diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c index 68ae9b0798..86b93a010d 100644 --- a/target/i386/tcg/translate.c +++ b/target/i386/tcg/translate.c @@ -203,7 +203,6 @@ STUB_HELPER(read_crN, TCGv ret, TCGv_env env, TCGv_i32 reg) STUB_HELPER(set_dr, TCGv_env env, TCGv_i32 reg, TCGv val) STUB_HELPER(stgi, TCGv_env env) STUB_HELPER(svm_check_intercept, TCGv_env env, TCGv_i32 type) -STUB_HELPER(svm_check_io, TCGv_env env, TCGv_i32 port, TCGv_i32 p, TCGv_i32 a) STUB_HELPER(vmload, TCGv_env env, TCGv_i32 aflag) STUB_HELPER(vmmcall, TCGv_env env) STUB_HELPER(vmrun, TCGv_env env, TCGv_i32 aflag, TCGv_i32 pc_ofs) @@ -217,6 +216,7 @@ static void gen_jr(DisasContext *s, TCGv dest); static void gen_jmp(DisasContext *s, target_ulong eip); static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num); static void gen_op(DisasContext *s1, int op, MemOp ot, int d); +static void gen_exception_gpf(DisasContext *s); /* i386 arith/logic operations */ enum { @@ -681,6 +681,14 @@ static void gen_helper_out_func(MemOp ot, TCGv_i32 v, TCGv_i32 n) static bool gen_check_io(DisasContext *s, MemOp ot, TCGv_i32 port, uint32_t svm_flags) { +#ifdef CONFIG_USER_ONLY + /* + * We do not implement the ioperm(2) syscall, so the TSS check + * will always fail. + */ + gen_exception_gpf(s); + return false; +#else if (PE(s) && (CPL(s) > IOPL(s) || VM86(s))) { gen_helper_check_io(cpu_env, port, tcg_constant_i32(1 << ot)); } @@ -699,6 +707,7 @@ static bool gen_check_io(DisasContext *s, MemOp ot, TCGv_i32 port, tcg_constant_i32(next_eip - cur_eip)); } return true; +#endif } static inline void gen_movs(DisasContext *s, MemOp ot) -- cgit v1.2.3