Skip to content

Commit dd82e35

Browse files
committed
RISC-V: KVM: Factor-out g-stage page table management
The upcoming nested virtualization can share g-stage page table management with the current host g-stage implementation hence factor-out g-stage page table management as separate sources and also use "kvm_riscv_mmu_" prefix for host g-stage functions. Signed-off-by: Anup Patel <apatel@ventanamicro.com> Tested-by: Atish Patra <atishp@rivosinc.com> Reviewed-by: Nutty Liu <liujingqi@lanxincomputing.com> Link: https://lore.kernel.org/r/20250618113532.471448-12-apatel@ventanamicro.com Signed-off-by: Anup Patel <anup@brainfault.org>
1 parent 4c933f3 commit dd82e35

10 files changed

Lines changed: 530 additions & 432 deletions

File tree

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
/*
3+
* Copyright (C) 2019 Western Digital Corporation or its affiliates.
4+
* Copyright (c) 2025 Ventana Micro Systems Inc.
5+
*/
6+
7+
#ifndef __RISCV_KVM_GSTAGE_H_
8+
#define __RISCV_KVM_GSTAGE_H_
9+
10+
#include <linux/kvm_types.h>
11+
12+
struct kvm_gstage {
13+
struct kvm *kvm;
14+
unsigned long flags;
15+
#define KVM_GSTAGE_FLAGS_LOCAL BIT(0)
16+
unsigned long vmid;
17+
pgd_t *pgd;
18+
};
19+
20+
struct kvm_gstage_mapping {
21+
gpa_t addr;
22+
pte_t pte;
23+
u32 level;
24+
};
25+
26+
#ifdef CONFIG_64BIT
27+
#define kvm_riscv_gstage_index_bits 9
28+
#else
29+
#define kvm_riscv_gstage_index_bits 10
30+
#endif
31+
32+
extern unsigned long kvm_riscv_gstage_mode;
33+
extern unsigned long kvm_riscv_gstage_pgd_levels;
34+
35+
#define kvm_riscv_gstage_pgd_xbits 2
36+
#define kvm_riscv_gstage_pgd_size (1UL << (HGATP_PAGE_SHIFT + kvm_riscv_gstage_pgd_xbits))
37+
#define kvm_riscv_gstage_gpa_bits (HGATP_PAGE_SHIFT + \
38+
(kvm_riscv_gstage_pgd_levels * \
39+
kvm_riscv_gstage_index_bits) + \
40+
kvm_riscv_gstage_pgd_xbits)
41+
#define kvm_riscv_gstage_gpa_size ((gpa_t)(1ULL << kvm_riscv_gstage_gpa_bits))
42+
43+
bool kvm_riscv_gstage_get_leaf(struct kvm_gstage *gstage, gpa_t addr,
44+
pte_t **ptepp, u32 *ptep_level);
45+
46+
int kvm_riscv_gstage_set_pte(struct kvm_gstage *gstage,
47+
struct kvm_mmu_memory_cache *pcache,
48+
const struct kvm_gstage_mapping *map);
49+
50+
int kvm_riscv_gstage_map_page(struct kvm_gstage *gstage,
51+
struct kvm_mmu_memory_cache *pcache,
52+
gpa_t gpa, phys_addr_t hpa, unsigned long page_size,
53+
bool page_rdonly, bool page_exec,
54+
struct kvm_gstage_mapping *out_map);
55+
56+
enum kvm_riscv_gstage_op {
57+
GSTAGE_OP_NOP = 0, /* Nothing */
58+
GSTAGE_OP_CLEAR, /* Clear/Unmap */
59+
GSTAGE_OP_WP, /* Write-protect */
60+
};
61+
62+
void kvm_riscv_gstage_op_pte(struct kvm_gstage *gstage, gpa_t addr,
63+
pte_t *ptep, u32 ptep_level, enum kvm_riscv_gstage_op op);
64+
65+
void kvm_riscv_gstage_unmap_range(struct kvm_gstage *gstage,
66+
gpa_t start, gpa_t size, bool may_block);
67+
68+
void kvm_riscv_gstage_wp_range(struct kvm_gstage *gstage, gpa_t start, gpa_t end);
69+
70+
void kvm_riscv_gstage_mode_detect(void);
71+
72+
#endif

