Skip to content

Commit b1c5356

Browse files
sean-jcbonzini
authored andcommitted
KVM: PPC: Convert to the gfn-based MMU notifier callbacks
Move PPC to the gfn-base MMU notifier APIs, and update all 15 bajillion PPC-internal hooks to work with gfns instead of hvas. No meaningful functional change intended, though the exact order of operations is slightly different since the memslot lookups occur before calling into arch code. Signed-off-by: Sean Christopherson <[email protected]> Message-Id: <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent d923ff2 commit b1c5356

File tree

10 files changed

+95
-173
lines changed

10 files changed

+95
-173
lines changed

arch/powerpc/include/asm/kvm_book3s.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -210,12 +210,12 @@ extern void kvmppc_free_pgtable_radix(struct kvm *kvm, pgd_t *pgd,
210210
unsigned int lpid);
211211
extern int kvmppc_radix_init(void);
212212
extern void kvmppc_radix_exit(void);
213-
extern int kvm_unmap_radix(struct kvm *kvm, struct kvm_memory_slot *memslot,
214-
unsigned long gfn);
215-
extern int kvm_age_radix(struct kvm *kvm, struct kvm_memory_slot *memslot,
216-
unsigned long gfn);
217-
extern int kvm_test_age_radix(struct kvm *kvm, struct kvm_memory_slot *memslot,
218-
unsigned long gfn);
213+
extern bool kvm_unmap_radix(struct kvm *kvm, struct kvm_memory_slot *memslot,
214+
unsigned long gfn);
215+
extern bool kvm_age_radix(struct kvm *kvm, struct kvm_memory_slot *memslot,
216+
unsigned long gfn);
217+
extern bool kvm_test_age_radix(struct kvm *kvm, struct kvm_memory_slot *memslot,
218+
unsigned long gfn);
219219
extern long kvmppc_hv_get_dirty_log_radix(struct kvm *kvm,
220220
struct kvm_memory_slot *memslot, unsigned long *map);
221221
extern void kvmppc_radix_flush_memslot(struct kvm *kvm,

arch/powerpc/include/asm/kvm_host.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
#include <linux/mmu_notifier.h>
5656

5757
#define KVM_ARCH_WANT_MMU_NOTIFIER
58+
#define KVM_ARCH_WANT_NEW_MMU_NOTIFIER_APIS
5859

5960
#define HPTEG_CACHE_NUM (1 << 15)
6061
#define HPTEG_HASH_BITS_PTE 13

arch/powerpc/include/asm/kvm_ppc.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -281,11 +281,10 @@ struct kvmppc_ops {
281281
const struct kvm_memory_slot *old,
282282
const struct kvm_memory_slot *new,
283283
enum kvm_mr_change change);
284-
int (*unmap_hva_range)(struct kvm *kvm, unsigned long start,
285-
unsigned long end);
286-
int (*age_hva)(struct kvm *kvm, unsigned long start, unsigned long end);
287-
int (*test_age_hva)(struct kvm *kvm, unsigned long hva);
288-
void (*set_spte_hva)(struct kvm *kvm, unsigned long hva, pte_t pte);
284+
bool (*unmap_gfn_range)(struct kvm *kvm, struct kvm_gfn_range *range);
285+
bool (*age_gfn)(struct kvm *kvm, struct kvm_gfn_range *range);
286+
bool (*test_age_gfn)(struct kvm *kvm, struct kvm_gfn_range *range);
287+
bool (*set_spte_gfn)(struct kvm *kvm, struct kvm_gfn_range *range);
289288
void (*free_memslot)(struct kvm_memory_slot *slot);
290289
int (*init_vm)(struct kvm *kvm);
291290
void (*destroy_vm)(struct kvm *kvm);

arch/powerpc/kvm/book3s.c

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -834,26 +834,24 @@ void kvmppc_core_commit_memory_region(struct kvm *kvm,
834834
kvm->arch.kvm_ops->commit_memory_region(kvm, mem, old, new, change);
835835
}
836836

837-
int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end,
838-
unsigned flags)
837+
bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range)
839838
{
840-
return kvm->arch.kvm_ops->unmap_hva_range(kvm, start, end);
839+
return kvm->arch.kvm_ops->unmap_gfn_range(kvm, range);
841840
}
842841

