https://bugs.winehq.org/show_bug.cgi?id=46132
--- Comment #3 from Anastasius Focht focht@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/60792ad349f3c6dc5735aafefe5dc9121c7...
--- 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: *