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 3/8] cputlb: Support generating CPU exceptions on memory transaction failures
Date: Sat, 5 Aug 2017 03:15:52 +0200 [thread overview]
Message-ID: <20170805011551.GB4859@toto> (raw)
In-Reply-To: <1501867249-1924-4-git-send-email-peter.maydell@linaro.org>
On Fri, Aug 04, 2017 at 06:20:44PM +0100, Peter Maydell wrote:
> Call the new cpu_transaction_failed() hook at the places where
> CPU generated code interacts with the memory system:
> io_readx()
> io_writex()
> get_page_addr_code()
>
> Any access from C code (eg via cpu_physical_memory_rw(),
> address_space_rw(), ld/st_*_phys()) will *not* trigger CPU exceptions
> via cpu_transaction_failed(). Handling for transactions failures for
> this kind of call should be done by using a function which returns a
> MemTxResult and treating the failure case appropriately in the
> calling code.
>
> In an ideal world we would not generate CPU exceptions for
> instruction fetch failures in get_page_addr_code() but instead wait
> until the code translation process tried a load and it failed;
> however that change would require too great a restructuring and
> redesign to attempt at this point.
You're right but onsidering the lack of models for I caches and
prefetching, I don't think that matters much...
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
> softmmu_template.h | 4 ++--
> accel/tcg/cputlb.c | 32 ++++++++++++++++++++++++++++++--
> 2 files changed, 32 insertions(+), 4 deletions(-)
>
> diff --git a/softmmu_template.h b/softmmu_template.h
> index 4a2b665..d756329 100644
> --- a/softmmu_template.h
> +++ b/softmmu_template.h
> @@ -101,7 +101,7 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
> uintptr_t retaddr)
> {
> CPUIOTLBEntry *iotlbentry = &env->iotlb[mmu_idx][index];
> - return io_readx(env, iotlbentry, addr, retaddr, DATA_SIZE);
> + return io_readx(env, iotlbentry, mmu_idx, addr, retaddr, DATA_SIZE);
> }
> #endif
>
> @@ -262,7 +262,7 @@ static inline void glue(io_write, SUFFIX)(CPUArchState *env,
> uintptr_t retaddr)
> {
> CPUIOTLBEntry *iotlbentry = &env->iotlb[mmu_idx][index];
> - return io_writex(env, iotlbentry, val, addr, retaddr, DATA_SIZE);
> + return io_writex(env, iotlbentry, mmu_idx, val, addr, retaddr, DATA_SIZE);
> }
>
> void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
> diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
> index 85635ae..e72415a 100644
> --- a/accel/tcg/cputlb.c
> +++ b/accel/tcg/cputlb.c
> @@ -747,6 +747,7 @@ static inline ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr)
> }
>
> static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
> + int mmu_idx,
> target_ulong addr, uintptr_t retaddr, int size)
> {
> CPUState *cpu = ENV_GET_CPU(env);
> @@ -754,6 +755,7 @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
> MemoryRegion *mr = iotlb_to_region(cpu, physaddr, iotlbentry->attrs);
> uint64_t val;
> bool locked = false;
> + MemTxResult r;
>
> physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
> cpu->mem_io_pc = retaddr;
> @@ -767,7 +769,12 @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
> qemu_mutex_lock_iothread();
> locked = true;
> }
> - memory_region_dispatch_read(mr, physaddr, &val, size, iotlbentry->attrs);
> + r = memory_region_dispatch_read(mr, physaddr,
> + &val, size, iotlbentry->attrs);
> + if (r != MEMTX_OK) {
> + cpu_transaction_failed(cpu, physaddr, addr, size, MMU_DATA_LOAD,
> + mmu_idx, iotlbentry->attrs, r, retaddr);
> + }
> if (locked) {
> qemu_mutex_unlock_iothread();
> }
> @@ -776,6 +783,7 @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
> }
>
> static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
> + int mmu_idx,
> uint64_t val, target_ulong addr,
> uintptr_t retaddr, int size)
> {
> @@ -783,6 +791,7 @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
> hwaddr physaddr = iotlbentry->addr;
> MemoryRegion *mr = iotlb_to_region(cpu, physaddr, iotlbentry->attrs);
> bool locked = false;
> + MemTxResult r;
>
> physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
> if (mr != &io_mem_rom && mr != &io_mem_notdirty && !cpu->can_do_io) {
> @@ -795,7 +804,12 @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
> qemu_mutex_lock_iothread();
> locked = true;
> }
> - memory_region_dispatch_write(mr, physaddr, val, size, iotlbentry->attrs);
> + r = memory_region_dispatch_write(mr, physaddr,
> + val, size, iotlbentry->attrs);
> + if (r != MEMTX_OK) {
> + cpu_transaction_failed(cpu, physaddr, addr, size, MMU_DATA_STORE,
> + mmu_idx, iotlbentry->attrs, r, retaddr);
> + }
> if (locked) {
> qemu_mutex_unlock_iothread();
> }
> @@ -845,6 +859,7 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr)
> MemoryRegion *mr;
> CPUState *cpu = ENV_GET_CPU(env);
> CPUIOTLBEntry *iotlbentry;
> + hwaddr physaddr;
>
> index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
> mmu_idx = cpu_mmu_index(env, true);
> @@ -868,6 +883,19 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr)
> }
> qemu_mutex_unlock_iothread();
>
> + /* Give the new-style cpu_transaction_failed() hook first chance
> + * to handle this.
> + * This is not the ideal place to detect and generate CPU
> + * exceptions for instruction fetch failure (for instance
> + * we don't know the length of the access that the CPU would
> + * use, and it would be better to go ahead and try the access
> + * and use the MemTXResult it produced). However it is the
> + * simplest place we have currently available for the check.
> + */
> + physaddr = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
> + cpu_transaction_failed(cpu, physaddr, addr, 0, MMU_INST_FETCH, mmu_idx,
> + iotlbentry->attrs, MEMTX_DECODE_ERROR, 0);
> +
> cpu_unassigned_access(cpu, addr, false, true, 0, 4);
> /* The CPU's unassigned access hook might have longjumped out
> * with an exception. If it didn't (or there was no hook) then
> --
> 2.7.4
>
>
next prev parent reply other threads:[~2017-08-05 1:16 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-08-04 17:20 [Qemu-devel] [PATCH 0/8] Implement ARM external abort handling Peter Maydell
2017-08-04 17:20 ` [Qemu-devel] [PATCH 1/8] memory.h: Move MemTxResult type to memattrs.h Peter Maydell
2017-08-04 17:47 ` Richard Henderson
2017-08-05 0:59 ` [Qemu-devel] [Qemu-arm] " Edgar E. Iglesias
2017-08-07 23:11 ` Alistair Francis
2017-08-04 17:20 ` [Qemu-devel] [PATCH 2/8] cpu: Define new cpu_transaction_failed() hook Peter Maydell
2017-08-04 18:42 ` Richard Henderson
2017-08-05 1:06 ` [Qemu-devel] [Qemu-arm] " Edgar E. Iglesias
2017-08-05 16:51 ` Peter Maydell
2017-08-05 1:12 ` Edgar E. Iglesias
2017-08-05 17:18 ` Peter Maydell
2017-08-04 17:20 ` [Qemu-devel] [PATCH 3/8] cputlb: Support generating CPU exceptions on memory transaction failures Peter Maydell
2017-08-05 1:15 ` Edgar E. Iglesias [this message]
2017-12-13 16:39 ` [Qemu-devel] [Qemu-arm] " Peter Maydell
2017-12-14 9:03 ` Paolo Bonzini
2017-08-04 17:20 ` [Qemu-devel] [PATCH 4/8] boards.h: Define new flag ignore_memory_transaction_failures Peter Maydell
2017-08-04 18:09 ` [Qemu-devel] [Qemu-arm] " Philippe Mathieu-Daudé
2017-08-04 19:23 ` Richard Henderson
2017-08-05 10:13 ` Peter Maydell
2017-08-17 10:25 ` Peter Maydell
2017-08-22 3:45 ` Philippe Mathieu-Daudé
2017-08-22 8:36 ` 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 1:23 ` Edgar E. Iglesias
2017-08-04 17:20 ` [Qemu-devel] [PATCH 5/8] hw/arm: Set ignore_memory_transaction_failures for most ARM boards Peter Maydell
2017-08-05 1:24 ` [Qemu-devel] [Qemu-arm] " Edgar E. Iglesias
2017-08-04 17:20 ` [Qemu-devel] [PATCH 6/8] target/arm: Factor out fault delivery code Peter Maydell
2017-08-04 20:10 ` Richard Henderson
2017-08-05 1:40 ` [Qemu-devel] [Qemu-arm] " Edgar E. Iglesias
2017-08-04 17:20 ` [Qemu-devel] [PATCH 7/8] target/arm: Allow deliver_fault() caller to specify EA bit Peter Maydell
2017-08-04 20:15 ` Richard Henderson
2017-08-05 1:45 ` [Qemu-devel] [Qemu-arm] " Edgar E. Iglesias
2017-08-04 17:20 ` [Qemu-devel] [PATCH 8/8] target/arm: Implement new do_transaction_failed hook Peter Maydell
2017-08-04 20:26 ` Richard Henderson
2017-08-05 1:44 ` [Qemu-devel] [Qemu-arm] " 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=20170805011551.GB4859@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 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).