mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-04 20:19:47 +08:00
RISC-V: KVM: Fix pte settings within kvm_riscv_gstage_ioremap()
Currently, kvm_riscv_gstage_ioremap() is used to map IMSIC gpa to the
spa of IMSIC guest interrupt file.
The PAGE_KERNEL_IO property includes global setting whereas it does not
include user mode settings, so when accessing the IMSIC address in the
virtual machine, a guest page fault will occur, this is not expected.
According to the RISC-V Privileged Architecture Spec, for G-stage address
translation, all memory accesses are considered to be user-level accesses
as though executed in U-mode.
Fixes: 659ad6d82c
("RISC-V: KVM: Use PAGE_KERNEL_IO in kvm_riscv_gstage_ioremap()")
Signed-off-by: Fangyu Yu <fangyu.yu@linux.alibaba.com>
Reviewed-by: Radim Krčmář <rkrcmar@ventanamicro.com>
Reviewed-by: Nutty Liu <nutty.liu@hotmail.com>
Link: https://lore.kernel.org/r/20250807070729.89701-1-fangyu.yu@linux.alibaba.com
Signed-off-by: Anup Patel <anup@brainfault.org>
This commit is contained in:
parent
1b237f190e
commit
9bca8be646
@ -39,6 +39,7 @@ int kvm_riscv_mmu_ioremap(struct kvm *kvm, gpa_t gpa, phys_addr_t hpa,
|
|||||||
unsigned long size, bool writable, bool in_atomic)
|
unsigned long size, bool writable, bool in_atomic)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
pgprot_t prot;
|
||||||
unsigned long pfn;
|
unsigned long pfn;
|
||||||
phys_addr_t addr, end;
|
phys_addr_t addr, end;
|
||||||
struct kvm_mmu_memory_cache pcache = {
|
struct kvm_mmu_memory_cache pcache = {
|
||||||
@ -55,10 +56,12 @@ int kvm_riscv_mmu_ioremap(struct kvm *kvm, gpa_t gpa, phys_addr_t hpa,
|
|||||||
|
|
||||||
end = (gpa + size + PAGE_SIZE - 1) & PAGE_MASK;
|
end = (gpa + size + PAGE_SIZE - 1) & PAGE_MASK;
|
||||||
pfn = __phys_to_pfn(hpa);
|
pfn = __phys_to_pfn(hpa);
|
||||||
|
prot = pgprot_noncached(PAGE_WRITE);
|
||||||
|
|
||||||
for (addr = gpa; addr < end; addr += PAGE_SIZE) {
|
for (addr = gpa; addr < end; addr += PAGE_SIZE) {
|
||||||
map.addr = addr;
|
map.addr = addr;
|
||||||
map.pte = pfn_pte(pfn, PAGE_KERNEL_IO);
|
map.pte = pfn_pte(pfn, prot);
|
||||||
|
map.pte = pte_mkdirty(map.pte);
|
||||||
map.level = 0;
|
map.level = 0;
|
||||||
|
|
||||||
if (!writable)
|
if (!writable)
|
||||||
|
Loading…
Reference in New Issue
Block a user