From: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
To: Peter Maydell <peter.maydell@linaro.org>
Cc: "Rob Herring" <rob.herring@linaro.org>,
"Patch Tracking" <patches@linaro.org>,
"Michael Matz" <matz@suse.de>,
"Claudio Fontana" <claudio.fontana@huawei.com>,
"Alexander Graf" <agraf@suse.de>,
"qemu-devel@nongnu.org Developers" <qemu-devel@nongnu.org>,
"Laurent Desnogues" <laurent.desnogues@gmail.com>,
"Dirk Mueller" <dmueller@suse.de>,
"Will Newton" <will.newton@linaro.org>,
"Alex Bennée" <alex.bennee@linaro.org>,
"kvmarm@lists.cs.columbia.edu" <kvmarm@lists.cs.columbia.edu>,
"Christoffer Dall" <christoffer.dall@linaro.org>,
"Richard Henderson" <rth@twiddle.net>
Subject: Re: [Qemu-devel] [PATCH v4 03/21] target-arm: Define exception record for AArch64 exceptions
Date: Mon, 17 Mar 2014 12:53:10 +1000 [thread overview]
Message-ID: <CAEgOgz6v0XdfgO9pQiKKex2+UEnSm3Unk3T6d=8GCtWdWSnWqQ@mail.gmail.com> (raw)
In-Reply-To: <1394134385-1727-4-git-send-email-peter.maydell@linaro.org>
On Fri, Mar 7, 2014 at 5:32 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> For AArch32 exceptions, the only information provided about
> the cause of an exception is the individual exception type (data
> abort, undef, etc), which we store in env->exception_index. For
> AArch64, the CPU provides much more detail about the cause of
> the exception, which can be found in the syndrome register.
> Create a set of fields in CPUARMState which must be filled in
> whenever an exception is raised, so that exception entry can
> correctly fill in the syndrome register for the guest.
> This includes the information which in AArch32 appears in
> the DFAR and IFAR (fault address registers) and the DFSR
> and IFSR (fault status registers) for data aborts and
> prefetch aborts, since if we end up taking the MMU fault
> to AArch64 rather than AArch32 this will need to end up
> in different system registers.
>
> This patch does a refactoring which moves the setting of the
> AArch32 DFAR/DFSR/IFAR/IFSR from the point where the exception
> is raised to the point where it is taken. (This is no change
> for cores with an MMU, retains the existing clearly incorrect
> behaviour for ARM946 of trashing the MP access permissions
> registers which share the c5_data and c5_insn state fields,
> and has no effect for v7M because we don't implement its
> MPU fault status or address registers.)
>
> As a side effect of the cleanup we fix a bug in the AArch64
> linux-user mode code where we were passing a 64 bit fault
> address through the 32 bit c6_data/c6_insn fields: it now
> goes via the always-64-bit exception.vaddress.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
> ---
> linux-user/main.c | 56 ++++++++++++++++++++++------------------------------
> target-arm/cpu.h | 15 ++++++++++++++
> target-arm/helper.c | 23 ++++++++++++---------
> target-arm/machine.c | 3 +++
> 4 files changed, 56 insertions(+), 41 deletions(-)
>
> diff --git a/linux-user/main.c b/linux-user/main.c
> index 9192977..a17ee47 100644
> --- a/linux-user/main.c
> +++ b/linux-user/main.c
> @@ -483,17 +483,17 @@ static void arm_kernel_cmpxchg64_helper(CPUARMState *env)
> addr = env->regs[2];
>
> if (get_user_u64(oldval, env->regs[0])) {
> - env->cp15.c6_data = env->regs[0];
> + env->exception.vaddress = env->regs[0];
> goto segv;
> };
>
> if (get_user_u64(newval, env->regs[1])) {
> - env->cp15.c6_data = env->regs[1];
> + env->exception.vaddress = env->regs[1];
> goto segv;
> };
>
> if (get_user_u64(val, addr)) {
> - env->cp15.c6_data = addr;
> + env->exception.vaddress = addr;
> goto segv;
> }
>
> @@ -501,7 +501,7 @@ static void arm_kernel_cmpxchg64_helper(CPUARMState *env)
> val = newval;
>
> if (put_user_u64(val, addr)) {
> - env->cp15.c6_data = addr;
> + env->exception.vaddress = addr;
> goto segv;
> };
>
> @@ -523,7 +523,7 @@ segv:
> info.si_errno = 0;
> /* XXX: check env->error_code */
> info.si_code = TARGET_SEGV_MAPERR;
> - info._sifields._sigfault._addr = env->cp15.c6_data;
> + info._sifields._sigfault._addr = env->exception.vaddress;
> queue_signal(env, info.si_signo, &info);
>
> end_exclusive();
> @@ -620,14 +620,14 @@ static int do_strex(CPUARMState *env)
> abort();
> }
> if (segv) {
> - env->cp15.c6_data = addr;
> + env->exception.vaddress = addr;
> goto done;
> }
> if (size == 3) {
> uint32_t valhi;
> segv = get_user_u32(valhi, addr + 4);
> if (segv) {
> - env->cp15.c6_data = addr + 4;
> + env->exception.vaddress = addr + 4;
> goto done;
> }
> val = deposit64(val, 32, 32, valhi);
> @@ -650,14 +650,14 @@ static int do_strex(CPUARMState *env)
> break;
> }
> if (segv) {
> - env->cp15.c6_data = addr;
> + env->exception.vaddress = addr;
> goto done;
> }
> if (size == 3) {
> val = env->regs[(env->exclusive_info >> 12) & 0xf];
> segv = put_user_u32(val, addr + 4);
> if (segv) {
> - env->cp15.c6_data = addr + 4;
> + env->exception.vaddress = addr + 4;
> goto done;
> }
> }
> @@ -832,12 +832,14 @@ void cpu_loop(CPUARMState *env)
> case EXCP_INTERRUPT:
> /* just indicate that signals should be handled asap */
> break;
> + case EXCP_STREX:
> + if (!do_strex(env)) {
> + break;
> + }
> + /* fall through for segv */
> case EXCP_PREFETCH_ABORT:
> - addr = env->cp15.c6_insn;
> - goto do_segv;
> case EXCP_DATA_ABORT:
> - addr = env->cp15.c6_data;
> - do_segv:
> + addr = env->exception.vaddress;
> {
> info.si_signo = SIGSEGV;
> info.si_errno = 0;
> @@ -865,12 +867,6 @@ void cpu_loop(CPUARMState *env)
> if (do_kernel_trap(env))
> goto error;
> break;
> - case EXCP_STREX:
> - if (do_strex(env)) {
> - addr = env->cp15.c6_data;
> - goto do_segv;
> - }
> - break;
> default:
> error:
> fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
> @@ -933,7 +929,7 @@ static int do_strex_a64(CPUARMState *env)
> abort();
> }
> if (segv) {
> - env->cp15.c6_data = addr;
> + env->exception.vaddress = addr;
> goto error;
> }
> if (val != env->exclusive_val) {
> @@ -946,7 +942,7 @@ static int do_strex_a64(CPUARMState *env)
> segv = get_user_u64(val, addr + 8);
> }
> if (segv) {
> - env->cp15.c6_data = addr + (size == 2 ? 4 : 8);
> + env->exception.vaddress = addr + (size == 2 ? 4 : 8);
> goto error;
> }
> if (val != env->exclusive_high) {
> @@ -981,7 +977,7 @@ static int do_strex_a64(CPUARMState *env)
> segv = put_user_u64(val, addr + 8);
> }
> if (segv) {
> - env->cp15.c6_data = addr + (size == 2 ? 4 : 8);
> + env->exception.vaddress = addr + (size == 2 ? 4 : 8);
> goto error;
> }
> }
> @@ -1037,12 +1033,14 @@ void cpu_loop(CPUARMState *env)
> info._sifields._sigfault._addr = env->pc;
> queue_signal(env, info.si_signo, &info);
> break;
> + case EXCP_STREX:
> + if (!do_strex_a64(env)) {
> + break;
> + }
> + /* fall through for segv */
> case EXCP_PREFETCH_ABORT:
> - addr = env->cp15.c6_insn;
> - goto do_segv;
> case EXCP_DATA_ABORT:
> - addr = env->cp15.c6_data;
> - do_segv:
> + addr = env->exception.vaddress;
> info.si_signo = SIGSEGV;
> info.si_errno = 0;
> /* XXX: check env->error_code */
> @@ -1060,12 +1058,6 @@ void cpu_loop(CPUARMState *env)
> queue_signal(env, info.si_signo, &info);
> }
> break;
> - case EXCP_STREX:
> - if (do_strex_a64(env)) {
> - addr = env->cp15.c6_data;
> - goto do_segv;
> - }
> - break;
> default:
> fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
> trapnr);
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 45eb6a2..9982e47 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -229,6 +229,21 @@ typedef struct CPUARMState {
> int pending_exception;
> } v7m;
>
> + /* Information associated with an exception about to be taken:
> + * code which raises an exception must set env->exception_index and
> + * the relevant parts of this structure; the cpu_do_interrupt function
> + * will then set the guest-visible registers as part of the exception
> + * entry process.
> + */
> + struct {
> + uint32_t syndrome; /* AArch64 format syndrome register */
> + uint32_t fsr; /* AArch32 format fault status register info */
> + uint64_t vaddress; /* virtual addr associated with exception, if any */
> + /* If we implement EL2 we will also need to store information
> + * about the intermediate physical address for stage 2 faults.
> + */
> + } exception;
> +
> /* Thumb-2 EE state. */
> uint32_t teecr;
> uint32_t teehbr;
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index f7168c1..2fa01ae 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -2610,12 +2610,11 @@ void arm_cpu_do_interrupt(CPUState *cs)
> int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address, int rw,
> int mmu_idx)
> {
> + env->exception.vaddress = address;
> if (rw == 2) {
> env->exception_index = EXCP_PREFETCH_ABORT;
> - env->cp15.c6_insn = address;
> } else {
> env->exception_index = EXCP_DATA_ABORT;
> - env->cp15.c6_data = address;
> }
> return 1;
> }
> @@ -2820,6 +2819,9 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
> return;
> case EXCP_PREFETCH_ABORT:
> case EXCP_DATA_ABORT:
> + /* TODO: if we implemented the MPU registers, this is where we
> + * should set the MMFAR, etc from exception.fsr and exception.vaddress.
> + */
> armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM);
> return;
> case EXCP_BKPT:
> @@ -2934,9 +2936,11 @@ void arm_cpu_do_interrupt(CPUState *cs)
> return;
> }
> }
> - env->cp15.c5_insn = 2;
> + env->exception.fsr = 2;
> /* Fall through to prefetch abort. */
> case EXCP_PREFETCH_ABORT:
> + env->cp15.c5_insn = env->exception.fsr;
> + env->cp15.c6_insn = env->exception.vaddress;
> qemu_log_mask(CPU_LOG_INT, "...with IFSR 0x%x IFAR 0x%x\n",
> env->cp15.c5_insn, env->cp15.c6_insn);
> new_mode = ARM_CPU_MODE_ABT;
> @@ -2945,6 +2949,8 @@ void arm_cpu_do_interrupt(CPUState *cs)
> offset = 4;
> break;
> case EXCP_DATA_ABORT:
> + env->cp15.c5_data = env->exception.fsr;
> + env->cp15.c6_data = env->exception.vaddress;
> qemu_log_mask(CPU_LOG_INT, "...with DFSR 0x%x DFAR 0x%x\n",
> env->cp15.c5_data, env->cp15.c6_data);
> new_mode = ARM_CPU_MODE_ABT;
> @@ -3593,16 +3599,15 @@ int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address,
> }
>
> if (access_type == 2) {
> - env->cp15.c5_insn = ret;
> - env->cp15.c6_insn = address;
> env->exception_index = EXCP_PREFETCH_ABORT;
> } else {
> - env->cp15.c5_data = ret;
> - if (access_type == 1 && arm_feature(env, ARM_FEATURE_V6))
> - env->cp15.c5_data |= (1 << 11);
> - env->cp15.c6_data = address;
> + if (access_type == 1 && arm_feature(env, ARM_FEATURE_V6)) {
> + ret |= (1 << 11);
> + }
> env->exception_index = EXCP_DATA_ABORT;
> }
> + env->exception.vaddress = address;
> + env->exception.fsr = ret;
> return 1;
> }
>
> diff --git a/target-arm/machine.c b/target-arm/machine.c
> index 8f9e7d4..fc8825e 100644
> --- a/target-arm/machine.c
> +++ b/target-arm/machine.c
> @@ -257,6 +257,9 @@ const VMStateDescription vmstate_arm_cpu = {
> VMSTATE_UINT64(env.exclusive_val, ARMCPU),
> VMSTATE_UINT64(env.exclusive_high, ARMCPU),
> VMSTATE_UINT64(env.features, ARMCPU),
> + VMSTATE_UINT32(env.exception.syndrome, ARMCPU),
> + VMSTATE_UINT32(env.exception.fsr, ARMCPU),
> + VMSTATE_UINT64(env.exception.vaddress, ARMCPU),
> VMSTATE_TIMER(gt_timer[GTIMER_PHYS], ARMCPU),
> VMSTATE_TIMER(gt_timer[GTIMER_VIRT], ARMCPU),
> VMSTATE_END_OF_LIST()
> --
> 1.9.0
>
>
next prev parent reply other threads:[~2014-03-17 2:53 UTC|newest]
Thread overview: 58+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-03-06 19:32 [Qemu-devel] [PATCH v4 00/21] AArch64 system emulation (boots a kernel!) Peter Maydell
2014-03-06 19:32 ` [Qemu-devel] [PATCH v4 01/21] target-arm: Split out private-to-target functions into internals.h Peter Maydell
2014-03-17 7:13 ` Peter Crosthwaite
2014-03-06 19:32 ` [Qemu-devel] [PATCH v4 02/21] target-arm: Implement AArch64 DAIF system register Peter Maydell
2014-03-17 2:30 ` Peter Crosthwaite
2014-03-06 19:32 ` [Qemu-devel] [PATCH v4 03/21] target-arm: Define exception record for AArch64 exceptions Peter Maydell
2014-03-17 2:53 ` Peter Crosthwaite [this message]
2014-03-06 19:32 ` [Qemu-devel] [PATCH v4 04/21] target-arm: Provide correct syndrome information for cpreg access traps Peter Maydell
2014-03-17 3:05 ` Peter Crosthwaite
2014-03-17 12:32 ` Peter Maydell
2014-03-06 19:32 ` [Qemu-devel] [PATCH v4 05/21] target-arm: Add support for generating exceptions with syndrome information Peter Maydell
2014-03-17 3:19 ` Peter Crosthwaite
2014-03-17 12:40 ` Peter Maydell
2014-03-06 19:32 ` [Qemu-devel] [PATCH v4 06/21] target-arm: Provide syndrome information for MMU faults Peter Maydell
2014-03-17 3:28 ` Peter Crosthwaite
2014-03-17 12:41 ` Peter Maydell
2014-03-17 12:50 ` Peter Maydell
2014-03-06 19:32 ` [Qemu-devel] [PATCH v4 07/21] target-arm: A64: Correctly fault FP/Neon if CPACR.FPEN set Peter Maydell
2014-03-06 19:32 ` [Qemu-devel] [PATCH v4 08/21] target-arm: A64: Add assertion that FP access was checked Peter Maydell
2014-03-06 19:32 ` [Qemu-devel] [PATCH v4 09/21] target-arm: Fix VFP enables for AArch32 EL0 under AArch64 EL1 Peter Maydell
2014-03-06 19:32 ` [Qemu-devel] [PATCH v4 10/21] target-arm: Add v8 mmu translation support Peter Maydell
2014-03-20 18:20 ` Peter Maydell
2014-03-06 19:32 ` [Qemu-devel] [PATCH v4 11/21] target-arm: Don't mention PMU in debug feature register Peter Maydell
2014-03-17 5:13 ` Peter Crosthwaite
2014-03-17 12:58 ` Peter Maydell
2014-03-17 13:11 ` Peter Crosthwaite
2014-03-06 19:32 ` [Qemu-devel] [PATCH v4 12/21] target-arm: A64: Implement DC ZVA Peter Maydell
2014-03-07 14:51 ` Richard Henderson
2014-03-07 15:11 ` Peter Maydell
2014-03-07 15:25 ` Richard Henderson
2014-03-07 15:40 ` Richard Henderson
2014-03-06 19:32 ` [Qemu-devel] [PATCH v4 13/21] target-arm: Use dedicated CPU state fields for ARM946 access bit registers Peter Maydell
2014-03-17 5:20 ` Peter Crosthwaite
2014-03-17 13:03 ` Peter Maydell
2014-03-06 19:32 ` [Qemu-devel] [PATCH v4 14/21] target-arm: Implement AArch64 views of fault status and data registers Peter Maydell
2014-03-17 5:30 ` Peter Crosthwaite
2014-03-17 13:06 ` Peter Maydell
2014-03-17 13:17 ` Peter Crosthwaite
2014-03-06 19:32 ` [Qemu-devel] [PATCH v4 15/21] target-arm: Add AArch64 ELR_EL1 register Peter Maydell
2014-03-17 5:33 ` Peter Crosthwaite
2014-03-06 19:33 ` [Qemu-devel] [PATCH v4 16/21] target-arm: Implement SP_EL0, SP_EL1 Peter Maydell
2014-03-17 7:02 ` Peter Crosthwaite
2014-03-17 7:31 ` Peter Crosthwaite
2014-03-20 17:12 ` Peter Maydell
2014-03-06 19:33 ` [Qemu-devel] [PATCH v4 17/21] target-arm: Implement AArch64 SPSR_EL1 Peter Maydell
2014-03-06 19:33 ` [Qemu-devel] [PATCH v4 18/21] target-arm: Move arm_log_exception() into internals.h Peter Maydell
2014-03-17 7:04 ` Peter Crosthwaite
2014-03-06 19:33 ` [Qemu-devel] [PATCH v4 19/21] target-arm: Implement AArch64 EL1 exception handling Peter Maydell
2014-03-06 19:33 ` [Qemu-devel] [PATCH v4 20/21] target-arm: Add Cortex-A57 processor Peter Maydell
2014-03-20 19:18 ` Peter Maydell
2014-03-26 2:34 ` Rob Herring
2014-03-06 19:33 ` [Qemu-devel] [PATCH v4 21/21] hw/arm/virt: Add support for Cortex-A57 Peter Maydell
2014-03-17 7:12 ` Peter Crosthwaite
2014-04-10 15:02 ` Peter Maydell
2014-04-10 19:41 ` Rob Herring
2014-04-10 21:16 ` Peter Maydell
2014-03-07 4:09 ` [Qemu-devel] [PATCH v4 00/21] AArch64 system emulation (boots a kernel!) Xuebing Wang
2014-03-07 8:47 ` Peter Maydell
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='CAEgOgz6v0XdfgO9pQiKKex2+UEnSm3Unk3T6d=8GCtWdWSnWqQ@mail.gmail.com' \
--to=peter.crosthwaite@xilinx.com \
--cc=agraf@suse.de \
--cc=alex.bennee@linaro.org \
--cc=christoffer.dall@linaro.org \
--cc=claudio.fontana@huawei.com \
--cc=dmueller@suse.de \
--cc=kvmarm@lists.cs.columbia.edu \
--cc=laurent.desnogues@gmail.com \
--cc=matz@suse.de \
--cc=patches@linaro.org \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=rob.herring@linaro.org \
--cc=rth@twiddle.net \
--cc=will.newton@linaro.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).