ARM: tag bits cleared in FAR_EL1

Bug #1867072 reported by Peter Collingbourne
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
QEMU
Fix Released
Undecided
Richard Henderson

Bug Description

The ARM Architecture Reference Manual provides the following for FAR_EL1:

"For a Data Abort or Watchpoint exception, if address tagging is enabled for the address accessed by the data access that caused the exception, then this field includes the tag."

However, I have found that the tag bits in FAR_EL1 are always clear, even if the tag bits were set in the original access.

I can reproduce the problem on both 4.1.1 and master (6e8a73e911f066527e775e04b98f31ebd19db600).

Revision history for this message
Richard Henderson (rth) wrote :

As it happens, I posted some cleanups for this last week:
https://<email address hidden>/

Some of them have been queued to Peter's target-arm.next branch,
but that hasn't made it to master yet.

Changed in qemu:
status: New → In Progress
assignee: nobody → Richard Henderson (rth)
Revision history for this message
Richard Henderson (rth) wrote :

Actually, I take that back: Peter has merged my TBI patch set,
and is included in 6e8a73e911f066.

Do you have a test case?

Revision history for this message
Richard Henderson (rth) wrote :

Ho hum, I must have been asleep last night.
Peter only merged 7 of 9 patches. The final 2 were re-posted:
https://<email address hidden>/

which includes the critical change that affects FAR_ELx.

Revision history for this message
Peter Collingbourne (pcc-goog) wrote :

With those two patches applied I can no longer reproduce the problem, thanks!

For posterity, this is how I've been reproducing the problem:

1. Build a Linux kernel with this patch applied: https://patchwork.kernel.org/patch/11435077/
2. Run this program under the kernel:

#include <stdint.h>
#include <stdio.h>
#include <signal.h>

void handler(int signo, siginfo_t *siginfo, void *context) {
  uint32_t *begin = (uint32_t *)context;
  uint32_t *end = ((uint32_t *)context) + (sizeof(ucontext_t)/4);
  for (uint32_t *i = begin; i != end; ++i) {
    printf("%08p %08x\n", i, *i);
  }
  _exit(0);
}

int main() {
  struct sigaction sa;
  sa.sa_sigaction = handler;
  sa.sa_flags = SA_SIGINFO;
  sigaction(SIGSEGV, &sa, 0);

  return *(int *)((1ULL << 56) + 0x123456);
}

I would expect this program's output to include something like the following:

0xffffd5869bd0 46415201
0xffffd5869bd4 00000010
0xffffd5869bd8 00123456
0xffffd5869bdc 01000000

But the output that I was seeing with the bad qemu looked like this:

0xffffd5869bd0 46415201
0xffffd5869bd4 00000010
0xffffd5869bd8 00123456
0xffffd5869bdc 00000000

Revision history for this message
Richard Henderson (rth) wrote :

Fix now in master.

Changed in qemu:
status: In Progress → Fix Committed
Revision history for this message
Laurent Vivier (laurent-vivier) wrote :
Changed in qemu:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.