Commit Graph
9 Commits
Author SHA1 Message Date
Baptiste Le Duc 8e34f567ef xen/riscv: fix A/D bits in Xen's page-table mappings
Xen does not handle page faults caused by clear A/D bits, so it presets
them when creating PTEs. pt_update_entry() does so, but three places build
leaf PTEs directly without going through it: setup_initial_mapping() (the
boot page tables), check_pgtbl_mode_support() (the temporary root entry
used to probe SATP mode support) and arch_pmap_map() (the fixmap).

On implementations that fault on clear A/D bits (Svade), all three fault
on first access. For check_pgtbl_mode_support(), the fault is raised by the
instruction fetch right after the SATP write, before any trap handler is
set.

Add PTE_ACCESSED and PTE_DIRTY to PAGE_HYPERVISOR_RO, and build
PAGE_HYPERVISOR_RW and PAGE_HYPERVISOR_RX on top of it. PTE_DIRTY is set in
all cases for consistency with pt_update_entry() which sets it at runtime.

This fixes arch_pmap_map() for free, since it already builds its PTE from
PAGE_HYPERVISOR_RW. Switch setup_initial_mapping() to use these macros for
its default, text and rodata permissions, and check_pgtbl_mode_support() to
use PAGE_HYPERVISOR_RX for its temporary root entry. The latter drops
PTE_WRITABLE, going from RWX to RX, but this is harmless, as that entry
only has to make the current instruction stream fetchable between the two
CSR_SATP writes, and nothing writes through it.

Drop the now-redundant PTE_LEAF_DEFAULT, since converting the last
open-coded site above leaves it with no user outside page.h itself.

pte_is_table() and pte_is_mapping() both assert that a PTE doesn't use one
of the two reserved encodings, (V=1, W=1, R=0) and (V=1, X=1, W=1, R=0), by
masking it with PAGE_HYPERVISOR_RW. Now that PAGE_HYPERVISOR_RW also
carries A and D, a reserved PTE with A or D set would no longer be caught.
Mask with the V, R and W bits explicitly instead, and factor the check out
into pte_has_reserved_rwx().

Fixes: e66003e7be ("xen/riscv: introduce setup_initial_pages")
Fixes: f89e1a1702 ("xen/riscv: introduce asm/pmap.h header")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Baptiste Le Duc <baptiste.le-duc@vates.tech>
Reviewed-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Tested-by: Zhang Zheng <zhangzheng@iscas.ac.cn>
Acked-by: Jan Beulich <jbeulich@suse.com>
2026-10-27 08:59:18 +01:00
Baptiste Le Duc 999c2ca1ab xen/riscv: use pte_is_valid() in pte_is_mapping()
Use pte_is_valid() instead of open-coding the PTE_VALID check.

No functional change.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Baptiste Le Duc <baptiste.le-duc@vates.tech>
Reviewed-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
2026-10-27 08:58:06 +01:00
Baptiste Le Duc 712a0c0ad4 MAINTAINERS: Add myself as RISC-V reviewer
Signed-off-by: Baptiste Le Duc <baptiste.le-duc@vates.tech>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
2026-10-26 09:01:40 +01:00
Baptiste Le Duc ccf9d78c82 xen/riscv: rename PTE "permissions" to "pte_flags"
paddr_to_pte()'s "permissions" parameter, the matching local in
setup_initial_mapping() and p2m_set_permission() don't only deal with
permission bits: they also handle PTE_VALID, PTE_USER, PTE_ACCESSED and
PTE_DIRTY.

Rename them to "pte_flags" and p2m_set_pte_flags() respectively.

No functional change.

Requested-by: Jan Beulich <jbeulich@suse.com>
Assisted-by: Claude:claude-opus-5
Signed-off-by: Baptiste Le Duc <baptiste.le-duc@vates.tech>
Acked-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
2026-10-01 09:59:06 +02:00
Baptiste Le Duc 861e44a3ba xen/riscv: make Zihintpause no longer a required extension
Zihintpause is in required_extensions[] so Xen panics when it is missing,
while it does not strictly require hardware support for it.

