Skip to content

Commit e38c884

Browse files
author
Claudio Imbrenda
committed
KVM: s390: Switch to new gmap
Switch KVM/s390 to use the new gmap code. Remove includes to <gmap.h> and include "gmap.h" instead; fix all the existing users of the old gmap functions to use the new ones instead. Fix guest storage key access functions to work with the new gmap. Acked-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
1 parent d29a29a commit e38c884

21 files changed

Lines changed: 1119 additions & 1726 deletions

arch/s390/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ config GENERIC_LOCKBREAK
3333
def_bool y if PREEMPTION
3434

3535
config PGSTE
36-
def_bool y if KVM
36+
def_bool n
3737

3838
config AUDIT_ARCH
3939
def_bool y

arch/s390/include/asm/kvm_host.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,7 @@ struct kvm_vcpu_arch {
442442
bool acrs_loaded;
443443
struct kvm_s390_pv_vcpu pv;
444444
union diag318_info diag318_info;
445-
void *mc; /* Placeholder */
445+
struct kvm_s390_mmu_cache *mc;
446446
};
447447

448448
struct kvm_vm_stat {
@@ -636,6 +636,8 @@ struct kvm_s390_pv {
636636
struct mutex import_lock;
637637
};
638638

639+
struct kvm_s390_mmu_cache;
640+
639641
struct kvm_arch {
640642
struct esca_block *sca;
641643
debug_info_t *dbf;
@@ -675,6 +677,7 @@ struct kvm_arch {
675677
struct kvm_s390_pv pv;
676678
struct list_head kzdev_list;
677679
spinlock_t kzdev_list_lock;
680+
struct kvm_s390_mmu_cache *mc;
678681
};
679682

680683
#define KVM_HVA_ERR_BAD (-1UL)

arch/s390/include/asm/mmu_context.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,7 @@ static inline int init_new_context(struct task_struct *tsk,
3030
mm->context.gmap_asce = 0;
3131
mm->context.flush_mm = 0;
3232
#if IS_ENABLED(CONFIG_KVM)
33-
mm->context.has_pgste = 0;
34-
mm->context.uses_skeys = 0;
35-
mm->context.uses_cmm = 0;
3633
mm->context.allow_cow_sharing = 1;
37-
mm->context.allow_gmap_hpage_1m = 0;
3834
#endif
3935
switch (mm->context.asce_limit) {
4036
default:

arch/s390/include/asm/tlb.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ static inline bool __tlb_remove_folio_pages(struct mmu_gather *tlb,
3636

3737
#include <asm/tlbflush.h>
3838
#include <asm-generic/tlb.h>
39-
#include <asm/gmap.h>
4039

4140
/*
4241
* Release the page cache reference for a pte removed by
@@ -85,8 +84,6 @@ static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
8584
tlb->mm->context.flush_mm = 1;
8685
tlb->freed_tables = 1;
8786
tlb->cleared_pmds = 1;
88-
if (mm_has_pgste(tlb->mm))
89-
gmap_unlink(tlb->mm, (unsigned long *)pte, address);
9087
tlb_remove_ptdesc(tlb, virt_to_ptdesc(pte));
9188
}
9289

arch/s390/include/asm/uaccess.h

Lines changed: 10 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -471,65 +471,15 @@ do { \
471471
#define arch_get_kernel_nofault __mvc_kernel_nofault
472472
#define arch_put_kernel_nofault __mvc_kernel_nofault
473473

474-
void __cmpxchg_user_key_called_with_bad_pointer(void);
475-
476-
int __cmpxchg_user_key1(unsigned long address, unsigned char *uval,
477-
unsigned char old, unsigned char new, unsigned long key);
478-
int __cmpxchg_user_key2(unsigned long address, unsigned short *uval,
479-
unsigned short old, unsigned short new, unsigned long key);
480-
int __cmpxchg_user_key4(unsigned long address, unsigned int *uval,
481-
unsigned int old, unsigned int new, unsigned long key);
482-
int __cmpxchg_user_key8(unsigned long address, unsigned long *uval,
483-
unsigned long old, unsigned long new, unsigned long key);
484-
int __cmpxchg_user_key16(unsigned long address, __uint128_t *uval,
485-
__uint128_t old, __uint128_t new, unsigned long key);
486-
487-
static __always_inline int _cmpxchg_user_key(unsigned long address, void *uval,
488-
__uint128_t old, __uint128_t new,
489-
unsigned long key, int size)
490-
{
491-
switch (size) {
492-
case 1: return __cmpxchg_user_key1(address, uval, old, new, key);
493-
case 2: return __cmpxchg_user_key2(address, uval, old, new, key);
494-
case 4: return __cmpxchg_user_key4(address, uval, old, new, key);
495-
case 8: return __cmpxchg_user_key8(address, uval, old, new, key);
496-
case 16: return __cmpxchg_user_key16(address, uval, old, new, key);
497-
default: __cmpxchg_user_key_called_with_bad_pointer();
498-
}
499-
return 0;
500-
}
501-
502-
/**
503-
* cmpxchg_user_key() - cmpxchg with user space target, honoring storage keys
504-
* @ptr: User space address of value to compare to @old and exchange with
505-
* @new. Must be aligned to sizeof(*@ptr).
506-
* @uval: Address where the old value of *@ptr is written to.
507-
* @old: Old value. Compared to the content pointed to by @ptr in order to
508-
* determine if the exchange occurs. The old value read from *@ptr is
509-
* written to *@uval.
510-
* @new: New value to place at *@ptr.
511-
* @key: Access key to use for checking storage key protection.
512-
*
513-
* Perform a cmpxchg on a user space target, honoring storage key protection.
514-
* @key alone determines how key checking is performed, neither
515-
* storage-protection-override nor fetch-protection-override apply.
516-
* The caller must compare *@uval and @old to determine if values have been
517-
* exchanged. In case of an exception *@uval is set to zero.
518-
*
519-
* Return: 0: cmpxchg executed
520-
* -EFAULT: an exception happened when trying to access *@ptr
521-
* -EAGAIN: maxed out number of retries (byte and short only)
522-
*/
523-
#define cmpxchg_user_key(ptr, uval, old, new, key) \
524-
({ \
525-
__typeof__(ptr) __ptr = (ptr); \
526-
__typeof__(uval) __uval = (uval); \
527-
\
528-
BUILD_BUG_ON(sizeof(*(__ptr)) != sizeof(*(__uval))); \
529-
might_fault(); \
530-
__chk_user_ptr(__ptr); \
531-
_cmpxchg_user_key((unsigned long)(__ptr), (void *)(__uval), \
532-
(old), (new), (key), sizeof(*(__ptr))); \
533-
})
474+
int __cmpxchg_key1(void *address, unsigned char *uval, unsigned char old,
475+
unsigned char new, unsigned long key);
476+
int __cmpxchg_key2(void *address, unsigned short *uval, unsigned short old,
477+
unsigned short new, unsigned long key);
478+
int __cmpxchg_key4(void *address, unsigned int *uval, unsigned int old,
479+
unsigned int new, unsigned long key);
480+
int __cmpxchg_key8(void *address, unsigned long *uval, unsigned long old,
481+
unsigned long new, unsigned long key);
482+
int __cmpxchg_key16(void *address, __uint128_t *uval, __uint128_t old,
483+
__uint128_t new, unsigned long key);
534484

535485
#endif /* __S390_UACCESS_H */

arch/s390/include/asm/uv.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -631,7 +631,6 @@ int uv_pin_shared(unsigned long paddr);
631631
int uv_destroy_folio(struct folio *folio);
632632
int uv_destroy_pte(pte_t pte);
633633
int uv_convert_from_secure_pte(pte_t pte);
634-
int make_hva_secure(struct mm_struct *mm, unsigned long hva, struct uv_cb_header *uvcb);
635634
int s390_wiggle_split_folio(struct mm_struct *mm, struct folio *folio);
636635
int __make_folio_secure(struct folio *folio, struct uv_cb_header *uvcb);
637636
int uv_convert_from_secure(unsigned long paddr);

arch/s390/kernel/uv.c

Lines changed: 7 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -209,39 +209,6 @@ int uv_convert_from_secure_pte(pte_t pte)
209209
return uv_convert_from_secure_folio(pfn_folio(pte_pfn(pte)));
210210
}
211211

212-
/**
213-
* should_export_before_import - Determine whether an export is needed
214-
* before an import-like operation
215-
* @uvcb: the Ultravisor control block of the UVC to be performed
216-
* @mm: the mm of the process
217-
*
218-
* Returns whether an export is needed before every import-like operation.
219-
* This is needed for shared pages, which don't trigger a secure storage
220-
* exception when accessed from a different guest.
221-
*
222-
* Although considered as one, the Unpin Page UVC is not an actual import,
223-
* so it is not affected.
224-
*
225-
* No export is needed also when there is only one protected VM, because the
226-
* page cannot belong to the wrong VM in that case (there is no "other VM"
227-
* it can belong to).
228-
*
229-
* Return: true if an export is needed before every import, otherwise false.
230-
*/
231-
static bool should_export_before_import(struct uv_cb_header *uvcb, struct mm_struct *mm)
232-
{
233-
/*
234-
* The misc feature indicates, among other things, that importing a
235-
* shared page from a different protected VM will automatically also
236-
* transfer its ownership.
237-
*/
238-
if (uv_has_feature(BIT_UV_FEAT_MISC))
239-
return false;
240-
if (uvcb->cmd == UVC_CMD_UNPIN_PAGE_SHARED)
241-
return false;
242-
return atomic_read(&mm->context.protected_count) > 1;
243-
}
244-
245212
/*
246213
* Calculate the expected ref_count for a folio that would otherwise have no
247214
* further pins. This was cribbed from similar functions in other places in
@@ -313,20 +280,6 @@ int __make_folio_secure(struct folio *folio, struct uv_cb_header *uvcb)
313280
}
314281
EXPORT_SYMBOL(__make_folio_secure);
315282

316-
static int make_folio_secure(struct mm_struct *mm, struct folio *folio, struct uv_cb_header *uvcb)
317-
{
318-
int rc;
319-
320-
if (!folio_trylock(folio))
321-
return -EAGAIN;
322-
if (should_export_before_import(uvcb, mm))
323-
uv_convert_from_secure(folio_to_phys(folio));
324-
rc = __make_folio_secure(folio, uvcb);
325-
folio_unlock(folio);
326-
327-
return rc;
328-
}
329-
330283
/**
331284
* s390_wiggle_split_folio() - try to drain extra references to a folio and
332285
* split the folio if it is large.
@@ -414,56 +367,6 @@ int s390_wiggle_split_folio(struct mm_struct *mm, struct folio *folio)
414367
}
415368
EXPORT_SYMBOL_GPL(s390_wiggle_split_folio);
416369

417-
int make_hva_secure(struct mm_struct *mm, unsigned long hva, struct uv_cb_header *uvcb)
418-
{
419-
struct vm_area_struct *vma;
420-
struct folio_walk fw;
421-
struct folio *folio;
422-
int rc;
423-
424-
mmap_read_lock(mm);
425-
vma = vma_lookup(mm, hva);
426-
if (!vma) {
427-
mmap_read_unlock(mm);
428-
return -EFAULT;
429-
}
430-
folio = folio_walk_start(&fw, vma, hva, 0);
431-
if (!folio) {
432-
mmap_read_unlock(mm);
433-
return -ENXIO;
434-
}
435-
436-
folio_get(folio);
437-
/*
438-
* Secure pages cannot be huge and userspace should not combine both.
439-
* In case userspace does it anyway this will result in an -EFAULT for
440-
* the unpack. The guest is thus never reaching secure mode.
441-
* If userspace plays dirty tricks and decides to map huge pages at a
442-
* later point in time, it will receive a segmentation fault or
443-
* KVM_RUN will return -EFAULT.
444-
*/
445-
if (folio_test_hugetlb(folio))
446-
rc = -EFAULT;
447-
else if (folio_test_large(folio))
448-
rc = -E2BIG;
449-
else if (!pte_write(fw.pte) || (pte_val(fw.pte) & _PAGE_INVALID))
450-
rc = -ENXIO;
451-
else
452-
rc = make_folio_secure(mm, folio, uvcb);
453-
folio_walk_end(&fw, vma);
454-
mmap_read_unlock(mm);
455-
456-
if (rc == -E2BIG || rc == -EBUSY) {
457-
rc = s390_wiggle_split_folio(mm, folio);
458-
if (!rc)
459-
rc = -EAGAIN;
460-
}
461-
folio_put(folio);
462-
463-
return rc;
464-
}
465-
EXPORT_SYMBOL_GPL(make_hva_secure);
466-
467370
/*
468371
* To be called with the folio locked or with an extra reference! This will
469372
* prevent kvm_s390_pv_make_secure() from touching the folio concurrently.
@@ -474,21 +377,18 @@ int arch_make_folio_accessible(struct folio *folio)
474377
{
475378
int rc = 0;
476379

477-
/* Large folios cannot be secure */
478-
if (unlikely(folio_test_large(folio)))
479-
return 0;
480-
481380
/*
482-
* PG_arch_1 is used in 2 places:
483-
* 1. for storage keys of hugetlb folios and KVM
484-
* 2. As an indication that this small folio might be secure. This can
485-
* overindicate, e.g. we set the bit before calling
486-
* convert_to_secure.
487-
* As secure pages are never large folios, both variants can co-exists.
381+
* PG_arch_1 is used as an indication that this small folio might be
382+
* secure. This can overindicate, e.g. we set the bit before calling
383+
* convert_to_secure.
488384
*/
489385
if (!test_bit(PG_arch_1, &folio->flags.f))
490386
return 0;
491387

388+
/* Large folios cannot be secure. */
389+
if (WARN_ON_ONCE(folio_test_large(folio)))
390+
return -EFAULT;
391+
492392
rc = uv_pin_shared(folio_to_phys(folio));
493393
if (!rc) {
494394
clear_bit(PG_arch_1, &folio->flags.f);

arch/s390/kvm/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ include $(srctree)/virt/kvm/Makefile.kvm
88
ccflags-y := -Ivirt/kvm -Iarch/s390/kvm
99

1010
kvm-y += kvm-s390.o intercept.o interrupt.o priv.o sigp.o
11-
kvm-y += diag.o gaccess.o guestdbg.o vsie.o pv.o gmap-vsie.o
11+
kvm-y += diag.o gaccess.o guestdbg.o vsie.o pv.o
1212
kvm-y += dat.o gmap.o faultin.o
1313

1414
kvm-$(CONFIG_VFIO_PCI_ZDEV_KVM) += pci.o

arch/s390/kvm/diag.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@
1010

1111
#include <linux/kvm.h>
1212
#include <linux/kvm_host.h>
13-
#include <asm/gmap.h>
1413
#include <asm/gmap_helpers.h>
1514
#include <asm/virtio-ccw.h>
1615
#include "kvm-s390.h"
1716
#include "trace.h"
1817
#include "trace-s390.h"
1918
#include "gaccess.h"
19+
#include "gmap.h"
2020

2121
static void do_discard_gfn_range(struct kvm_vcpu *vcpu, gfn_t gfn_start, gfn_t gfn_end)
2222
{

0 commit comments

Comments
 (0)