perf arm_spe: Fixup top byte for data virtual address
[linux-2.6-microblaze.git] / tools / perf / util / arm-spe-decoder / arm-spe-decoder.c
index 776b3e6..cac2ef7 100644 (file)
@@ -24,7 +24,7 @@
 
 static u64 arm_spe_calc_ip(int index, u64 payload)
 {
-       u64 ns, el;
+       u64 ns, el, val;
 
        /* Instruction virtual address or Branch target address */
        if (index == SPE_ADDR_PKT_HDR_INDEX_INS ||
@@ -45,8 +45,22 @@ static u64 arm_spe_calc_ip(int index, u64 payload)
                /* Clean tags */
                payload = SPE_ADDR_PKT_ADDR_GET_BYTES_0_6(payload);
 
-               /* Fill highest byte if bits [48..55] is 0xff */
-               if (SPE_ADDR_PKT_ADDR_GET_BYTE_6(payload) == 0xffULL)
+               /*
+                * Armv8 ARM (ARM DDI 0487F.c), chapter "D10.2.1 Address packet"
+                * defines the data virtual address payload format, the top byte
+                * (bits [63:56]) is assigned as top-byte tag; so we only can
+                * retrieve address value from bits [55:0].
+                *
+                * According to Documentation/arm64/memory.rst, if detects the
+                * specific pattern in bits [55:52] of payload which falls in
+                * the kernel space, should fixup the top byte and this allows
+                * perf tool to parse DSO symbol for data address correctly.
+                *
+                * For this reason, if detects the bits [55:52] is 0xf, will
+                * fill 0xff into the top byte.
+                */
+               val = SPE_ADDR_PKT_ADDR_GET_BYTE_6(payload);
+               if ((val & 0xf0ULL) == 0xf0ULL)
                        payload |= 0xffULL << SPE_ADDR_PKT_ADDR_BYTE7_SHIFT;
 
        /* Data access physical address */