The PAUSE hint (Zihintpause extension) is encoded as FENCE W, 0
(0x0100000F). In accordance with the RISC-V Unprivileged ISA, HINTs are
encoded in the space of valid standard instructions. On platforms without
Zihintpause support, executing 0x0100000F is treated as a standard FENCE
with an empty successor set, which acts as a NOP and never generates an
illegal instruction trap.

Zihintpause is therefore purely an optimization hint. Drop it from
required_extensions[] so Xen can still boot on systems that don't advertise
it, and print a warning in that case.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Baptiste Le Duc <baptiste.le-duc@vates.tech>
Reviewed-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
2026-09-30 15:00:48 +02:00
Baptiste Le Duc 08a898b93d xen/riscv: fix level_map_mask truncation on load_start
check_pgtbl_mode_support() declares level_map_mask as bare `unsigned`, i.e.
a 32-bit type while it derives from a paddr_t which is in both RV32/RV64 a
64-bit type. Storing that value into a 32-bit local silently drops any set
bits above bit 31.

The mask is then used as:

    aligned_load_start = load_start & level_map_mask;

load_start is `unsigned long` (64-bit on riscv64) and if it requires more
than 32 bits to represent, because load_start zero-extend to 64 bits, we
would drop some load_start's bits during the AND.

Widen level_map_mask to `unsigned long`, matching the width of the physical
address.

Fixes: e66003e7be ("xen/riscv: introduce setup_initial_pages")
Reported-by: Zheng Zhang <zhangzheng@iscas.ac.cn>
Signed-off-by: Baptiste Le Duc <baptiste.le-duc@vates.tech>
Tested-by: Zheng Zhang <zhangzheng@iscas.ac.cn>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
2026-09-23 10:01:38 +02:00
Baptiste Le Duc d8ca89f26c xen/riscv: flush speculatively cached Bare-mode TLB entries in turn_on_mmu()
The existing SFENCE.VMA before the satp write only orders the page table
stores from setup_initial_pagetables() against subsequent implicit reads.
It does not prevent the CPU from speculatively caching translations after
the fence retires.

According to the RISC-V Privileged specification, implementations are
permitted to speculatively cache Bare-mode identity mappings. Furthermore,
selecting MODE=Bare (which happens during check_pgtbl_mode_support())
requires zeroing the remaining fields of satp, causing ASID=0 to be
actively used in Bare mode. Consequently, the TLB can be polluted with Bare
identity mappings tagged with ASID=0.

Once satp is written to enable Sv39 translation, these cached identity
mappings (tagged with ASID=0) can shadow the true Sv39 translations. This
would lead to translation failures since turn_on_mmu() jumps to a
non-identity-mapped linker address.

Fix this by adding a post-satp-write SFENCE.VMA to invalidate any stale
translations (including Bare-mode identity mappings under ASID=0) before
jumping to the virtual address space.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Baptiste Le Duc <baptiste.le-duc@vates.tech>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
2026-09-23 10:01:38 +02:00
Baptiste Le Duc 4830ddbee3 Add basic b4 config file
b4[1] is a convenient tool for mail-based contribution. A config file[2]
tracked in the tree lets the project ship a few defaults that match the Xen
patch submission rules.

This aims to help new contributors who have never used a mailing list avoid
mistakes when sending their patch series.

The tree has no scripts/checkpatch.pl or equivalent, so there is nothing
for b4 to run per patch. Disable the needs-checking pre-flight check so a
series can be sent without first running b4 prep --check.

[1] https://pypi.org/project/b4/
[2] https://b4.docs.kernel.org/en/latest/config.html

Signed-off-by: Baptiste Le Duc <baptiste.le-duc@vates.tech>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
2026-09-15 11:46:07 +02:00
Baptiste Le Duc a472f640dd xen/riscv: Fix SSTC init to write VSTIMECMP instead of STIMECMP
According to the preceeding comment, CSR_VSTIMECMP should be written rather
than CSR_STIMECMP.

Fixes: 25e0327306 ("xen/riscv: allow Xen to use SSTC while hiding it from guests")
Signed-off-by: Baptiste Le Duc <baptiste.le-duc@vates.tech>
Reviewed-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
2026-05-19 22:29:31 +01:00