843-
int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end)
842+
bool kvm_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
844843
{
845-
return kvm->arch.kvm_ops->age_hva(kvm, start, end);
844+
return kvm->arch.kvm_ops->age_gfn(kvm, range);
846845
}
847846

848-
int kvm_test_age_hva(struct kvm *kvm, unsigned long hva)
847+
bool kvm_test_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
849848
{
850-
return kvm->arch.kvm_ops->test_age_hva(kvm, hva);
849+
return kvm->arch.kvm_ops->test_age_gfn(kvm, range);
851850
}
852851

853-
int kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte)
852+
bool kvm_set_spte_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
854853
{
855-
kvm->arch.kvm_ops->set_spte_hva(kvm, hva, pte);
856-
return 0;
854+
return kvm->arch.kvm_ops->set_spte_gfn(kvm, range);
857855
}
858856

859857
int kvmppc_core_init_vm(struct kvm *kvm)

arch/powerpc/kvm/book3s.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,10 @@
99

1010
extern void kvmppc_core_flush_memslot_hv(struct kvm *kvm,
1111
struct kvm_memory_slot *memslot);
12-
extern int kvm_unmap_hva_range_hv(struct kvm *kvm, unsigned long start,
13-
unsigned long end);
14-
extern int kvm_age_hva_hv(struct kvm *kvm, unsigned long start,
15-
unsigned long end);
16-
extern int kvm_test_age_hva_hv(struct kvm *kvm, unsigned long hva);
17-
extern void kvm_set_spte_hva_hv(struct kvm *kvm, unsigned long hva, pte_t pte);
12+
extern bool kvm_unmap_gfn_range_hv(struct kvm *kvm, struct kvm_gfn_range *range);
13+
extern bool kvm_age_gfn_hv(struct kvm *kvm, struct kvm_gfn_range *range);
14+
extern bool kvm_test_age_gfn_hv(struct kvm *kvm, struct kvm_gfn_range *range);
15+
extern bool kvm_set_spte_gfn_hv(struct kvm *kvm, struct kvm_gfn_range *range);
1816

1917
extern int kvmppc_mmu_init_pr(struct kvm_vcpu *vcpu);
2018
extern void kvmppc_mmu_destroy_pr(struct kvm_vcpu *vcpu);

arch/powerpc/kvm/book3s_64_mmu_hv.c

Lines changed: 26 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -752,51 +752,6 @@ void kvmppc_rmap_reset(struct kvm *kvm)
752752
srcu_read_unlock(&kvm->srcu, srcu_idx);
753753
}
754754

755-
typedef int (*hva_handler_fn)(struct kvm *kvm, struct kvm_memory_slot *memslot,
756-
unsigned long gfn);
757-
758-
static int kvm_handle_hva_range(struct kvm *kvm,
759-
unsigned long start,
760-
unsigned long end,
761-
hva_handler_fn handler)
762-
{
763-
int ret;
764-
int retval = 0;
765-
struct kvm_memslots *slots;
766-
struct kvm_memory_slot *memslot;
767-
768-
slots = kvm_memslots(kvm);
769-
kvm_for_each_memslot(memslot, slots) {
770-
unsigned long hva_start, hva_end;
771-
gfn_t gfn, gfn_end;
772-
773-
hva_start = max(start, memslot->userspace_addr);
774-
hva_end = min(end, memslot->userspace_addr +
775-
(memslot->npages << PAGE_SHIFT));
776-
if (hva_start >= hva_end)
777-
continue;
778-
/*
779-
* {gfn(page) | page intersects with [hva_start, hva_end)} =
780-
* {gfn, gfn+1, ..., gfn_end-1}.
781-
*/
782-
gfn = hva_to_gfn_memslot(hva_start, memslot);
783-
gfn_end = hva_to_gfn_memslot(hva_end + PAGE_SIZE - 1, memslot);
784-
785-
for (; gfn < gfn_end; ++gfn) {
786-
ret = handler(kvm, memslot, gfn);
787-
retval |= ret;
788-
}
789-
}
790-
791-
return retval;
792-
}
793-
794-
static int kvm_handle_hva(struct kvm *kvm, unsigned long hva,
795-
hva_handler_fn handler)
796-
{
797-
return kvm_handle_hva_range(kvm, hva, hva + 1, handler);
798-
}
799-
800755
/* Must be called with both HPTE and rmap locked */
801756
static void kvmppc_unmap_hpte(struct kvm *kvm, unsigned long i,
802757
struct kvm_memory_slot *memslot,
@@ -840,8 +795,8 @@ static void kvmppc_unmap_hpte(struct kvm *kvm, unsigned long i,
840795
}
841796
}
842797

