The kvm_riscv_mmu_update_hgatp() will be also used for when switching
between guest HS-mode and guest VS/VU-mode so extend it accordingly.

Signed-off-by: Anup Patel <[email protected]>
---
 arch/riscv/include/asm/kvm_gstage.h |  2 ++
 arch/riscv/include/asm/kvm_mmu.h    |  2 +-
 arch/riscv/kvm/gstage.c             | 14 ++++++++++++++
 arch/riscv/kvm/mmu.c                | 18 ++++++++----------
 arch/riscv/kvm/vcpu.c               |  4 ++--
 5 files changed, 27 insertions(+), 13 deletions(-)

diff --git a/arch/riscv/include/asm/kvm_gstage.h 
b/arch/riscv/include/asm/kvm_gstage.h
index 595e2183173e..007a5fd7a526 100644
--- a/arch/riscv/include/asm/kvm_gstage.h
+++ b/arch/riscv/include/asm/kvm_gstage.h
@@ -67,6 +67,8 @@ void kvm_riscv_gstage_unmap_range(struct kvm_gstage *gstage,
 
 void kvm_riscv_gstage_wp_range(struct kvm_gstage *gstage, gpa_t start, gpa_t 
end);
 
+void kvm_riscv_gstage_update_hgatp(phys_addr_t pgd_phys, unsigned long vmid);
+
 void kvm_riscv_gstage_mode_detect(void);
 
 #endif
diff --git a/arch/riscv/include/asm/kvm_mmu.h b/arch/riscv/include/asm/kvm_mmu.h
index 5439e76f0a96..cc5994ec2805 100644
--- a/arch/riscv/include/asm/kvm_mmu.h
+++ b/arch/riscv/include/asm/kvm_mmu.h
@@ -16,6 +16,6 @@ int kvm_riscv_mmu_map(struct kvm_vcpu *vcpu, struct 
kvm_memory_slot *memslot,
                      struct kvm_gstage_mapping *out_map);
 int kvm_riscv_mmu_alloc_pgd(struct kvm *kvm);
 void kvm_riscv_mmu_free_pgd(struct kvm *kvm);
-void kvm_riscv_mmu_update_hgatp(struct kvm_vcpu *vcpu);
+void kvm_riscv_mmu_update_hgatp(struct kvm_vcpu *vcpu, bool nested_virt);
 
 #endif
diff --git a/arch/riscv/kvm/gstage.c b/arch/riscv/kvm/gstage.c
index b67d60d722c2..7834e1178b68 100644
--- a/arch/riscv/kvm/gstage.c
+++ b/arch/riscv/kvm/gstage.c
@@ -10,6 +10,7 @@
 #include <linux/module.h>
 #include <linux/pgtable.h>
 #include <asm/kvm_gstage.h>
+#include <asm/kvm_nacl.h>
 
 #ifdef CONFIG_64BIT
 unsigned long kvm_riscv_gstage_mode __ro_after_init = HGATP_MODE_SV39X4;
@@ -313,6 +314,19 @@ void kvm_riscv_gstage_wp_range(struct kvm_gstage *gstage, 
gpa_t start, gpa_t end
        }
 }
 
+void kvm_riscv_gstage_update_hgatp(phys_addr_t pgd_phys, unsigned long vmid)
+{
+       unsigned long hgatp = kvm_riscv_gstage_mode << HGATP_MODE_SHIFT;
+
+       hgatp |= (vmid << HGATP_VMID_SHIFT) & HGATP_VMID;
+       hgatp |= (pgd_phys >> PAGE_SHIFT) & HGATP_PPN;
+
+       ncsr_write(CSR_HGATP, hgatp);
+
+       if (!kvm_riscv_gstage_vmid_bits())
+               kvm_riscv_local_hfence_gvma_all();
+}
+
 void __init kvm_riscv_gstage_mode_detect(void)
 {
 #ifdef CONFIG_64BIT
diff --git a/arch/riscv/kvm/mmu.c b/arch/riscv/kvm/mmu.c
index 0b75eb2a1820..250606f5aa41 100644
--- a/arch/riscv/kvm/mmu.c
+++ b/arch/riscv/kvm/mmu.c
@@ -14,7 +14,6 @@
 #include <linux/kvm_host.h>
 #include <linux/sched/signal.h>
 #include <asm/kvm_mmu.h>
-#include <asm/kvm_nacl.h>
 
 static void mmu_wp_memory_region(struct kvm *kvm, int slot)
 {
@@ -597,16 +596,15 @@ void kvm_riscv_mmu_free_pgd(struct kvm *kvm)
                free_pages((unsigned long)pgd, 
get_order(kvm_riscv_gstage_pgd_size));
 }
 
-void kvm_riscv_mmu_update_hgatp(struct kvm_vcpu *vcpu)
+void kvm_riscv_mmu_update_hgatp(struct kvm_vcpu *vcpu, bool nested_virt)
 {
-       unsigned long hgatp = kvm_riscv_gstage_mode << HGATP_MODE_SHIFT;
+       struct kvm_vcpu_nested_swtlb *nst = &vcpu->arch.nested.swtlb;
        struct kvm_arch *k = &vcpu->kvm->arch;
+       unsigned long vmid = READ_ONCE(k->vmid.vmid);
 
-       hgatp |= (READ_ONCE(k->vmid.vmid) << HGATP_VMID_SHIFT) & HGATP_VMID;
-       hgatp |= (k->pgd_phys >> PAGE_SHIFT) & HGATP_PPN;
-
-       ncsr_write(CSR_HGATP, hgatp);
-
-       if (!kvm_riscv_gstage_vmid_bits())
-               kvm_riscv_local_hfence_gvma_all();
+       if (nested_virt)
+               kvm_riscv_gstage_update_hgatp(nst->shadow_pgd_phys,
+                                             
kvm_riscv_gstage_nested_vmid(vmid));
+       else
+               kvm_riscv_gstage_update_hgatp(k->pgd_phys, vmid);
 }
diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c
index 859c8e71df65..178a4409d4e9 100644
--- a/arch/riscv/kvm/vcpu.c
+++ b/arch/riscv/kvm/vcpu.c
@@ -585,7 +585,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
                csr_write(CSR_VSATP, csr->vsatp);
        }
 
-       kvm_riscv_mmu_update_hgatp(vcpu);
+       kvm_riscv_mmu_update_hgatp(vcpu, kvm_riscv_vcpu_nested_virt(vcpu));
 
        kvm_riscv_vcpu_timer_restore(vcpu);
 
@@ -677,7 +677,7 @@ static int kvm_riscv_check_vcpu_requests(struct kvm_vcpu 
*vcpu)
                        kvm_riscv_reset_vcpu(vcpu, true);
 
                if (kvm_check_request(KVM_REQ_UPDATE_HGATP, vcpu))
-                       kvm_riscv_mmu_update_hgatp(vcpu);
+                       kvm_riscv_mmu_update_hgatp(vcpu, 
kvm_riscv_vcpu_nested_virt(vcpu));
 
                if (kvm_check_request(KVM_REQ_FENCE_I, vcpu))
                        kvm_riscv_fence_i_process(vcpu);
-- 
2.43.0


Reply via email to