Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6e0ff1b4 authored by Radim Krčmář's avatar Radim Krčmář
Browse files
KVM: s390: Fixes and features for 4.14

- merge of topic branch tlb-flushing from the s390 tree to get the
  no-dat base features
- merge of kvm/master to avoid conflicts with additional sthyi fixes
- wire up the no-dat enhancements in KVM
- multiple epoch facility (z14 feature)
- Configuration z/Architecture Mode
- more sthyi fixes
- gdb server range checking fix
- small code cleanups
parents 712b12d7 c95c8953
Loading
Loading
Loading
Loading
+13 −1
Original line number Original line Diff line number Diff line
@@ -176,7 +176,8 @@ Architectures: s390


3.1. ATTRIBUTE: KVM_S390_VM_TOD_HIGH
3.1. ATTRIBUTE: KVM_S390_VM_TOD_HIGH


Allows user space to set/get the TOD clock extension (u8).
Allows user space to set/get the TOD clock extension (u8) (superseded by
KVM_S390_VM_TOD_EXT).


Parameters: address of a buffer in user space to store the data (u8) to
Parameters: address of a buffer in user space to store the data (u8) to
Returns:    -EFAULT if the given address is not accessible from kernel space
Returns:    -EFAULT if the given address is not accessible from kernel space
@@ -190,6 +191,17 @@ the POP (u64).
Parameters: address of a buffer in user space to store the data (u64) to
Parameters: address of a buffer in user space to store the data (u64) to
Returns:    -EFAULT if the given address is not accessible from kernel space
Returns:    -EFAULT if the given address is not accessible from kernel space


3.3. ATTRIBUTE: KVM_S390_VM_TOD_EXT
Allows user space to set/get bits 0-63 of the TOD clock register as defined in
the POP (u64). If the guest CPU model supports the TOD clock extension (u8), it
also allows user space to get/set it. If the guest CPU model does not support
it, it is stored as 0 and not allowed to be set to a value != 0.

Parameters: address of a buffer in user space to store the data
            (kvm_s390_vm_tod_clock) to
Returns:    -EFAULT if the given address is not accessible from kernel space
	    -EINVAL if setting the TOD clock extension to != 0 is not supported

4. GROUP: KVM_S390_VM_CRYPTO
4. GROUP: KVM_S390_VM_CRYPTO
Architectures: s390
Architectures: s390