843-
static int kvm_unmap_rmapp(struct kvm *kvm, struct kvm_memory_slot *memslot,
844-
unsigned long gfn)
798+
static bool kvm_unmap_rmapp(struct kvm *kvm, struct kvm_memory_slot *memslot,
799+
unsigned long gfn)
845800
{
846801
unsigned long i;
847802
__be64 *hptep;
@@ -874,16 +829,15 @@ static int kvm_unmap_rmapp(struct kvm *kvm, struct kvm_memory_slot *memslot,
874829
unlock_rmap(rmapp);
875830
__unlock_hpte(hptep, be64_to_cpu(hptep[0]));
876831
}
877-
return 0;
832+
return false;
878833
}
879834

880-
int kvm_unmap_hva_range_hv(struct kvm *kvm, unsigned long start, unsigned long end)
835+
bool kvm_unmap_gfn_range_hv(struct kvm *kvm, struct kvm_gfn_range *range)
881836
{
882-
hva_handler_fn handler;
837+
if (kvm_is_radix(kvm))
838+
return kvm_unmap_radix(kvm, range->slot, range->start);
883839

884-
handler = kvm_is_radix(kvm) ? kvm_unmap_radix : kvm_unmap_rmapp;
885-
kvm_handle_hva_range(kvm, start, end, handler);
886-
return 0;
840+
return kvm_unmap_rmapp(kvm, range->slot, range->start);
887841
}
888842

889843
void kvmppc_core_flush_memslot_hv(struct kvm *kvm,
@@ -913,8 +867,8 @@ void kvmppc_core_flush_memslot_hv(struct kvm *kvm,
913867
}
914868
}
915869

916-
static int kvm_age_rmapp(struct kvm *kvm, struct kvm_memory_slot *memslot,
917-
unsigned long gfn)
870+
static bool kvm_age_rmapp(struct kvm *kvm, struct kvm_memory_slot *memslot,
871+
unsigned long gfn)
918872
{
919873
struct revmap_entry *rev = kvm->arch.hpt.rev;
920874
unsigned long head, i, j;
@@ -968,26 +922,26 @@ static int kvm_age_rmapp(struct kvm *kvm, struct kvm_memory_slot *memslot,
968922
return ret;
969923
}
970924

971-
int kvm_age_hva_hv(struct kvm *kvm, unsigned long start, unsigned long end)
925+
bool kvm_age_gfn_hv(struct kvm *kvm, struct kvm_gfn_range *range)
972926
{
973-
hva_handler_fn handler;
927+
if (kvm_is_radix(kvm))
928+
kvm_age_radix(kvm, range->slot, range->start);
974929

975-
handler = kvm_is_radix(kvm) ? kvm_age_radix : kvm_age_rmapp;
976-
return kvm_handle_hva_range(kvm, start, end, handler);
930+
return kvm_age_rmapp(kvm, range->slot, range->start);
977931
}
978932

979-
static int kvm_test_age_rmapp(struct kvm *kvm, struct kvm_memory_slot *memslot,
980-
unsigned long gfn)
933+
static bool kvm_test_age_rmapp(struct kvm *kvm, struct kvm_memory_slot *memslot,
934+
unsigned long gfn)
981935
{
982936
struct revmap_entry *rev = kvm->arch.hpt.rev;
983937
unsigned long head, i, j;
984938
unsigned long *hp;
985-
int ret = 1;
939+
bool ret = true;
986940
unsigned long *rmapp;
987941

988942
rmapp = &memslot->arch.rmap[gfn - memslot->base_gfn];
989943
if (*rmapp & KVMPPC_RMAP_REFERENCED)
990-
return 1;
944+
return true;
991945

992946
lock_rmap(rmapp);
993947
if (*rmapp & KVMPPC_RMAP_REFERENCED)
@@ -1002,27 +956,27 @@ static int kvm_test_age_rmapp(struct kvm *kvm, struct kvm_memory_slot *memslot,
1002956
goto out;
1003957
} while ((i = j) != head);
1004958
}
1005-
ret = 0;
959+
ret = false;
1006960

1007961
out:
1008962
unlock_rmap(rmapp);
1009963
return ret;
1010964
}
1011965

