[Bug 46132] Multiple Windows 10 ARM64 apps crash with illegal instruction fault due to access of ARMv8 PMU cycle counter via 'PMCCNTR_EL0' register in EL0 (Linux kernel disallows access by default)

wine-bugs at winehq.org wine-bugs at winehq.org
Tue Apr 30 16:53:37 CDT 2019


https://bugs.winehq.org/show_bug.cgi?id=46132

--- Comment #3 from Anastasius Focht <focht at gmx.net> ---
Hello André,

I didn't check what happens if you are totally off with the increment when
using emulation approach. There might be cases where the app relies on an
accurate cycle counter increment which is hard to approximate with
trap-and-emulate.

Instead I introduced a Linux kernel patch that reverses the default policy. The
patch from my own cross-dev Yocto/Poky-Wine project (sadly didn't find the time
yet to prepare/polish everything for github):

--- snip ---
>From 4299a8ad4013546deca47709a8c23f47f03c7cb0 Mon Sep 17 00:00:00 2001
From: <hidden>
Date: Sat, 1 Dec 2018 01:32:55 +0100
Subject: [PATCH] arm64: kernel: Enable PMU access from EL0.

Needed for Windows 10 ARM64 apps which read the PMU cycle counter from EL0.
See Wine bug #46132 [1] for details.
The kernel default policy of denying EL0 access to PMU was introduced in [2].

[1]: https://bugs.winehq.org/show_bug.cgi?id=46132
[2]:
https://github.com/torvalds/linux/commit/60792ad349f3c6dc5735aafefe5dc9121c79e320

---
 arch/arm64/include/asm/assembler.h | 15 +++++++++++++++
 arch/arm64/mm/proc.S               |  4 ++--
 2 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/assembler.h
b/arch/arm64/include/asm/assembler.h
index 0bcc98dbba56..23f0aba5fc8d 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -438,6 +438,21 @@ USER(\label, ic    ivau, \tmp2)            // invalidate I
line PoU
 9000:
     .endm

+/*
+ * enable_pmuserenr_el0 -  Enable PMU access from EL0 if PMUv3 present
+ */
+    .macro    enable_pmuserenr_el0, tmpreg
+    mrs    \tmpreg, id_aa64dfr0_el1    // Check ID_AA64DFR0_EL1 PMUVer
+    sbfx    \tmpreg, \tmpreg, #8, #4
+    cmp    \tmpreg, #1            // Skip if no PMU present
+    b.lt    9100f
+    mov    \tmpreg, #1 << 0        // EL0 access enable
+    orr    \tmpreg, \tmpreg, #1 << 2    // Cycle counter read enable
+    orr    \tmpreg, \tmpreg, #1 << 3    // Event counter read enable
+    msr    pmuserenr_el0, \tmpreg        // enable PMU access from EL0
+9100:
+    .endm
+
 /*
  * copy_page - copy src to dest using temp registers t1-t8
  */
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 03646e6a2ef4..98a5a1bf3430 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -137,7 +137,7 @@ alternative_endif
      */
     ubfx    x11, x11, #1, #1
     msr    oslar_el1, x11
-    reset_pmuserenr_el0 x0            // Disable PMU access from EL0
+    enable_pmuserenr_el0 x0            // Enable PMU access from EL0

 alternative_if ARM64_HAS_RAS_EXTN
     msr_s    SYS_DISR_EL1, xzr
@@ -410,7 +410,7 @@ ENTRY(__cpu_setup)
     msr    mdscr_el1, x0            // access to the DCC from EL0
     isb                    // Unmask debug exceptions now,
     enable_dbg                // since this is per-cpu
-    reset_pmuserenr_el0 x0            // Disable PMU access from EL0
+    enable_pmuserenr_el0 x0            // Enable PMU access from EL0
     /*
      * Memory region attributes for LPAE:
      *
-- 
2.17.2

--- snip ---

Regards

-- 
Do not reply to this email, post in Bugzilla using the
above URL to reply.
You are receiving this mail because:
You are watching all bug changes.


More information about the wine-bugs mailing list