zephyr/soc
Daniel Leung debb9f6352 xtensa: dc233c: force invalidating TLBs during page table swap
QEMU MMU tracing showed that there might be something wrong with
its Xtensa MMU implementation, which result in access violation
when running samples/userspace/hello_world_user.

Here is the MMU trace from QEMU from failed runs:

  get_pte: autorefill(00109020): PTE va = 20000424, pa = 0010c424
  get_physical_addr_mmu: autorefill(00109020): 00109000 -> 00109006
  xtensa_cpu_tlb_fill(00109020, 1, 0) -> 00109020, ret = 0
  xtensa_cpu_tlb_fill(00109028, 1, 0) -> 00109028, ret = 0
  xtensa_cpu_tlb_fill(00109014, 0, 2) -> 00103050, ret = 26

The place where it fails is during reading from 0x109014.
From the trace above, the auto-refill maps 0x109000 correctly
with ring 0 and RW access with WB cache (which should be correct
the first time under kernel mode). The page 0x109000 is the libc
partition which needs to be accessible from user thread.
However, when accessing that page, the returned physical address
became 0x103050 (and resulting in load/store access violation).
We always identity map memory pages so it should never return
a different physical address.

After forcing TLB invalidation during page table swaps, the MMU
trace is:

  get_pte: autorefill(00109020): PTE va = 20000424, pa = 0010c424
  get_physical_addr_mmu: autorefill(00109020): 00109000 -> 00109006
  xtensa_cpu_tlb_fill(00109020, 1, 0) -> 00109020, ret = 0
  get_pte: autorefill(00109028): PTE va = 21000424, pa = 0010e424
  get_physical_addr_mmu: autorefill(00109028): 00109000 -> 00109022
  xtensa_cpu_tlb_fill(00109028, 1, 0) -> 00109028, ret = 0
  get_pte: autorefill(00109014): PTE va = 21000424, pa = 0010e424
  get_physical_addr_mmu: autorefill(00109014): 00109000 -> 00109022
  xtensa_cpu_tlb_fill(00109014, 0, 2) -> 00109014, ret = 0
  xtensa_cpu_tlb_fill(00109020, 0, 0) -> 00109020, ret = 0

Here, when the same page is accessed, it got the correct PTE
entry, which is ring 2 with RW access mode (but no cache).
Actually accessing the variable via virtual address returns
the correct physical address: 0x109014.

So workaround that by forcing TLB invalidation during page swap.

Fixes #66029

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2023-12-27 15:59:05 +00:00
..
arc arch: introduce DSP_SHARING and CPU_HAS_DSP configs 2023-11-27 09:05:54 +00:00
arm soc: arm: nxp: add MK22F12 definition 2023-12-23 10:00:36 +00:00
arm64 drivers: pinctrl: Add R-Car Gen4 support 2023-11-25 08:50:47 -05:00
mips cmake: mips: update mips SoC to use SOC_LINKER_SCRIPT variable 2023-11-03 11:01:23 +01:00
nios2 cmake: cleanup and simplify the standard include logic in Zephyr 2023-11-06 18:57:30 -05:00
posix soc: posix: fix kconfig description 2023-12-18 10:11:18 +01:00
riscv drivers: usb: usb_dc_it82xx2: optimize the basic/extend endpoints control 2023-12-20 11:15:38 +01:00
sparc cmake: sparc: update sparc SoC to use SOC_LINKER_SCRIPT variable 2023-11-03 11:01:23 +01:00
x86 cmake: x86: update x86 SoC to use SOC_LINKER_SCRIPT variable 2023-11-03 11:01:23 +01:00
xtensa xtensa: dc233c: force invalidating TLBs during page table swap 2023-12-27 15:59:05 +00:00
CMakeLists.txt cmake: enable -Wshadow partially for in-tree code 2023-08-22 11:39:58 +02:00
Kconfig nrf5x_bsim: Add helper kconfig symbols for simulated nrf5340 2023-09-20 08:56:49 +02:00