1012-
int kvm_test_age_hva_hv(struct kvm *kvm, unsigned long hva)
966+
bool kvm_test_age_gfn_hv(struct kvm *kvm, struct kvm_gfn_range *range)
1013967
{
1014-
hva_handler_fn handler;
968+
if (kvm_is_radix(kvm))
969+
kvm_test_age_radix(kvm, range->slot, range->start);
1015970

1016-
handler = kvm_is_radix(kvm) ? kvm_test_age_radix : kvm_test_age_rmapp;
1017-
return kvm_handle_hva(kvm, hva, handler);
971+
return kvm_test_age_rmapp(kvm, range->slot, range->start);
1018972
}
1019973

1020-
void kvm_set_spte_hva_hv(struct kvm *kvm, unsigned long hva, pte_t pte)
974+
bool kvm_set_spte_gfn_hv(struct kvm *kvm, struct kvm_gfn_range *range)
1021975
{
1022-
hva_handler_fn handler;
976+
if (kvm_is_radix(kvm))
977+
return kvm_unmap_radix(kvm, range->slot, range->start);
1023978

1024-
handler = kvm_is_radix(kvm) ? kvm_unmap_radix : kvm_unmap_rmapp;
1025-
kvm_handle_hva(kvm, hva, handler);
979+
return kvm_unmap_rmapp(kvm, range->slot, range->start);
1026980
}
1027981

1028982
static int vcpus_running(struct kvm *kvm)

arch/powerpc/kvm/book3s_64_mmu_radix.c

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -993,33 +993,33 @@ int kvmppc_book3s_radix_page_fault(struct kvm_vcpu *vcpu,
993993
}
994994

995995
/* Called with kvm->mmu_lock held */
996-
int kvm_unmap_radix(struct kvm *kvm, struct kvm_memory_slot *memslot,
997-
unsigned long gfn)
996+
bool kvm_unmap_radix(struct kvm *kvm, struct kvm_memory_slot *memslot,
997+
unsigned long gfn)
998998
{
999999
pte_t *ptep;
10001000
unsigned long gpa = gfn << PAGE_SHIFT;
10011001
unsigned int shift;
10021002

10031003
if (kvm->arch.secure_guest & KVMPPC_SECURE_INIT_DONE) {
10041004
uv_page_inval(kvm->arch.lpid, gpa, PAGE_SHIFT);
1005-
return 0;
1005+
return false;
10061006
}
10071007

10081008
ptep = find_kvm_secondary_pte(kvm, gpa, &shift);
10091009
if (ptep && pte_present(*ptep))
10101010
kvmppc_unmap_pte(kvm, ptep, gpa, shift, memslot,
10111011
kvm->arch.lpid);
1012-
return 0;
1012+
return false;
10131013
}
10141014

10151015
/* Called with kvm->mmu_lock held */
1016-
int kvm_age_radix(struct kvm *kvm, struct kvm_memory_slot *memslot,
1017-
unsigned long gfn)
1016+
bool kvm_age_radix(struct kvm *kvm, struct kvm_memory_slot *memslot,
1017+
unsigned long gfn)
10181018
{
10191019
pte_t *ptep;
10201020
unsigned long gpa = gfn << PAGE_SHIFT;
10211021
unsigned int shift;
1022-
int ref = 0;
1022+
bool ref = false;
10231023
unsigned long old, *rmapp;
10241024

10251025
if (kvm->arch.secure_guest & KVMPPC_SECURE_INIT_DONE)
@@ -1035,26 +1035,27 @@ int kvm_age_radix(struct kvm *kvm, struct kvm_memory_slot *memslot,
10351035
kvmhv_update_nest_rmap_rc_list(kvm, rmapp, _PAGE_ACCESSED, 0,
10361036
old & PTE_RPN_MASK,
10371037
1UL << shift);
1038-
ref = 1;
1038+
ref = true;
10391039
}
10401040
return ref;
10411041
}
10421042

10431043
/* Called with kvm->mmu_lock held */
1044-
int kvm_test_age_radix(struct kvm *kvm, struct kvm_memory_slot *memslot,
1045-
unsigned long gfn)
1044+
bool kvm_test_age_radix(struct kvm *kvm, struct kvm_memory_slot *memslot,
1045+
unsigned long gfn)
1046+
10461047
{
10471048
pte_t *ptep;
10481049
unsigned long gpa = gfn << PAGE_SHIFT;
10491050
unsigned int shift;
1050-
int ref = 0;
1051+
bool ref = false;
10511052

10521053
if (kvm->arch.secure_guest & KVMPPC_SECURE_INIT_DONE)
10531054
return ref;
10541055

10551056
ptep = find_kvm_secondary_pte(kvm, gpa, &shift);
10561057
if (ptep && pte_present(*ptep) && pte_young(*ptep))
1057-
ref = 1;
1058+
ref = true;
10581059
return ref;
10591060
}
10601061

arch/powerpc/kvm/book3s_hv.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4770,7 +4770,7 @@ int kvmppc_switch_mmu_to_hpt(struct kvm *kvm)
47704770
kvmhv_release_all_nested(kvm);
47714771
kvmppc_rmap_reset(kvm);
47724772
kvm->arch.process_table = 0;
4773-
/* Mutual exclusion with kvm_unmap_hva_range etc. */
4773+
/* Mutual exclusion with kvm_unmap_gfn_range etc. */
47744774
spin_lock(&kvm->mmu_lock);
47754775
kvm->arch.radix = 0;
47764776
spin_unlock(&kvm->mmu_lock);
@@ -4792,7 +4792,7 @@ int kvmppc_switch_mmu_to_radix(struct kvm *kvm)
47924792
if (err)
47934793
return err;
47944794
kvmppc_rmap_reset(kvm);
4795-
/* Mutual exclusion with kvm_unmap_hva_range etc. */
4795+
/* Mutual exclusion with kvm_unmap_gfn_range etc. */
47964796
spin_lock(&kvm->mmu_lock);
47974797
kvm->arch.radix = 1;
47984798
spin_unlock(&kvm->mmu_lock);
@@ -5654,10 +5654,10 @@ static struct kvmppc_ops kvm_ops_hv = {
56545654
.flush_memslot = kvmppc_core_flush_memslot_hv,
56555655
.prepare_memory_region = kvmppc_core_prepare_memory_region_hv,
56565656
.commit_memory_region = kvmppc_core_commit_memory_region_hv,
5657-
.unmap_hva_range = kvm_unmap_hva_range_hv,
5658-
.age_hva = kvm_age_hva_hv,
5659-
.test_age_hva = kvm_test_age_hva_hv,
5660-
.set_spte_hva = kvm_set_spte_hva_hv,
5657+
.unmap_gfn_range = kvm_unmap_gfn_range_hv,
5658+
.age_gfn = kvm_age_gfn_hv,
5659+
.test_age_gfn = kvm_test_age_gfn_hv,
5660+
.set_spte_gfn = kvm_set_spte_gfn_hv,
56615661
.free_memslot = kvmppc_core_free_memslot_hv,
56625662
.init_vm = kvmppc_core_init_vm_hv,
56635663
.destroy_vm = kvmppc_core_destroy_vm_hv,

0 commit comments

Comments
 (0)