From: Peter Maydell <peter.maydell@linaro.org>
To: Richard Henderson <richard.henderson@linaro.org>
Cc: qemu-arm <qemu-arm@nongnu.org>, QEMU Developers <qemu-devel@nongnu.org>
Subject: Re: [PATCH v5 1/9] target/arm: Fix mte_checkN
Date: Mon, 19 Apr 2021 17:26:44 +0100 [thread overview]
Message-ID: <CAFEAcA_XdxxuDSi7nwwB2JPMYFDxJYWv7fv1f-ySuwWnTmVaLg@mail.gmail.com> (raw)
In-Reply-To: <20210416183106.1516563-2-richard.henderson@linaro.org>
On Fri, 16 Apr 2021 at 19:31, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> We were incorrectly assuming that only the first byte of an MTE access
> is checked against the tags. But per the ARM, unaligned accesses are
> pre-decomposed into single-byte accesses. So by the time we reach the
> actual MTE check in the ARM pseudocode, all accesses are aligned.
>
> Therefore, the first failure is always either the first byte of the
> access, or the first byte of the granule.
>
> In addition, some of the arithmetic is off for last-first -> count.
> This does not become directly visible until a later patch that passes
> single bytes into this function, so ptr == ptr_last.
>
> Buglink: https://bugs.launchpad.net/bugs/1921948
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/arm/mte_helper.c | 38 +++++++++++++++++---------------------
> 1 file changed, 17 insertions(+), 21 deletions(-)
>
> diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
> index 8be17e1b70..c87717127c 100644
> --- a/target/arm/mte_helper.c
> +++ b/target/arm/mte_helper.c
> @@ -757,10 +757,10 @@ uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
> uint64_t ptr, uintptr_t ra)
> {
> int mmu_idx, ptr_tag, bit55;
> - uint64_t ptr_last, ptr_end, prev_page, next_page;
> - uint64_t tag_first, tag_end;
> - uint64_t tag_byte_first, tag_byte_end;
> - uint32_t esize, total, tag_count, tag_size, n, c;
> + uint64_t ptr_last, prev_page, next_page;
> + uint64_t tag_first, tag_last;
> + uint64_t tag_byte_first, tag_byte_last;
> + uint32_t total, tag_count, tag_size, n, c;
> uint8_t *mem1, *mem2;
> MMUAccessType type;
>
> @@ -779,29 +779,27 @@ uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
>
> mmu_idx = FIELD_EX32(desc, MTEDESC, MIDX);
> type = FIELD_EX32(desc, MTEDESC, WRITE) ? MMU_DATA_STORE : MMU_DATA_LOAD;
> - esize = FIELD_EX32(desc, MTEDESC, ESIZE);
> total = FIELD_EX32(desc, MTEDESC, TSIZE);
>
> /* Find the addr of the end of the access, and of the last element. */
> - ptr_end = ptr + total;
> - ptr_last = ptr_end - esize;
> + ptr_last = ptr + total - 1;
Code change means the comment needs updating, since we're no longer
finding two things. Change to just
/* Find the addr of the end of the access */
?
>
> /* Round the bounds to the tag granule, and compute the number of tags. */
> tag_first = QEMU_ALIGN_DOWN(ptr, TAG_GRANULE);
> - tag_end = QEMU_ALIGN_UP(ptr_last, TAG_GRANULE);
> - tag_count = (tag_end - tag_first) / TAG_GRANULE;
> + tag_last = QEMU_ALIGN_DOWN(ptr_last, TAG_GRANULE);
> + tag_count = ((tag_last - tag_first) / TAG_GRANULE) + 1;
>
> /* Round the bounds to twice the tag granule, and compute the bytes. */
> tag_byte_first = QEMU_ALIGN_DOWN(ptr, 2 * TAG_GRANULE);
> - tag_byte_end = QEMU_ALIGN_UP(ptr_last, 2 * TAG_GRANULE);
> + tag_byte_last = QEMU_ALIGN_DOWN(ptr_last, 2 * TAG_GRANULE);
>
> /* Locate the page boundaries. */
> prev_page = ptr & TARGET_PAGE_MASK;
> next_page = prev_page + TARGET_PAGE_SIZE;
>
> - if (likely(tag_end - prev_page <= TARGET_PAGE_SIZE)) {
> + if (likely(tag_last - prev_page <= TARGET_PAGE_SIZE)) {
> /* Memory access stays on one page. */
> - tag_size = (tag_byte_end - tag_byte_first) / (2 * TAG_GRANULE);
> + tag_size = ((tag_byte_last - tag_byte_first) / (2 * TAG_GRANULE)) + 1;
> mem1 = allocation_tag_mem(env, mmu_idx, ptr, type, total,
> MMU_DATA_LOAD, tag_size, ra);
> if (!mem1) {
> @@ -815,9 +813,9 @@ uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
> mem1 = allocation_tag_mem(env, mmu_idx, ptr, type, next_page - ptr,
> MMU_DATA_LOAD, tag_size, ra);
>
> - tag_size = (tag_byte_end - next_page) / (2 * TAG_GRANULE);
> + tag_size = ((tag_byte_last - next_page) / (2 * TAG_GRANULE)) + 1;
> mem2 = allocation_tag_mem(env, mmu_idx, next_page, type,
> - ptr_end - next_page,
> + ptr_last - next_page + 1,
> MMU_DATA_LOAD, tag_size, ra);
>
> /*
> @@ -838,15 +836,13 @@ uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
> }
>
> /*
> - * If we failed, we know which granule. Compute the element that
> - * is first in that granule, and signal failure on that element.
> + * If we failed, we know which granule. For the first granule, the
> + * failure address is @ptr, the first byte accessed. Otherwise the
> + * failure address is the first byte of the nth granule.
> */
> if (unlikely(n < tag_count)) {
> - uint64_t fail_ofs;
> -
> - fail_ofs = tag_first + n * TAG_GRANULE - ptr;
> - fail_ofs = ROUND_UP(fail_ofs, esize);
> - mte_check_fail(env, desc, ptr + fail_ofs, ra);
> + uint64_t fault = (n == 0 ? ptr : tag_first + n * TAG_GRANULE);
> + mte_check_fail(env, desc, fault, ra);
> }
>
This pointer arithmetic makes my head hurt. But I think it's right now.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
thanks
-- PMM
next prev parent reply other threads:[~2021-04-19 16:28 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-04-16 18:30 [PATCH v5 for-6.1 0/9] target/arm mte fixes Richard Henderson
2021-04-16 18:30 ` [PATCH v5 1/9] target/arm: Fix mte_checkN Richard Henderson
2021-04-19 16:26 ` Peter Maydell [this message]
2021-04-19 17:39 ` Richard Henderson
2021-04-16 18:30 ` [PATCH v5 2/9] target/arm: Split out mte_probe_int Richard Henderson
2021-04-19 16:28 ` Peter Maydell
2021-04-16 18:31 ` [PATCH v5 3/9] target/arm: Fix unaligned checks for mte_check1, mte_probe1 Richard Henderson
2021-04-16 18:31 ` [PATCH v5 4/9] test/tcg/aarch64: Add mte-5 Richard Henderson
2021-04-16 18:31 ` [PATCH v5 5/9] target/arm: Replace MTEDESC ESIZE+TSIZE with SIZEM1 Richard Henderson
2021-04-16 18:31 ` [PATCH v5 6/9] target/arm: Merge mte_check1, mte_checkN Richard Henderson
2021-04-16 18:31 ` [PATCH v5 7/9] target/arm: Rename mte_probe1 to mte_probe Richard Henderson
2021-04-16 18:31 ` [PATCH v5 8/9] target/arm: Simplify sve mte checking Richard Henderson
2021-04-16 18:31 ` [PATCH v5 9/9] target/arm: Remove log2_esize parameter to gen_mte_checkN Richard Henderson
2021-04-16 18:45 ` [PATCH v5 for-6.1 0/9] target/arm mte fixes no-reply
2021-04-19 16:41 ` 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=CAFEAcA_XdxxuDSi7nwwB2JPMYFDxJYWv7fv1f-ySuwWnTmVaLg@mail.gmail.com \
--to=peter.maydell@linaro.org \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=richard.henderson@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).