Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] The `-EEXIST` fallback logic incorrectly maps the base 0th page of a Transparent Huge Page (THP) instead of the actual faulting 4K page, causing the guest to infinitely page fault on the same instruction.
--
--- Patch [1]: [PATCH] KVM: riscv: Avoid overwriting existing G-stage tables with huge leaves ---
commit b862a43d3100b276d3d9db5fb9e061641914af1a
Author: Jinyu Tang <[email protected]>
KVM: riscv: Avoid overwriting existing G-stage tables with huge leaves
This patch adds a check in kvm_riscv_gstage_set_pte() to prevent replacing
an existing lower-level page table with a huge leaf mapping. If this conflict
occurs, it returns -EEXIST and falls back to installing a 4K mapping for the
faulting GPA instead.
> diff --git a/arch/riscv/kvm/gstage.c b/arch/riscv/kvm/gstage.c
> index b0474fcf065aa..af6b469718eb6 100644
> --- a/arch/riscv/kvm/gstage.c
> +++ b/arch/riscv/kvm/gstage.c
[ ... ]
> @@ -287,7 +294,18 @@ int kvm_riscv_gstage_map_page(struct kvm_gstage *gstage,
> out_map->pte = pfn_pte(PFN_DOWN(hpa), prot);
> out_map->pte = pte_mkdirty(out_map->pte);
>
> - return kvm_riscv_gstage_set_pte(gstage, pcache, out_map);
> + ret = kvm_riscv_gstage_set_pte(gstage, pcache, out_map);
> + if (ret == -EEXIST) {
> + huge_page_offset = out_map->addr & (page_size - 1);
> + hpa += huge_page_offset;
[Severity: High]
Does this calculation result in an offset of 0 when handling Transparent
Huge Pages (THPs)?
When a guest faults on a GPA backed by a THP, kvm_riscv_mmu_map() calls
transparent_hugepage_adjust(), which aligns the gpa down to the PMD boundary:
arch/riscv/kvm/mmu.c:transparent_hugepage_adjust() {
...
*gpa &= PMD_MASK;
...
}
Because out_map->addr is derived from this heavily-aligned gpa,
out_map->addr & (page_size - 1) will always evaluate to 0.
If the fallback mistakenly installs a 4K mapping at the base physical
address (hpa += 0) instead of the actual faulting offset within the huge
page, will the guest continuously fault on the same instruction when
attempting to access a non-zero offset, causing an infinite page fault
loop?
> + out_map->level = 0;
> + out_map->pte = pfn_pte(PFN_DOWN(hpa), prot);
> + out_map->pte = pte_mkdirty(out_map->pte);
> +
> + ret = kvm_riscv_gstage_set_pte(gstage, pcache, out_map);
> + }
> +
> + return ret;
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=1
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.