diff options
| -rw-r--r-- | arch/riscv/include/asm/kvm_gstage.h | 4 | ||||
| -rw-r--r-- | arch/riscv/kvm/gstage.c | 14 |
2 files changed, 18 insertions, 0 deletions
diff --git a/arch/riscv/include/asm/kvm_gstage.h b/arch/riscv/include/asm/kvm_gstage.h index f820c6783e16..21e2019df0cf 100644 --- a/arch/riscv/include/asm/kvm_gstage.h +++ b/arch/riscv/include/asm/kvm_gstage.h @@ -54,6 +54,10 @@ int kvm_riscv_gstage_set_pte(struct kvm_gstage *gstage, struct kvm_mmu_memory_cache *pcache, const struct kvm_gstage_mapping *map); +bool kvm_riscv_gstage_try_update_pte(struct kvm_gstage *gstage, u32 level, + gpa_t addr, pte_t *ptep, + pte_t old_pte, pte_t new_pte); + int kvm_riscv_gstage_map_page(struct kvm_gstage *gstage, struct kvm_mmu_memory_cache *pcache, gpa_t gpa, phys_addr_t hpa, unsigned long page_size, diff --git a/arch/riscv/kvm/gstage.c b/arch/riscv/kvm/gstage.c index d4ce5e76989c..d878100aeb35 100644 --- a/arch/riscv/kvm/gstage.c +++ b/arch/riscv/kvm/gstage.c @@ -123,6 +123,20 @@ static void gstage_tlb_flush(struct kvm_gstage *gstage, u32 level, gpa_t addr) gstage->vmid); } +bool kvm_riscv_gstage_try_update_pte(struct kvm_gstage *gstage, u32 level, + gpa_t addr, pte_t *ptep, + pte_t old_pte, pte_t new_pte) +{ + if (cmpxchg(&ptep->pte, pte_val(old_pte), pte_val(new_pte)) != + pte_val(old_pte)) + return false; + + if (pte_val(old_pte) != pte_val(new_pte)) + gstage_tlb_flush(gstage, level, addr); + + return true; +} + int kvm_riscv_gstage_set_pte(struct kvm_gstage *gstage, struct kvm_mmu_memory_cache *pcache, const struct kvm_gstage_mapping *map) |
