From: "Edgar E. Iglesias" <edgar.iglesias@gmail.com>
To: Peter Maydell <peter.maydell@linaro.org>
Cc: qemu-arm@nongnu.org, qemu-devel@nongnu.org, patches@linaro.org,
Richard Henderson <rth@twiddle.net>
Subject: Re: [Qemu-arm] [PATCH 6/8] target/arm: Factor out fault delivery code
Date: Sat, 5 Aug 2017 03:40:45 +0200 [thread overview]
Message-ID: <20170805014045.GE4859@toto> (raw)
In-Reply-To: <1501867249-1924-7-git-send-email-peter.maydell@linaro.org>
On Fri, Aug 04, 2017 at 06:20:47PM +0100, Peter Maydell wrote:
> We currently have some similar code in tlb_fill() and in
> arm_cpu_do_unaligned_access() for delivering a data abort or prefetch
> abort. We're also going to want to do the same thing to handle
> external aborts. Factor out the common code into a new function
> deliver_fault().
I found this a bit hard to read but I think it looks OK :-)
Acked-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
> target/arm/op_helper.c | 110 +++++++++++++++++++++++++------------------------
> 1 file changed, 57 insertions(+), 53 deletions(-)
>
> diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
> index 2a85666..aa52a98 100644
> --- a/target/arm/op_helper.c
> +++ b/target/arm/op_helper.c
> @@ -115,6 +115,51 @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
> return syn;
> }
>
> +static void deliver_fault(ARMCPU *cpu, vaddr addr, MMUAccessType access_type,
> + uint32_t fsr, uint32_t fsc, ARMMMUFaultInfo *fi)
> +{
> + CPUARMState *env = &cpu->env;
> + int target_el;
> + bool same_el;
> + uint32_t syn, exc;
> +
> + target_el = exception_target_el(env);
> + if (fi->stage2) {
> + target_el = 2;
> + env->cp15.hpfar_el2 = extract64(fi->s2addr, 12, 47) << 4;
> + }
> + same_el = (arm_current_el(env) == target_el);
> +
> + if (fsc == 0x3f) {
> + /* Caller doesn't have a long-format fault status code. This
> + * should only happen if this fault will never actually be reported
> + * to an EL that uses a syndrome register. Check that here.
> + * 0x3f is a (currently) reserved FSR code, in case the constructed
> + * syndrome does leak into the guest somehow.
> + */
> + assert(target_el != 2 && !arm_el_is_aa64(env, target_el));
> + }
> +
> + if (access_type == MMU_INST_FETCH) {
> + syn = syn_insn_abort(same_el, 0, fi->s1ptw, fsc);
> + exc = EXCP_PREFETCH_ABORT;
> + } else {
> + syn = merge_syn_data_abort(env->exception.syndrome, target_el,
> + same_el, fi->s1ptw,
> + access_type == MMU_DATA_STORE,
> + fsc);
> + if (access_type == MMU_DATA_STORE
> + && arm_feature(env, ARM_FEATURE_V6)) {
> + fsr |= (1 << 11);
> + }
> + exc = EXCP_DATA_ABORT;
> + }
> +
> + env->exception.vaddress = addr;
> + env->exception.fsr = fsr;
> + raise_exception(env, exc, syn, target_el);
> +}
> +
> /* try to fill the TLB and return an exception if error. If retaddr is
> * NULL, it means that the function was called in C code (i.e. not
> * from generated code or from helper.c)
> @@ -129,23 +174,13 @@ void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
> ret = arm_tlb_fill(cs, addr, access_type, mmu_idx, &fsr, &fi);
> if (unlikely(ret)) {
> ARMCPU *cpu = ARM_CPU(cs);
> - CPUARMState *env = &cpu->env;
> - uint32_t syn, exc, fsc;
> - unsigned int target_el;
> - bool same_el;
> + uint32_t fsc;
>
> if (retaddr) {
> /* now we have a real cpu fault */
> cpu_restore_state(cs, retaddr);
> }
>
> - target_el = exception_target_el(env);
> - if (fi.stage2) {
> - target_el = 2;
> - env->cp15.hpfar_el2 = extract64(fi.s2addr, 12, 47) << 4;
> - }
> - same_el = arm_current_el(env) == target_el;
> -
> if (fsr & (1 << 9)) {
> /* LPAE format fault status register : bottom 6 bits are
> * status code in the same form as needed for syndrome
> @@ -153,34 +188,15 @@ void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
> fsc = extract32(fsr, 0, 6);
> } else {
> /* Short format FSR : this fault will never actually be reported
> - * to an EL that uses a syndrome register. Check that here,
> - * and use a (currently) reserved FSR code in case the constructed
> - * syndrome does leak into the guest somehow.
> + * to an EL that uses a syndrome register. Use a (currently)
> + * reserved FSR code in case the constructed syndrome does leak
> + * into the guest somehow. deliver_fault will assert that
> + * we don't target an EL using the syndrome.
> */
> - assert(target_el != 2 && !arm_el_is_aa64(env, target_el));
> fsc = 0x3f;
> }
>
> - /* For insn and data aborts we assume there is no instruction syndrome
> - * information; this is always true for exceptions reported to EL1.
> - */
> - if (access_type == MMU_INST_FETCH) {
> - syn = syn_insn_abort(same_el, 0, fi.s1ptw, fsc);
> - exc = EXCP_PREFETCH_ABORT;
> - } else {
> - syn = merge_syn_data_abort(env->exception.syndrome, target_el,
> - same_el, fi.s1ptw,
> - access_type == MMU_DATA_STORE, fsc);
> - if (access_type == MMU_DATA_STORE
> - && arm_feature(env, ARM_FEATURE_V6)) {
> - fsr |= (1 << 11);
> - }
> - exc = EXCP_DATA_ABORT;
> - }
> -
> - env->exception.vaddress = addr;
> - env->exception.fsr = fsr;
> - raise_exception(env, exc, syn, target_el);
> + deliver_fault(cpu, addr, access_type, fsr, fsc, &fi);
> }
> }
>
> @@ -191,9 +207,8 @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
> {
> ARMCPU *cpu = ARM_CPU(cs);
> CPUARMState *env = &cpu->env;
> - int target_el;
> - bool same_el;
> - uint32_t syn;
> + uint32_t fsr, fsc;
> + ARMMMUFaultInfo fi = {};
> ARMMMUIdx arm_mmu_idx = core_to_arm_mmu_idx(env, mmu_idx);
>
> if (retaddr) {
> @@ -201,28 +216,17 @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
> cpu_restore_state(cs, retaddr);
> }
>
> - target_el = exception_target_el(env);
> - same_el = (arm_current_el(env) == target_el);
> -
> - env->exception.vaddress = vaddr;
> -
> /* the DFSR for an alignment fault depends on whether we're using
> * the LPAE long descriptor format, or the short descriptor format
> */
> if (arm_s1_regime_using_lpae_format(env, arm_mmu_idx)) {
> - env->exception.fsr = (1 << 9) | 0x21;
> + fsr = (1 << 9) | 0x21;
> } else {
> - env->exception.fsr = 0x1;
> - }
> -
> - if (access_type == MMU_DATA_STORE && arm_feature(env, ARM_FEATURE_V6)) {
> - env->exception.fsr |= (1 << 11);
> + fsr = 0x1;
> }
> + fsc = 0x21;
>
> - syn = merge_syn_data_abort(env->exception.syndrome, target_el,
> - same_el, 0, access_type == MMU_DATA_STORE,
> - 0x21);
> - raise_exception(env, EXCP_DATA_ABORT, syn, target_el);
> + deliver_fault(cpu, vaddr, access_type, fsr, fsc, &fi);
> }
>
> #endif /* !defined(CONFIG_USER_ONLY) */
> --
> 2.7.4
>
>
WARNING: multiple messages have this Message-ID (diff)
From: "Edgar E. Iglesias" <edgar.iglesias@gmail.com>
To: Peter Maydell <peter.maydell@linaro.org>
Cc: qemu-arm@nongnu.org, qemu-devel@nongnu.org,
Richard Henderson <rth@twiddle.net>,
patches@linaro.org
Subject: Re: [Qemu-devel] [Qemu-arm] [PATCH 6/8] target/arm: Factor out fault delivery code
Date: Sat, 5 Aug 2017 03:40:45 +0200 [thread overview]
Message-ID: <20170805014045.GE4859@toto> (raw)
In-Reply-To: <1501867249-1924-7-git-send-email-peter.maydell@linaro.org>
On Fri, Aug 04, 2017 at 06:20:47PM +0100, Peter Maydell wrote:
> We currently have some similar code in tlb_fill() and in
> arm_cpu_do_unaligned_access() for delivering a data abort or prefetch
> abort. We're also going to want to do the same thing to handle
> external aborts. Factor out the common code into a new function
> deliver_fault().
I found this a bit hard to read but I think it looks OK :-)
Acked-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
> target/arm/op_helper.c | 110 +++++++++++++++++++++++++------------------------
> 1 file changed, 57 insertions(+), 53 deletions(-)
>
> diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
> index 2a85666..aa52a98 100644
> --- a/target/arm/op_helper.c
> +++ b/target/arm/op_helper.c
> @@ -115,6 +115,51 @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
> return syn;
> }
>
> +static void deliver_fault(ARMCPU *cpu, vaddr addr, MMUAccessType access_type,
> + uint32_t fsr, uint32_t fsc, ARMMMUFaultInfo *fi)
> +{
> + CPUARMState *env = &cpu->env;
> + int target_el;
> + bool same_el;
> + uint32_t syn, exc;
> +
> + target_el = exception_target_el(env);
> + if (fi->stage2) {
> + target_el = 2;
> + env->cp15.hpfar_el2 = extract64(fi->s2addr, 12, 47) << 4;
> + }
> + same_el = (arm_current_el(env) == target_el);
> +
> + if (fsc == 0x3f) {
> + /* Caller doesn't have a long-format fault status code. This
> + * should only happen if this fault will never actually be reported
> + * to an EL that uses a syndrome register. Check that here.
> + * 0x3f is a (currently) reserved FSR code, in case the constructed
> + * syndrome does leak into the guest somehow.
> + */
> + assert(target_el != 2 && !arm_el_is_aa64(env, target_el));
> + }
> +
> + if (access_type == MMU_INST_FETCH) {
> + syn = syn_insn_abort(same_el, 0, fi->s1ptw, fsc);
> + exc = EXCP_PREFETCH_ABORT;
> + } else {
> + syn = merge_syn_data_abort(env->exception.syndrome, target_el,
> + same_el, fi->s1ptw,
> + access_type == MMU_DATA_STORE,
> + fsc);
> + if (access_type == MMU_DATA_STORE
> + && arm_feature(env, ARM_FEATURE_V6)) {
> + fsr |= (1 << 11);
> + }
> + exc = EXCP_DATA_ABORT;
> + }
> +
> + env->exception.vaddress = addr;
> + env->exception.fsr = fsr;
> + raise_exception(env, exc, syn, target_el);
> +}
> +
> /* try to fill the TLB and return an exception if error. If retaddr is
> * NULL, it means that the function was called in C code (i.e. not
> * from generated code or from helper.c)
> @@ -129,23 +174,13 @@ void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
> ret = arm_tlb_fill(cs, addr, access_type, mmu_idx, &fsr, &fi);
> if (unlikely(ret)) {
> ARMCPU *cpu = ARM_CPU(cs);
> - CPUARMState *env = &cpu->env;
> - uint32_t syn, exc, fsc;
> - unsigned int target_el;
> - bool same_el;
> + uint32_t fsc;
>
> if (retaddr) {
> /* now we have a real cpu fault */
> cpu_restore_state(cs, retaddr);
> }
>
> - target_el = exception_target_el(env);
> - if (fi.stage2) {
> - target_el = 2;
> - env->cp15.hpfar_el2 = extract64(fi.s2addr, 12, 47) << 4;
> - }
> - same_el = arm_current_el(env) == target_el;
> -
> if (fsr & (1 << 9)) {
> /* LPAE format fault status register : bottom 6 bits are
> * status code in the same form as needed for syndrome
> @@ -153,34 +188,15 @@ void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
> fsc = extract32(fsr, 0, 6);
> } else {
> /* Short format FSR : this fault will never actually be reported
> - * to an EL that uses a syndrome register. Check that here,
> - * and use a (currently) reserved FSR code in case the constructed
> - * syndrome does leak into the guest somehow.
> + * to an EL that uses a syndrome register. Use a (currently)
> + * reserved FSR code in case the constructed syndrome does leak
> + * into the guest somehow. deliver_fault will assert that
> + * we don't target an EL using the syndrome.
> */
> - assert(target_el != 2 && !arm_el_is_aa64(env, target_el));
> fsc = 0x3f;
> }
>
> - /* For insn and data aborts we assume there is no instruction syndrome
> - * information; this is always true for exceptions reported to EL1.
> - */
> - if (access_type == MMU_INST_FETCH) {
> - syn = syn_insn_abort(same_el, 0, fi.s1ptw, fsc);
> - exc = EXCP_PREFETCH_ABORT;
> - } else {
> - syn = merge_syn_data_abort(env->exception.syndrome, target_el,
> - same_el, fi.s1ptw,
> - access_type == MMU_DATA_STORE, fsc);
> - if (access_type == MMU_DATA_STORE
> - && arm_feature(env, ARM_FEATURE_V6)) {
> - fsr |= (1 << 11);
> - }
> - exc = EXCP_DATA_ABORT;
> - }
> -
> - env->exception.vaddress = addr;
> - env->exception.fsr = fsr;
> - raise_exception(env, exc, syn, target_el);
> + deliver_fault(cpu, addr, access_type, fsr, fsc, &fi);
> }
> }
>
> @@ -191,9 +207,8 @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
> {
> ARMCPU *cpu = ARM_CPU(cs);
> CPUARMState *env = &cpu->env;
> - int target_el;
> - bool same_el;
> - uint32_t syn;
> + uint32_t fsr, fsc;
> + ARMMMUFaultInfo fi = {};
> ARMMMUIdx arm_mmu_idx = core_to_arm_mmu_idx(env, mmu_idx);
>
> if (retaddr) {
> @@ -201,28 +216,17 @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
> cpu_restore_state(cs, retaddr);
> }
>
> - target_el = exception_target_el(env);
> - same_el = (arm_current_el(env) == target_el);
> -
> - env->exception.vaddress = vaddr;
> -
> /* the DFSR for an alignment fault depends on whether we're using
> * the LPAE long descriptor format, or the short descriptor format
> */
> if (arm_s1_regime_using_lpae_format(env, arm_mmu_idx)) {
> - env->exception.fsr = (1 << 9) | 0x21;
> + fsr = (1 << 9) | 0x21;
> } else {
> - env->exception.fsr = 0x1;
> - }
> -
> - if (access_type == MMU_DATA_STORE && arm_feature(env, ARM_FEATURE_V6)) {
> - env->exception.fsr |= (1 << 11);
> + fsr = 0x1;
> }
> + fsc = 0x21;
>
> - syn = merge_syn_data_abort(env->exception.syndrome, target_el,
> - same_el, 0, access_type == MMU_DATA_STORE,
> - 0x21);
> - raise_exception(env, EXCP_DATA_ABORT, syn, target_el);
> + deliver_fault(cpu, vaddr, access_type, fsr, fsc, &fi);
> }
>
> #endif /* !defined(CONFIG_USER_ONLY) */
> --
> 2.7.4
>
>
next prev parent reply other threads:[~2017-08-05 1:41 UTC|newest]
Thread overview: 71+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-08-04 17:20 [Qemu-arm] [PATCH 0/8] Implement ARM external abort handling Peter Maydell
2017-08-04 17:20 ` [Qemu-devel] " Peter Maydell
2017-08-04 17:20 ` [Qemu-arm] [PATCH 1/8] memory.h: Move MemTxResult type to memattrs.h Peter Maydell
2017-08-04 17:20 ` [Qemu-devel] " Peter Maydell
2017-08-04 17:47 ` [Qemu-arm] " Richard Henderson
2017-08-04 17:47 ` [Qemu-devel] " Richard Henderson
2017-08-05 0:59 ` [Qemu-arm] " Edgar E. Iglesias
2017-08-05 0:59 ` [Qemu-devel] " Edgar E. Iglesias
2017-08-07 23:11 ` [Qemu-arm] [Qemu-devel] " Alistair Francis
2017-08-07 23:11 ` [Qemu-devel] [Qemu-arm] " Alistair Francis
2017-08-04 17:20 ` [Qemu-arm] [PATCH 2/8] cpu: Define new cpu_transaction_failed() hook Peter Maydell
2017-08-04 17:20 ` [Qemu-devel] " Peter Maydell
2017-08-04 18:42 ` [Qemu-arm] " Richard Henderson
2017-08-04 18:42 ` [Qemu-devel] " Richard Henderson
2017-08-05 1:06 ` [Qemu-arm] " Edgar E. Iglesias
2017-08-05 1:06 ` [Qemu-devel] " Edgar E. Iglesias
2017-08-05 16:51 ` Peter Maydell
2017-08-05 16:51 ` [Qemu-devel] " Peter Maydell
2017-08-05 1:12 ` Edgar E. Iglesias
2017-08-05 1:12 ` [Qemu-devel] " Edgar E. Iglesias
2017-08-05 17:18 ` Peter Maydell
2017-08-05 17:18 ` [Qemu-devel] " Peter Maydell
2017-08-04 17:20 ` [Qemu-arm] [PATCH 3/8] cputlb: Support generating CPU exceptions on memory transaction failures Peter Maydell
2017-08-04 17:20 ` [Qemu-devel] " Peter Maydell
2017-08-05 1:15 ` [Qemu-arm] " Edgar E. Iglesias
2017-08-05 1:15 ` [Qemu-devel] " Edgar E. Iglesias
2017-12-13 16:39 ` Peter Maydell
2017-12-13 16:39 ` [Qemu-devel] " Peter Maydell
2017-12-14 9:03 ` Paolo Bonzini
2017-12-14 9:03 ` [Qemu-devel] " Paolo Bonzini
2017-08-04 17:20 ` [Qemu-arm] [PATCH 4/8] boards.h: Define new flag ignore_memory_transaction_failures Peter Maydell
2017-08-04 17:20 ` [Qemu-devel] " Peter Maydell
2017-08-04 18:09 ` [Qemu-arm] " Philippe Mathieu-Daudé
2017-08-04 18:09 ` [Qemu-devel] " Philippe Mathieu-Daudé
2017-08-04 19:23 ` Richard Henderson
2017-08-05 10:13 ` Peter Maydell
2017-08-05 10:13 ` Peter Maydell
2017-08-17 10:25 ` Peter Maydell
2017-08-17 10:25 ` [Qemu-devel] " Peter Maydell
2017-08-22 3:45 ` Philippe Mathieu-Daudé
2017-08-22 3:45 ` [Qemu-devel] " Philippe Mathieu-Daudé
2017-08-22 8:36 ` Peter Maydell
2017-08-22 8:36 ` [Qemu-devel] " Peter Maydell
[not found] ` <CAFEAcA_rSqsrfd_qJijtPFRe1qKEA=JiyHE+3J5atAgxAX8NBg@mail.gmail.com>
2017-08-24 20:28 ` Richard Henderson
2017-08-25 12:02 ` Peter Maydell
2017-08-05 10:29 ` Peter Maydell
2017-08-05 10:29 ` [Qemu-devel] " Peter Maydell
2017-08-05 1:23 ` Edgar E. Iglesias
2017-08-05 1:23 ` [Qemu-devel] " Edgar E. Iglesias
2017-08-04 17:20 ` [Qemu-arm] [PATCH 5/8] hw/arm: Set ignore_memory_transaction_failures for most ARM boards Peter Maydell
2017-08-04 17:20 ` [Qemu-devel] " Peter Maydell
2017-08-05 1:24 ` [Qemu-arm] " Edgar E. Iglesias
2017-08-05 1:24 ` [Qemu-devel] " Edgar E. Iglesias
2017-08-04 17:20 ` [Qemu-arm] [PATCH 6/8] target/arm: Factor out fault delivery code Peter Maydell
2017-08-04 17:20 ` [Qemu-devel] " Peter Maydell
2017-08-04 20:10 ` [Qemu-arm] " Richard Henderson
2017-08-04 20:10 ` [Qemu-devel] " Richard Henderson
2017-08-05 1:40 ` Edgar E. Iglesias [this message]
2017-08-05 1:40 ` [Qemu-devel] [Qemu-arm] " Edgar E. Iglesias
2017-08-04 17:20 ` [Qemu-arm] [PATCH 7/8] target/arm: Allow deliver_fault() caller to specify EA bit Peter Maydell
2017-08-04 17:20 ` [Qemu-devel] " Peter Maydell
2017-08-04 20:15 ` [Qemu-arm] " Richard Henderson
2017-08-04 20:15 ` [Qemu-devel] " Richard Henderson
2017-08-05 1:45 ` [Qemu-devel] [Qemu-arm] " Edgar E. Iglesias
2017-08-05 1:45 ` Edgar E. Iglesias
2017-08-04 17:20 ` [Qemu-arm] [PATCH 8/8] target/arm: Implement new do_transaction_failed hook Peter Maydell
2017-08-04 17:20 ` [Qemu-devel] " Peter Maydell
2017-08-04 20:26 ` [Qemu-arm] " Richard Henderson
2017-08-04 20:26 ` [Qemu-devel] " Richard Henderson
2017-08-05 1:44 ` [Qemu-arm] " Edgar E. Iglesias
2017-08-05 1:44 ` [Qemu-devel] " Edgar E. Iglesias
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170805014045.GE4859@toto \
--to=edgar.iglesias@gmail.com \
--cc=patches@linaro.org \
--cc=peter.maydell@linaro.org \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=rth@twiddle.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.