arch/riscv/include/asm/kvm_mmu.h

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,16 @@
66
#ifndef __RISCV_KVM_MMU_H_
77
#define __RISCV_KVM_MMU_H_
88

9-
#include <linux/kvm_types.h>
9+
#include <asm/kvm_gstage.h>
1010

11-
struct kvm_gstage_mapping {
12-
gpa_t addr;
13-
pte_t pte;
14-
u32 level;
15-
};
16-
17-
int kvm_riscv_gstage_ioremap(struct kvm *kvm, gpa_t gpa,
18-
phys_addr_t hpa, unsigned long size,
19-
bool writable, bool in_atomic);
20-
void kvm_riscv_gstage_iounmap(struct kvm *kvm, gpa_t gpa,
21-
unsigned long size);
22-
int kvm_riscv_gstage_map(struct kvm_vcpu *vcpu,
23-
struct kvm_memory_slot *memslot,
24-
gpa_t gpa, unsigned long hva, bool is_write,
25-
struct kvm_gstage_mapping *out_map);
26-
int kvm_riscv_gstage_alloc_pgd(struct kvm *kvm);
27-
void kvm_riscv_gstage_free_pgd(struct kvm *kvm);
28-
void kvm_riscv_gstage_update_hgatp(struct kvm_vcpu *vcpu);
29-
void kvm_riscv_gstage_mode_detect(void);
30-
unsigned long kvm_riscv_gstage_mode(void);
31-
int kvm_riscv_gstage_gpa_bits(void);
11+
int kvm_riscv_mmu_ioremap(struct kvm *kvm, gpa_t gpa, phys_addr_t hpa,
12+
unsigned long size, bool writable, bool in_atomic);
13+
void kvm_riscv_mmu_iounmap(struct kvm *kvm, gpa_t gpa, unsigned long size);
14+
int kvm_riscv_mmu_map(struct kvm_vcpu *vcpu, struct kvm_memory_slot *memslot,
15+
gpa_t gpa, unsigned long hva, bool is_write,
16+
struct kvm_gstage_mapping *out_map);
17+
int kvm_riscv_mmu_alloc_pgd(struct kvm *kvm);
18+
void kvm_riscv_mmu_free_pgd(struct kvm *kvm);
19+
void kvm_riscv_mmu_update_hgatp(struct kvm_vcpu *vcpu);
3220

3321
#endif

arch/riscv/kvm/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ kvm-y += aia.o
1414
kvm-y += aia_aplic.o
1515
kvm-y += aia_device.o
1616
kvm-y += aia_imsic.o
17+
kvm-y += gstage.o
1718
kvm-y += main.o
1819
kvm-y += mmu.o
1920
kvm-y += nacl.o

arch/riscv/kvm/aia_imsic.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -746,9 +746,8 @@ void kvm_riscv_vcpu_aia_imsic_release(struct kvm_vcpu *vcpu)
746746
*/
747747

748748
/* Purge the G-stage mapping */
749-
kvm_riscv_gstage_iounmap(vcpu->kvm,
750-
vcpu->arch.aia_context.imsic_addr,
751-
IMSIC_MMIO_PAGE_SZ);
749+
kvm_riscv_mmu_iounmap(vcpu->kvm, vcpu->arch.aia_context.imsic_addr,
750+
IMSIC_MMIO_PAGE_SZ);
752751

753752
/* TODO: Purge the IOMMU mapping ??? */
754753

@@ -831,9 +830,9 @@ int kvm_riscv_vcpu_aia_imsic_update(struct kvm_vcpu *vcpu)
831830
imsic_vsfile_local_clear(new_vsfile_hgei, imsic->nr_hw_eix);
832831

833832
/* Update G-stage mapping for the new IMSIC VS-file */
834-
ret = kvm_riscv_gstage_ioremap(kvm, vcpu->arch.aia_context.imsic_addr,
835-
new_vsfile_pa, IMSIC_MMIO_PAGE_SZ,
836-
true, true);
833+
ret = kvm_riscv_mmu_ioremap(kvm, vcpu->arch.aia_context.imsic_addr,
834+
new_vsfile_pa, IMSIC_MMIO_PAGE_SZ,
835+
true, true);
837836
if (ret)
838837
goto fail_free_vsfile_hgei;
839838

0 commit comments

Comments
 (0)