qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 4/4] tests/tcg/aarch64: Extend MTE gdbstub tests to system mo


From: Richard Henderson
Subject: Re: [PATCH 4/4] tests/tcg/aarch64: Extend MTE gdbstub tests to system mode
Date: Fri, 26 Jul 2024 09:17:29 +1000
User-agent: Mozilla Thunderbird

On 7/23/24 02:07, Gustavo Romero wrote:
  def run_test():
-    gdb.execute("break 95", False, True)
+    if mode == "system":
+        # Break address: where to break before performing the tests
+        # Addresss is the last insn. before 'main' returns. See mte.c
+        ba = "*main+52"

Ugly.  You can add labels in your inline asm block instead.

diff --git a/tests/tcg/aarch64/system/boot.S b/tests/tcg/aarch64/system/boot.S
index 501685d0ec..a12393d00b 100644
--- a/tests/tcg/aarch64/system/boot.S
+++ b/tests/tcg/aarch64/system/boot.S
@@ -135,11 +135,22 @@ __start:
        orr     x1, x1, x3
        str     x1, [x2]                        /* 2nd 2mb (.data & .bss)*/
+ /* Third block: .mte_page */
+       adrp    x1, .mte_page
+       add     x1, x1, :lo12:.mte_page
+       bic     x1, x1, #(1 << 21) - 1
+       and     x4, x1, x5
+       add     x2, x0, x4, lsr #(21 - 3)
+       ldr     x3, =(3 << 53) | 0x401 | 1 << 2     /* attr(AF, NX, block, 
AttrIndx=Attr1) */
+       orr     x1, x1, x3
+       str     x1, [x2]
+
        /* Setup/enable the MMU.  */
/*
         * TCR_EL1 - Translation Control Registers
         *
+        * TBI0[37] = 0b1 => Top Byte ignored and used for tagged addresses
         * IPS[34:32] = 40-bit PA, 1TB
         * TG0[14:15] = b00 => 4kb granuale
         * ORGN0[11:10] = Outer: Normal, WB Read-Alloc No Write-Alloc Cacheable
@@ -152,16 +163,22 @@ __start:
         * with at least 1gb range to see RAM. So we start with a
         * level 1 lookup.
         */
-       ldr     x0, = (2 << 32) | 25 | (3 << 10) | (3 << 8)
+       ldr     x0, = (1 << 37) | (2 << 32) | 25 | (3 << 10) | (3 << 8)
        msr     tcr_el1, x0
- mov x0, #0xee /* Inner/outer cacheable WB */
+       /*
+        * Attr0: Normal, Inner/outer cacheable WB
+        * Attr1: Tagged Normal (MTE)
+        */
+       mov     x0, #0xf0ee

Up to here, I think we're fine, no matter the emulated cpu model.

        msr     mair_el1, x0
        isb
/*
         * SCTLR_EL1 - System Control Register
         *
+        * ATA[43] = 1 = enable access to allocation tags at EL1
+        * TCF[40] = 1 = Tag Check Faults cause a synchronous exception
         * WXN[19] = 0 = no effect, Write does not imply XN (execute never)
         * I[12] = Instruction cachability control
         * SA[3] = SP alignment check
@@ -169,7 +186,8 @@ __start:
         * M[0] = 1, enable stage 1 address translation for EL0/1
         */
        mrs     x0, sctlr_el1
-       ldr     x1, =0x100d                     /* bits I(12) SA(3) C(2) M(0) */
+       /* Bits set: ATA(43) TCF(40) I(12) SA(3) C(2) M(0) */
+       ldr     x1, =(0x100d | 1 << 43 | 1 << 40)

But here, it's only legal to run this modified boot.S on -cpu max.
We should check for MTE enabled before setting those, or
set them elsewhere, e.g. in main of the specific MTE test.

@@ -239,3 +257,5 @@ ttb_stage2:
  stack:
        .space 65536, 0
  stack_end:
+
+       .section .mte_page

Why?

diff --git a/tests/tcg/aarch64/system/kernel.ld 
b/tests/tcg/aarch64/system/kernel.ld
index 7b3a76dcbf..7c00c1c378 100644
--- a/tests/tcg/aarch64/system/kernel.ld
+++ b/tests/tcg/aarch64/system/kernel.ld
@@ -18,6 +18,11 @@ SECTIONS
      .bss : {
          *(.bss)
      }
+    /* align MTE section to next (third) 2mb */
+    . = ALIGN(1 << 22);
+    .mte : {
+        *(.mte_page)
+    }

Why?

      /DISCARD/ : {
          *(.ARM.attributes)
      }
diff --git a/tests/tcg/aarch64/system/mte.c b/tests/tcg/aarch64/system/mte.c
new file mode 100644
index 0000000000..58a5ac31ff
--- /dev/null
+++ b/tests/tcg/aarch64/system/mte.c
@@ -0,0 +1,40 @@
+#include <inttypes.h>
+
+int main(void)
+{
+    uint8_t *addr;
+
+    /*
+     * Third 2MB chunk in the second 1GB block.
+     * See .mte_page section in kernel.ld.
+     */
+    addr = (void *)((1UL << 30) | (1UL << 22));

... because you're not using .mte_page here, just computing it.

+
+    asm (
+        /*
+         * Set GCR for randon tag generation. 0xA5 is just a random value to 
set

random

+         * GCR != 0 so the tag generated by 'irg' is not zero.
+         */
+        "ldr x1, =0xA5;"
+        "msr gcr_el1, x1;"

I think it might be easier to split the asm:

  asm volatile("msr gcr_el1, %0" : : "r"(0xA5));

+
+         /* Generate a logical tag and put it in 'addr' pointer. */
+         "irg %[addr], %[addr];"

  asm("irg %0,%0" : "+r"(addr));

+
+         /*
+          * Store the generated tag to memory region pointed to by 'addr', i.e.
+          * set the allocation tag for the memory region.
+          */
+         "stg %[addr], [%[addr]];"

Storing addr into addr is a titch confusing, clearer with zero?

  asm("stg xzr,[%0]" : : "r"(addr));

+
+         /*
+          * Store a random value (0xdeadbeef) to *addr. This must not cause any
+          * Tag Check Fault since logical and allocation tags are set the same.
+          */
+        "ldr x1, =0xdeadbeef;"
+        "str x1, [x0];"

Where does x0 come from?  Certainly not "addr"...
Can you use "addr" directly in the gdb script?


r~



reply via email to

[Prev in Thread] Current Thread [Next in Thread]