+5 −1
Original line number Original line Diff line number Diff line
@@ -226,7 +226,9 @@ struct kvm_s390_sie_block {
#define ECB3_RI  0x01
#define ECB3_RI  0x01
	__u8    ecb3;			/* 0x0063 */
	__u8    ecb3;			/* 0x0063 */
	__u32	scaol;			/* 0x0064 */
	__u32	scaol;			/* 0x0064 */
	__u8	reserved68[4];		/* 0x0068 */
	__u8	reserved68;		/* 0x0068 */
	__u8    epdx;			/* 0x0069 */
	__u8    reserved6a[2];		/* 0x006a */
	__u32	todpr;			/* 0x006c */
	__u32	todpr;			/* 0x006c */
	__u8	reserved70[16];		/* 0x0070 */
	__u8	reserved70[16];		/* 0x0070 */
	__u64	mso;			/* 0x0080 */
	__u64	mso;			/* 0x0080 */
@@ -265,6 +267,7 @@ struct kvm_s390_sie_block {
	__u64	cbrlo;			/* 0x01b8 */
	__u64	cbrlo;			/* 0x01b8 */
	__u8	reserved1c0[8];		/* 0x01c0 */
	__u8	reserved1c0[8];		/* 0x01c0 */
#define ECD_HOSTREGMGMT	0x20000000
#define ECD_HOSTREGMGMT	0x20000000
#define ECD_MEF		0x08000000
	__u32	ecd;			/* 0x01c8 */
	__u32	ecd;			/* 0x01c8 */
	__u8	reserved1cc[18];	/* 0x01cc */
	__u8	reserved1cc[18];	/* 0x01cc */
	__u64	pp;			/* 0x01de */
	__u64	pp;			/* 0x01de */
@@ -739,6 +742,7 @@ struct kvm_arch{
	struct kvm_s390_cpu_model model;
	struct kvm_s390_cpu_model model;
	struct kvm_s390_crypto crypto;
	struct kvm_s390_crypto crypto;
	struct kvm_s390_vsie vsie;
	struct kvm_s390_vsie vsie;
	u8 epdx;
	u64 epoch;
	u64 epoch;
	struct kvm_s390_migration_state *migration_state;
	struct kvm_s390_migration_state *migration_state;
	/* subset of available cpu features enabled by user space */
	/* subset of available cpu features enabled by user space */
+2 −1
Original line number Original line Diff line number Diff line
@@ -13,7 +13,8 @@
#define ESSA_SET_POT_VOLATILE		4
#define ESSA_SET_POT_VOLATILE		4
#define ESSA_SET_STABLE_RESIDENT	5
#define ESSA_SET_STABLE_RESIDENT	5
#define ESSA_SET_STABLE_IF_RESIDENT	6
#define ESSA_SET_STABLE_IF_RESIDENT	6
#define ESSA_SET_STABLE_NODAT		7


#define ESSA_MAX	ESSA_SET_STABLE_IF_RESIDENT
#define ESSA_MAX	ESSA_SET_STABLE_NODAT


#endif
#endif
+3 −0
Original line number Original line Diff line number Diff line
@@ -133,6 +133,9 @@ static inline int page_reset_referenced(unsigned long addr)
struct page;
struct page;
void arch_free_page(struct page *page, int order);
void arch_free_page(struct page *page, int order);
void arch_alloc_page(struct page *page, int order);
void arch_alloc_page(struct page *page, int order);
void arch_set_page_dat(struct page *page, int order);
void arch_set_page_nodat(struct page *page, int order);
int arch_test_page_nodat(struct page *page);
void arch_set_page_states(int make_stable);
void arch_set_page_states(int make_stable);


static inline int devmem_is_allowed(unsigned long pfn)
static inline int devmem_is_allowed(unsigned long pfn)
+67 −21
Original line number Original line Diff line number Diff line
@@ -376,6 +376,7 @@ static inline int is_module_addr(void *addr)


/* Guest Page State used for virtualization */
/* Guest Page State used for virtualization */
#define _PGSTE_GPS_ZERO			0x0000000080000000UL
#define _PGSTE_GPS_ZERO			0x0000000080000000UL
#define _PGSTE_GPS_NODAT		0x0000000040000000UL
#define _PGSTE_GPS_USAGE_MASK		0x0000000003000000UL
#define _PGSTE_GPS_USAGE_MASK		0x0000000003000000UL
#define _PGSTE_GPS_USAGE_STABLE		0x0000000000000000UL
#define _PGSTE_GPS_USAGE_STABLE		0x0000000000000000UL
#define _PGSTE_GPS_USAGE_UNUSED		0x0000000001000000UL
#define _PGSTE_GPS_USAGE_UNUSED		0x0000000001000000UL
@@ -952,15 +953,30 @@ static inline pte_t pte_mkhuge(pte_t pte)
#define IPTE_GLOBAL	0
#define IPTE_GLOBAL	0
#define	IPTE_LOCAL	1
#define	IPTE_LOCAL	1


static inline void __ptep_ipte(unsigned long address, pte_t *ptep, int local)
#define IPTE_NODAT	0x400
#define IPTE_GUEST_ASCE	0x800

static inline void __ptep_ipte(unsigned long address, pte_t *ptep,
			       unsigned long opt, unsigned long asce,
			       int local)
{
{
	unsigned long pto = (unsigned long) ptep;
	unsigned long pto = (unsigned long) ptep;


	if (__builtin_constant_p(opt) && opt == 0) {
		/* Invalidation + TLB flush for the pte */
		/* Invalidation + TLB flush for the pte */
		asm volatile(
		asm volatile(
			"	.insn	rrf,0xb2210000,%[r1],%[r2],0,%[m4]"
			"	.insn	rrf,0xb2210000,%[r1],%[r2],0,%[m4]"
			: "+m" (*ptep) : [r1] "a" (pto), [r2] "a" (address),
			: "+m" (*ptep) : [r1] "a" (pto), [r2] "a" (address),
			  [m4] "i" (local));
			  [m4] "i" (local));
		return;
	}

	/* Invalidate ptes with options + TLB flush of the ptes */
	opt = opt | (asce & _ASCE_ORIGIN);
	asm volatile(
		"	.insn	rrf,0xb2210000,%[r1],%[r2],%[r3],%[m4]"
		: [r2] "+a" (address), [r3] "+a" (opt)
		: [r1] "a" (pto), [m4] "i" (local) : "memory");
}
}


static inline void __ptep_ipte_range(unsigned long address, int nr,
static inline void __ptep_ipte_range(unsigned long address, int nr,
@@ -1341,31 +1357,61 @@ static inline void __pmdp_csp(pmd_t *pmdp)
#define IDTE_GLOBAL	0
#define IDTE_GLOBAL	0
#define IDTE_LOCAL	1
#define IDTE_LOCAL	1


static inline void __pmdp_idte(unsigned long address, pmd_t *pmdp, int local)
#define IDTE_PTOA	0x0800
#define IDTE_NODAT	0x1000
#define IDTE_GUEST_ASCE	0x2000

static inline void __pmdp_idte(unsigned long addr, pmd_t *pmdp,
			       unsigned long opt, unsigned long asce,
			       int local)
{
{
	unsigned long sto;
	unsigned long sto;


	sto = (unsigned long) pmdp - pmd_index(address) * sizeof(pmd_t);
	sto = (unsigned long) pmdp - pmd_index(addr) * sizeof(pmd_t);
	if (__builtin_constant_p(opt) && opt == 0) {
		/* flush without guest asce */
		asm volatile(
		asm volatile(
			"	.insn	rrf,0xb98e0000,%[r1],%[r2],0,%[m4]"
			"	.insn	rrf,0xb98e0000,%[r1],%[r2],0,%[m4]"
			: "+m" (*pmdp)
			: "+m" (*pmdp)
		: [r1] "a" (sto), [r2] "a" ((address & HPAGE_MASK)),
			: [r1] "a" (sto), [r2] "a" ((addr & HPAGE_MASK)),
			  [m4] "i" (local)
			  [m4] "i" (local)
			: "cc" );
			: "cc" );
	} else {
		/* flush with guest asce */
		asm volatile(
			"	.insn	rrf,0xb98e0000,%[r1],%[r2],%[r3],%[m4]"
			: "+m" (*pmdp)
			: [r1] "a" (sto), [r2] "a" ((addr & HPAGE_MASK) | opt),
			  [r3] "a" (asce), [m4] "i" (local)
			: "cc" );
	}
}
}


static inline void __pudp_idte(unsigned long address, pud_t *pudp, int local)
static inline void __pudp_idte(unsigned long addr, pud_t *pudp,
			       unsigned long opt, unsigned long asce,
			       int local)
{
{
	unsigned long r3o;
	unsigned long r3o;


	r3o = (unsigned long) pudp - pud_index(address) * sizeof(pud_t);
	r3o = (unsigned long) pudp - pud_index(addr) * sizeof(pud_t);
	r3o |= _ASCE_TYPE_REGION3;
	r3o |= _ASCE_TYPE_REGION3;
	if (__builtin_constant_p(opt) && opt == 0) {
		/* flush without guest asce */
		asm volatile(
		asm volatile(
			"	.insn	rrf,0xb98e0000,%[r1],%[r2],0,%[m4]"
			"	.insn	rrf,0xb98e0000,%[r1],%[r2],0,%[m4]"
			: "+m" (*pudp)
			: "+m" (*pudp)
		: [r1] "a" (r3o), [r2] "a" ((address & PUD_MASK)),
			: [r1] "a" (r3o), [r2] "a" ((addr & PUD_MASK)),
			  [m4] "i" (local)
			  [m4] "i" (local)
			: "cc");
			: "cc");
	} else {
		/* flush with guest asce */
		asm volatile(
			"	.insn	rrf,0xb98e0000,%[r1],%[r2],%[r3],%[m4]"
			: "+m" (*pudp)
			: [r1] "a" (r3o), [r2] "a" ((addr & PUD_MASK) | opt),
			  [r3] "a" (asce), [m4] "i" (local)
			: "cc" );
	}
}
}


pmd_t pmdp_xchg_direct(struct mm_struct *, unsigned long, pmd_t *, pmd_t);
pmd_t pmdp_xchg_direct(struct mm_struct *, unsigned long, pmd_t *, pmd_t);
Loading