Commit e38c884d authored by Claudio Imbrenda's avatar Claudio Imbrenda
Browse files

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: default avatarHeiko Carstens <hca@linux.ibm.com>
Signed-off-by: default avatarClaudio Imbrenda <imbrenda@linux.ibm.com>
parent d29a29a9
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@ config GENERIC_LOCKBREAK
	def_bool y if PREEMPTION

config PGSTE
	def_bool y if KVM
	def_bool n

config AUDIT_ARCH
	def_bool y
+4 −1
Original line number Diff line number Diff line
@@ -442,7 +442,7 @@ struct kvm_vcpu_arch {
	bool acrs_loaded;
	struct kvm_s390_pv_vcpu pv;
	union diag318_info diag318_info;
	void *mc; /* Placeholder */
	struct kvm_s390_mmu_cache *mc;
};

struct kvm_vm_stat {
@@ -636,6 +636,8 @@ struct kvm_s390_pv {
	struct mutex import_lock;
};

struct kvm_s390_mmu_cache;

struct kvm_arch {
	struct esca_block *sca;
	debug_info_t *dbf;
@@ -675,6 +677,7 @@ struct kvm_arch {
	struct kvm_s390_pv pv;
	struct list_head kzdev_list;
	spinlock_t kzdev_list_lock;
	struct kvm_s390_mmu_cache *mc;
};

#define KVM_HVA_ERR_BAD		(-1UL)
+0 −4
Original line number Diff line number Diff line
@@ -30,11 +30,7 @@ static inline int init_new_context(struct task_struct *tsk,
	mm->context.gmap_asce = 0;
	mm->context.flush_mm = 0;
#if IS_ENABLED(CONFIG_KVM)
	mm->context.has_pgste = 0;
	mm->context.uses_skeys = 0;
	mm->context.uses_cmm = 0;
	mm->context.allow_cow_sharing = 1;
	mm->context.allow_gmap_hpage_1m = 0;
#endif
	switch (mm->context.asce_limit) {
	default:
+0 −3
Original line number Diff line number Diff line
@@ -36,7 +36,6 @@ static inline bool __tlb_remove_folio_pages(struct mmu_gather *tlb,

#include <asm/tlbflush.h>
#include <asm-generic/tlb.h>
#include <asm/gmap.h>

/*
 * 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,
	tlb->mm->context.flush_mm = 1;
	tlb->freed_tables = 1;
	tlb->cleared_pmds = 1;
	if (mm_has_pgste(tlb->mm))
		gmap_unlink(tlb->mm, (unsigned long *)pte, address);
	tlb_remove_ptdesc(tlb, virt_to_ptdesc(pte));
}

+10 −60
Original line number Diff line number Diff line
@@ -471,65 +471,15 @@ do { \
#define arch_get_kernel_nofault __mvc_kernel_nofault
#define arch_put_kernel_nofault __mvc_kernel_nofault

void __cmpxchg_user_key_called_with_bad_pointer(void);

int __cmpxchg_user_key1(unsigned long address, unsigned char *uval,
			unsigned char old, unsigned char new, unsigned long key);
int __cmpxchg_user_key2(unsigned long address, unsigned short *uval,
			unsigned short old, unsigned short new, unsigned long key);
int __cmpxchg_user_key4(unsigned long address, unsigned int *uval,
			unsigned int old, unsigned int new, unsigned long key);
int __cmpxchg_user_key8(unsigned long address, unsigned long *uval,
			unsigned long old, unsigned long new, unsigned long key);
int __cmpxchg_user_key16(unsigned long address, __uint128_t *uval,
			 __uint128_t old, __uint128_t new, unsigned long key);

static __always_inline int _cmpxchg_user_key(unsigned long address, void *uval,
					     __uint128_t old, __uint128_t new,
					     unsigned long key, int size)
{
	switch (size) {
	case 1:  return __cmpxchg_user_key1(address, uval, old, new, key);
	case 2:  return __cmpxchg_user_key2(address, uval, old, new, key);
	case 4:  return __cmpxchg_user_key4(address, uval, old, new, key);
	case 8:  return __cmpxchg_user_key8(address, uval, old, new, key);
	case 16: return __cmpxchg_user_key16(address, uval, old, new, key);
	default: __cmpxchg_user_key_called_with_bad_pointer();
	}
	return 0;
}

/**
 * cmpxchg_user_key() - cmpxchg with user space target, honoring storage keys
 * @ptr: User space address of value to compare to @old and exchange with
 *	 @new. Must be aligned to sizeof(*@ptr).
 * @uval: Address where the old value of *@ptr is written to.
 * @old: Old value. Compared to the content pointed to by @ptr in order to
 *	 determine if the exchange occurs. The old value read from *@ptr is
 *	 written to *@uval.
 * @new: New value to place at *@ptr.
 * @key: Access key to use for checking storage key protection.
 *
 * Perform a cmpxchg on a user space target, honoring storage key protection.
 * @key alone determines how key checking is performed, neither
 * storage-protection-override nor fetch-protection-override apply.
 * The caller must compare *@uval and @old to determine if values have been
 * exchanged. In case of an exception *@uval is set to zero.
 *
 * Return:     0: cmpxchg executed
 *	       -EFAULT: an exception happened when trying to access *@ptr
 *	       -EAGAIN: maxed out number of retries (byte and short only)
 */
#define cmpxchg_user_key(ptr, uval, old, new, key)			\
({									\
	__typeof__(ptr) __ptr = (ptr);					\
	__typeof__(uval) __uval = (uval);				\
									\
	BUILD_BUG_ON(sizeof(*(__ptr)) != sizeof(*(__uval)));		\
	might_fault();							\
	__chk_user_ptr(__ptr);						\
	_cmpxchg_user_key((unsigned long)(__ptr), (void *)(__uval),	\
			  (old), (new), (key), sizeof(*(__ptr)));	\
})
int __cmpxchg_key1(void *address, unsigned char *uval, unsigned char old,
		   unsigned char new, unsigned long key);
int __cmpxchg_key2(void *address, unsigned short *uval, unsigned short old,
		   unsigned short new, unsigned long key);
int __cmpxchg_key4(void *address, unsigned int *uval, unsigned int old,
		   unsigned int new, unsigned long key);
int __cmpxchg_key8(void *address, unsigned long *uval, unsigned long old,
		   unsigned long new, unsigned long key);
int __cmpxchg_key16(void *address, __uint128_t *uval, __uint128_t old,
		    __uint128_t new, unsigned long key);

#endif /* __S390_UACCESS_H */
Loading