[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen master] Revert "xen/arm64: io: Support instructions (for which ISS is not valid) on emulated MMIO region using MMIO/ioreq handler"
commit 07aebcd55fd2f7997e9fe50a6c849c8a12ec2e68 Author: Julien Grall <jgrall@xxxxxxxxxx> AuthorDate: Mon Mar 14 22:58:33 2022 +0000 Commit: Julien Grall <jgrall@xxxxxxxxxx> CommitDate: Mon Mar 14 23:01:02 2022 +0000 Revert "xen/arm64: io: Support instructions (for which ISS is not valid) on emulated MMIO region using MMIO/ioreq handler" This reverts commit 9e5a68a6652cc54ce3cb3b0ce208eeed79d5aeb5. This breaks boot on arm32: https://lore.kernel.org/xen-devel/osstest-168589-mainreport@xxxxxxx/T/#u --- xen/arch/arm/arm32/traps.c | 11 ----- xen/arch/arm/arm64/traps.c | 52 ---------------------- xen/arch/arm/decode.c | 2 - xen/arch/arm/include/asm/domain.h | 4 -- xen/arch/arm/include/asm/mmio.h | 17 +------- xen/arch/arm/include/asm/traps.h | 2 - xen/arch/arm/io.c | 90 +++++++++++++++------------------------ xen/arch/arm/ioreq.c | 8 +--- xen/arch/arm/traps.c | 77 +++++++-------------------------- xen/arch/x86/include/asm/ioreq.h | 3 -- xen/include/xen/sched.h | 2 - 11 files changed, 54 insertions(+), 214 deletions(-) diff --git a/xen/arch/arm/arm32/traps.c b/xen/arch/arm/arm32/traps.c index 159e3cef8b..9c9790a6d1 100644 --- a/xen/arch/arm/arm32/traps.c +++ b/xen/arch/arm/arm32/traps.c @@ -18,11 +18,9 @@ #include <xen/lib.h> #include <xen/kernel.h> -#include <xen/sched.h> #include <public/xen.h> -#include <asm/mmio.h> #include <asm/processor.h> #include <asm/traps.h> @@ -84,15 +82,6 @@ void do_trap_data_abort(struct cpu_user_regs *regs) do_unexpected_trap("Data Abort", regs); } -void post_increment_register(const struct instr_details *instr) -{ - /* - * We have not implemented decoding of post indexing instructions for 32 bit. - * Thus, this should be unreachable. - */ - domain_crash(current->domain); -} - /* * Local variables: * mode: C diff --git a/xen/arch/arm/arm64/traps.c b/xen/arch/arm/arm64/traps.c index 6ce4a1fa8c..9113a15c7a 100644 --- a/xen/arch/arm/arm64/traps.c +++ b/xen/arch/arm/arm64/traps.c @@ -17,7 +17,6 @@ */ #include <xen/lib.h> -#include <xen/sched.h> #include <asm/hsr.h> #include <asm/system.h> @@ -45,57 +44,6 @@ void do_bad_mode(struct cpu_user_regs *regs, int reason) panic("bad mode\n"); } -void post_increment_register(const struct instr_details *instr) -{ - struct cpu_user_regs *regs = guest_cpu_user_regs(); - register_t val = 0; - uint8_t psr_mode = (regs->cpsr & PSR_MODE_MASK); - - /* Currently, we handle only ldr/str post indexing instructions */ - if ( instr->state != INSTR_LDR_STR_POSTINDEXING ) - return; - - /* - * Handle when rn = SP - * Refer ArmV8 ARM DDI 0487G.b, Page - D1-2463 "Stack pointer register - * selection" - * t = SP_EL0 - * h = SP_ELx - * and M[3:0] (Page - C5-474 "When exception taken from AArch64 state:") - */ - if ( instr->rn == 31 ) - { - switch ( psr_mode ) - { - case PSR_MODE_EL1h: - val = regs->sp_el1; - break; - case PSR_MODE_EL1t: - case PSR_MODE_EL0t: - val = regs->sp_el0; - break; - - default: - domain_crash(current->domain); - return; - } - } - else - val = get_user_reg(regs, instr->rn); - - val += instr->imm9; - - if ( instr->rn == 31 ) - { - if ( (regs->cpsr & PSR_MODE_MASK) == PSR_MODE_EL1h ) - regs->sp_el1 = val; - else - regs->sp_el0 = val; - } - else - set_user_reg(regs, instr->rn, val); -} - /* * Local variables: * mode: C diff --git a/xen/arch/arm/decode.c b/xen/arch/arm/decode.c index f5f6562600..3add87e83a 100644 --- a/xen/arch/arm/decode.c +++ b/xen/arch/arm/decode.c @@ -146,10 +146,8 @@ static int decode_arm64(register_t pc, mmio_info_t *info) update_dabt(dabt, opcode.ldr_str.rt, opcode.ldr_str.size, false); - dabt_instr->state = INSTR_LDR_STR_POSTINDEXING; dabt_instr->rn = opcode.ldr_str.rn; dabt_instr->imm9 = opcode.ldr_str.imm9; - dabt->valid = 1; return 0; diff --git a/xen/arch/arm/include/asm/domain.h b/xen/arch/arm/include/asm/domain.h index ed63c2b6f9..c56f6e4398 100644 --- a/xen/arch/arm/include/asm/domain.h +++ b/xen/arch/arm/include/asm/domain.h @@ -281,10 +281,6 @@ static inline void arch_vcpu_block(struct vcpu *v) {} /* vPCI is not available on Arm */ #define has_vpci(d) ({ (void)(d); false; }) -struct arch_vcpu_io { - struct instr_details dabt_instr; /* when the instruction is decoded */ -}; - #endif /* __ASM_DOMAIN_H__ */ /* diff --git a/xen/arch/arm/include/asm/mmio.h b/xen/arch/arm/include/asm/mmio.h index ca259a79c2..3354d9c635 100644 --- a/xen/arch/arm/include/asm/mmio.h +++ b/xen/arch/arm/include/asm/mmio.h @@ -26,24 +26,12 @@ #define MAX_IO_HANDLER 16 -enum instr_decode_state -{ - INSTR_ERROR, /* Error encountered while decoding instr */ - INSTR_VALID, /* ISS is valid, so no need to decode */ - /* - * Instruction is decoded successfully. It is a ldr/str post indexing - * instruction. - */ - INSTR_LDR_STR_POSTINDEXING, -}; - typedef struct { struct hsr_dabt dabt; struct instr_details { unsigned long rn:5; signed int imm9:9; - enum instr_decode_state state; } dabt_instr; paddr_t gpa; } mmio_info_t; @@ -81,15 +69,14 @@ struct vmmio { }; enum io_state try_handle_mmio(struct cpu_user_regs *regs, - mmio_info_t *info); + const union hsr hsr, + paddr_t gpa); void register_mmio_handler(struct domain *d, const struct mmio_handler_ops *ops, paddr_t addr, paddr_t size, void *priv); int domain_io_init(struct domain *d, int max_count); void domain_io_free(struct domain *d); -void try_decode_instruction(const struct cpu_user_regs *regs, - mmio_info_t *info); #endif /* __ASM_ARM_MMIO_H__ */ diff --git a/xen/arch/arm/include/asm/traps.h b/xen/arch/arm/include/asm/traps.h index 95c46ad391..2ed2b85c6f 100644 --- a/xen/arch/arm/include/asm/traps.h +++ b/xen/arch/arm/include/asm/traps.h @@ -109,8 +109,6 @@ static inline register_t sign_extend(const struct hsr_dabt dabt, register_t r) return r; } -void post_increment_register(const struct instr_details *instr); - #endif /* __ASM_ARM_TRAPS__ */ /* * Local variables: diff --git a/xen/arch/arm/io.c b/xen/arch/arm/io.c index fd903b7b03..fad103bdbd 100644 --- a/xen/arch/arm/io.c +++ b/xen/arch/arm/io.c @@ -102,79 +102,57 @@ static const struct mmio_handler *find_mmio_handler(struct domain *d, return handler; } -void try_decode_instruction(const struct cpu_user_regs *regs, - mmio_info_t *info) -{ - int rc; - - if ( info->dabt.valid ) - { - info->dabt_instr.state = INSTR_VALID; - - /* - * Erratum 766422: Thumb store translation fault to Hypervisor may - * not have correct HSR Rt value. - */ - if ( check_workaround_766422() && (regs->cpsr & PSR_THUMB) && - info->dabt.write ) - { - rc = decode_instruction(regs, info); - if ( rc ) - { - gprintk(XENLOG_DEBUG, "Unable to decode instruction\n"); - info->dabt_instr.state = INSTR_ERROR; - } - } - return; - } - - /* - * Armv8 processor does not provide a valid syndrome for decoding some - * instructions. So in order to process these instructions, Xen must - * decode them. - */ - rc = decode_instruction(regs, info); - if ( rc ) - { - gprintk(XENLOG_ERR, "Unable to decode instruction\n"); - info->dabt_instr.state = INSTR_ERROR; - } -} - enum io_state try_handle_mmio(struct cpu_user_regs *regs, - mmio_info_t *info) + const union hsr hsr, + paddr_t gpa) { struct vcpu *v = current; const struct mmio_handler *handler = NULL; - int rc; + const struct hsr_dabt dabt = hsr.dabt; + mmio_info_t info = { + .gpa = gpa, + .dabt = dabt + }; - ASSERT(info->dabt.ec == HSR_EC_DATA_ABORT_LOWER_EL); + ASSERT(hsr.ec == HSR_EC_DATA_ABORT_LOWER_EL); - if ( !info->dabt.valid ) - { - ASSERT_UNREACHABLE(); - return IO_ABORT; - } - - handler = find_mmio_handler(v->domain, info->gpa); + handler = find_mmio_handler(v->domain, info.gpa); if ( !handler ) { - rc = try_fwd_ioserv(regs, v, info); + int rc; + + rc = try_fwd_ioserv(regs, v, &info); if ( rc == IO_HANDLED ) return handle_ioserv(regs, v); return rc; } + /* All the instructions used on emulated MMIO region should be valid */ + if ( !dabt.valid ) + return IO_ABORT; + /* - * At this point, we know that the instruction is either valid or has been - * decoded successfully. Thus, Xen should be allowed to execute the - * instruction on the emulated MMIO region. + * Erratum 766422: Thumb store translation fault to Hypervisor may + * not have correct HSR Rt value. */ - if ( info->dabt.write ) - return handle_write(handler, v, info); + if ( check_workaround_766422() && (regs->cpsr & PSR_THUMB) && + dabt.write ) + { + int rc; + + rc = decode_instruction(regs, &info); + if ( rc ) + { + gprintk(XENLOG_DEBUG, "Unable to decode instruction\n"); + return IO_ABORT; + } + } + + if ( info.dabt.write ) + return handle_write(handler, v, &info); else - return handle_read(handler, v, info); + return handle_read(handler, v, &info); } void register_mmio_handler(struct domain *d, diff --git a/xen/arch/arm/ioreq.c b/xen/arch/arm/ioreq.c index cc9bf23213..308650b400 100644 --- a/xen/arch/arm/ioreq.c +++ b/xen/arch/arm/ioreq.c @@ -47,8 +47,6 @@ enum io_state try_fwd_ioserv(struct cpu_user_regs *regs, struct vcpu *v, mmio_info_t *info) { struct vcpu_io *vio = &v->io; - struct instr_details instr = info->dabt_instr; - struct hsr_dabt dabt = info->dabt; ioreq_t p = { .type = IOREQ_TYPE_COPY, .addr = info->gpa, @@ -78,10 +76,10 @@ enum io_state try_fwd_ioserv(struct cpu_user_regs *regs, if ( !s ) return IO_UNHANDLED; - ASSERT(dabt.valid); + if ( !info->dabt.valid ) + return IO_ABORT; vio->req = p; - vio->info.dabt_instr = instr; rc = ioreq_send(s, &p, 0); if ( rc != IO_RETRY || v->domain->is_shutting_down ) @@ -97,7 +95,6 @@ enum io_state try_fwd_ioserv(struct cpu_user_regs *regs, bool arch_ioreq_complete_mmio(void) { struct vcpu *v = current; - struct instr_details dabt_instr = v->io.info.dabt_instr; struct cpu_user_regs *regs = guest_cpu_user_regs(); const union hsr hsr = { .bits = regs->hsr }; @@ -109,7 +106,6 @@ bool arch_ioreq_complete_mmio(void) if ( handle_ioserv(regs, v) == IO_HANDLED ) { - post_increment_register(&dabt_instr); advance_pc(regs, hsr); return true; } diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c index 53652d7781..7a1b679b8c 100644 --- a/xen/arch/arm/traps.c +++ b/xen/arch/arm/traps.c @@ -1893,21 +1893,6 @@ static bool try_map_mmio(gfn_t gfn) return !map_regions_p2mt(d, gfn, 1, mfn, p2m_mmio_direct_c); } -static inline bool check_p2m(bool is_data, paddr_t gpa) -{ - /* - * First check if the translation fault can be resolved by the P2M subsystem. - * If that's the case nothing else to do. - */ - if ( p2m_resolve_translation_fault(current->domain , gaddr_to_gfn(gpa)) ) - return true; - - if ( is_data && try_map_mmio(gaddr_to_gfn(gpa)) ) - return true; - - return false; -} - static void do_trap_stage2_abort_guest(struct cpu_user_regs *regs, const union hsr hsr) { @@ -1921,8 +1906,6 @@ static void do_trap_stage2_abort_guest(struct cpu_user_regs *regs, paddr_t gpa; uint8_t fsc = xabt.fsc & ~FSC_LL_MASK; bool is_data = (hsr.ec == HSR_EC_DATA_ABORT_LOWER_EL); - mmio_info_t info; - enum io_state state; /* * If this bit has been set, it means that this stage-2 abort is caused @@ -1976,52 +1959,21 @@ static void do_trap_stage2_abort_guest(struct cpu_user_regs *regs, return; } case FSC_FLT_TRANS: - { - info.gpa = gpa; - info.dabt = hsr.dabt; - /* - * Assumption :- Most of the times when we get a data abort and the ISS - * is invalid or an instruction abort, the underlying cause is that the - * page tables have not been set up correctly. + * Attempt first to emulate the MMIO as the data abort will + * likely happen in an emulated region. + * + * Note that emulated region cannot be executed */ - if ( !is_data || !info.dabt.valid ) + if ( is_data ) { - if ( check_p2m(is_data, gpa) ) - return; - - /* - * If the instruction abort could not be resolved by setting the - * appropriate bits in the translation table, then Xen should - * forward the abort to the guest. - */ - if ( !is_data ) - goto inject_abt; - } - - try_decode_instruction(regs, &info); - - /* - * If Xen could not decode the instruction or encountered an error - * while decoding, then it should forward the abort to the guest. - */ - if ( info.dabt_instr.state == INSTR_ERROR ) - goto inject_abt; - - state = try_handle_mmio(regs, &info); + enum io_state state = try_handle_mmio(regs, hsr, gpa); - switch ( state ) - { + switch ( state ) + { case IO_ABORT: goto inject_abt; case IO_HANDLED: - /* - * If the instruction was decoded and has executed successfully - * on the MMIO region, then Xen should execute the next part of - * the instruction. (for eg increment the rn if it is a - * post-indexing instruction. - */ - post_increment_register(&info.dabt_instr); advance_pc(regs, hsr); return; case IO_RETRY: @@ -2030,18 +1982,21 @@ static void do_trap_stage2_abort_guest(struct cpu_user_regs *regs, case IO_UNHANDLED: /* IO unhandled, try another way to handle it. */ break; + } } /* - * If the instruction syndrome was invalid, then we already checked if - * this was due to a P2M fault. So no point to check again as the result - * will be the same. + * First check if the translation fault can be resolved by the + * P2M subsystem. If that's the case nothing else to do. */ - if ( (info.dabt_instr.state == INSTR_VALID) && check_p2m(is_data, gpa) ) + if ( p2m_resolve_translation_fault(current->domain, + gaddr_to_gfn(gpa)) ) + return; + + if ( is_data && try_map_mmio(gaddr_to_gfn(gpa)) ) return; break; - } default: gprintk(XENLOG_WARNING, "Unsupported FSC: HSR=%#"PRIregister" DFSC=%#x\n", diff --git a/xen/arch/x86/include/asm/ioreq.h b/xen/arch/x86/include/asm/ioreq.h index ecfe7f9fdb..d06ce9a6ea 100644 --- a/xen/arch/x86/include/asm/ioreq.h +++ b/xen/arch/x86/include/asm/ioreq.h @@ -26,9 +26,6 @@ #include <asm/hvm/ioreq.h> #endif -struct arch_vcpu_io { -}; - #endif /* __ASM_X86_IOREQ_H__ */ /* diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 406d9bc610..10ea969c7a 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -160,8 +160,6 @@ struct vcpu_io { /* I/O request in flight to device model. */ enum vio_completion completion; ioreq_t req; - /* Arch specific info pertaining to the io request */ - struct arch_vcpu_io info; }; struct vcpu -- generated by git-patchbot for /home/xen/git/xen.git#master
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |