Refactor dat_set_slot(), _dat_slot_pte(), _dat_slot_crste(). Now they only take a struct kvm_s390_mmu_cache as priv. For dat_delete_slot(), mc is NULL, as no allocations should take place. This is needed as a prerequisite to move gmap DAT table setup from kvm_arch_commit_memory_region() to kvm_arch_prepare_memory_region(). Signed-off-by: Claudio Imbrenda --- arch/s390/kvm/dat.c | 29 +++++++++-------------------- arch/s390/kvm/dat.h | 10 ++++------ arch/s390/kvm/kvm-s390.c | 4 ++-- 3 files changed, 15 insertions(+), 28 deletions(-) diff --git a/arch/s390/kvm/dat.c b/arch/s390/kvm/dat.c index f2ea013cb33e..7e5dd5a1eb1e 100644 --- a/arch/s390/kvm/dat.c +++ b/arch/s390/kvm/dat.c @@ -844,19 +844,12 @@ long dat_reset_skeys(union asce asce, gfn_t start) return _dat_walk_gfn_range(start, asce_end(asce), asce, &ops, DAT_WALK_IGN_HOLES, NULL); } -struct slot_priv { - unsigned long token; - struct kvm_s390_mmu_cache *mc; -}; - static long _dat_slot_pte(union pte *ptep, gfn_t gfn, gfn_t next, struct dat_walk *walk) { - struct slot_priv *p = walk->priv; - union crste dummy = { .val = p->token }; union pte new_pte, pte = READ_ONCE(*ptep); union pgste pgste; - new_pte = _PTE_TOK(dummy.tok.type, dummy.tok.par); + new_pte = walk->priv ? _PTE_EMPTY : _PTE_TOK(_DAT_TOKEN_PIC, PGM_ADDRESSING); /* Table entry already in the desired state. */ if (pte.val == new_pte.val) @@ -873,10 +866,9 @@ static long _dat_slot_pte(union pte *ptep, gfn_t gfn, gfn_t next, struct dat_wal static long _dat_slot_crste(union crste *crstep, gfn_t gfn, gfn_t next, struct dat_walk *walk) { union crste new_crste, crste = READ_ONCE(*crstep); - struct slot_priv *p = walk->priv; + struct kvm_s390_mmu_cache *mc = walk->priv; - new_crste.val = p->token; - new_crste.h.tt = crste.h.tt; + new_crste = mc ? _CRSTE_EMPTY(crste.h.tt) : _CRSTE_HOLE(crste.h.tt); /* Table entry already in the desired state. */ if (crste.val == new_crste.val) @@ -900,7 +892,10 @@ static long _dat_slot_crste(union crste *crstep, gfn_t gfn, gfn_t next, struct d if (!crste.h.fc && !crste.h.i) return 0; /* Split (install a lower level table), and handle things there. */ - return dat_split_crste(p->mc, crstep, gfn, walk->asce, false); + if (mc) + return dat_split_crste(mc, crstep, gfn, walk->asce, false); + /* A large page should never cross memslots boundaries */ + return -EINVAL; } static const struct dat_walk_ops dat_slot_ops = { @@ -908,16 +903,10 @@ static const struct dat_walk_ops dat_slot_ops = { .crste_ops = { _dat_slot_crste, _dat_slot_crste, _dat_slot_crste, _dat_slot_crste, }, }; -int dat_set_slot(struct kvm_s390_mmu_cache *mc, union asce asce, gfn_t start, gfn_t end, - u16 type, u16 param) +int dat_set_slot(struct kvm_s390_mmu_cache *mc, union asce asce, gfn_t start, gfn_t end) { - struct slot_priv priv = { - .token = _CRSTE_TOK(0, type, param).val, - .mc = mc, - }; - return _dat_walk_gfn_range(start, end, asce, &dat_slot_ops, - DAT_WALK_IGN_HOLES | DAT_WALK_ANY, &priv); + DAT_WALK_IGN_HOLES | DAT_WALK_ANY, mc); } static void pgste_set_unlock_multiple(union pte *first, int n, union pgste *pgstes) diff --git a/arch/s390/kvm/dat.h b/arch/s390/kvm/dat.h index 141ee7b9f019..57f32ac9ffed 100644 --- a/arch/s390/kvm/dat.h +++ b/arch/s390/kvm/dat.h @@ -543,8 +543,7 @@ long dat_reset_skeys(union asce asce, gfn_t start); unsigned long dat_get_ptval(struct page_table *table, struct ptval_param param); void dat_set_ptval(struct page_table *table, struct ptval_param param, unsigned long val); -int dat_set_slot(struct kvm_s390_mmu_cache *mc, union asce asce, gfn_t start, gfn_t end, - u16 type, u16 param); +int dat_set_slot(struct kvm_s390_mmu_cache *mc, union asce asce, gfn_t start, gfn_t end); int dat_set_prefix_notif_bit(union asce asce, gfn_t gfn); bool dat_test_age_gfn(union asce asce, gfn_t start, gfn_t end); @@ -958,16 +957,15 @@ static inline int get_level(union crste *crstep, union pte *ptep) return ptep ? TABLE_TYPE_PAGE_TABLE : crstep->h.tt; } -static inline int dat_delete_slot(struct kvm_s390_mmu_cache *mc, union asce asce, gfn_t start, - unsigned long npages) +static inline int dat_delete_slot(union asce asce, gfn_t start, unsigned long npages) { - return dat_set_slot(mc, asce, start, start + npages, _DAT_TOKEN_PIC, PGM_ADDRESSING); + return dat_set_slot(NULL, asce, start, start + npages); } static inline int dat_create_slot(struct kvm_s390_mmu_cache *mc, union asce asce, gfn_t start, unsigned long npages) { - return dat_set_slot(mc, asce, start, start + npages, _DAT_TOKEN_NONE, 0); + return dat_set_slot(mc, asce, start, start + npages); } static inline bool crste_is_ucas(union crste crste) diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 91b975835457..212ff0f8eecc 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -5860,10 +5860,10 @@ void kvm_arch_commit_memory_region(struct kvm *kvm, switch (change) { case KVM_MR_DELETE: - rc = dat_delete_slot(mc, kvm->arch.gmap->asce, old->base_gfn, old->npages); + rc = dat_delete_slot(kvm->arch.gmap->asce, old->base_gfn, old->npages); break; case KVM_MR_MOVE: - rc = dat_delete_slot(mc, kvm->arch.gmap->asce, old->base_gfn, old->npages); + rc = dat_delete_slot(kvm->arch.gmap->asce, old->base_gfn, old->npages); if (rc) break; fallthrough; -- 2.55.0