Commit 85e67d56 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull more s390 updates from Heiko Carstens:

 - add Sven Schnelle as reviewer for s390 code

 - make uaccess code more readable

 - change cpu measurement facility code to also support counter second
   version number 7, and add discard support for limited samples

* tag 's390-5.17-2' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux:
  s390: add Sven Schnelle as reviewer
  s390/uaccess: introduce bit field for OAC specifier
  s390/cpumf: Support for CPU Measurement Sampling Facility LS bit
  s390/cpumf: Support for CPU Measurement Facility CSVN 7
parents 31d94978 5754f908
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -16807,6 +16807,7 @@ M: Heiko Carstens <hca@linux.ibm.com>
M:	Vasily Gorbik <gor@linux.ibm.com>
M:	Christian Borntraeger <borntraeger@linux.ibm.com>
R:	Alexander Gordeev <agordeev@linux.ibm.com>
R:	Sven Schnelle <svens@linux.ibm.com>
L:	linux-s390@vger.kernel.org
S:	Supported
W:	http://www.ibm.com/developerworks/linux/linux390/
+3 −1
Original line number Diff line number Diff line
@@ -109,7 +109,9 @@ struct hws_basic_entry {
	unsigned int AS:2;	    /* 29-30 PSW address-space control	 */
	unsigned int I:1;	    /* 31 entry valid or invalid	 */
	unsigned int CL:2;	    /* 32-33 Configuration Level	 */
	unsigned int:14;
	unsigned int H:1;	    /* 34 Host Indicator		 */
	unsigned int LS:1;	    /* 35 Limited Sampling		 */
	unsigned int:12;
	unsigned int prim_asn:16;   /* primary ASN			 */
	unsigned long long ia;	    /* Instruction Address		 */
	unsigned long long gpp;     /* Guest Program Parameter		 */
+77 −43
Original line number Diff line number Diff line
@@ -49,12 +49,34 @@ int __get_user_bad(void) __attribute__((noreturn));

#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES

#define __put_get_user_asm(to, from, size, insn)		\
union oac {
	unsigned int val;
	struct {
		struct {
			unsigned short key : 4;
			unsigned short	   : 4;
			unsigned short as  : 2;
			unsigned short	   : 4;
			unsigned short k   : 1;
			unsigned short a   : 1;
		} oac1;
		struct {
			unsigned short key : 4;
			unsigned short	   : 4;
			unsigned short as  : 2;
			unsigned short	   : 4;
			unsigned short k   : 1;
			unsigned short a   : 1;
		} oac2;
	};
};

#define __put_get_user_asm(to, from, size, oac_spec)			\
({									\
	int __rc;							\
									\
	asm volatile(							\
		insn "		0,%[spec]\n"			\
		"	lr	0,%[spec]\n"				\
		"0:	mvcos	%[_to],%[_from],%[_size]\n"		\
		"1:	xr	%[rc],%[rc]\n"				\
		"2:\n"							\
@@ -65,35 +87,47 @@ int __get_user_bad(void) __attribute__((noreturn));
		EX_TABLE(0b,3b) EX_TABLE(1b,3b)				\
		: [rc] "=&d" (__rc), [_to] "+Q" (*(to))			\
		: [_size] "d" (size), [_from] "Q" (*(from)),		\
		  [retval] "K" (-EFAULT), [spec] "K" (0x81UL)	\
		  [retval] "K" (-EFAULT), [spec] "d" (oac_spec.val)	\
		: "cc", "0");						\
	__rc;								\
})

#define __put_user_asm(to, from, size)				\
	__put_get_user_asm(to, from, size, ((union oac) {	\
		.oac1.as = PSW_BITS_AS_SECONDARY,		\
		.oac1.a = 1					\
	}))

#define __get_user_asm(to, from, size)				\
	__put_get_user_asm(to, from, size, ((union oac) {	\
		.oac2.as = PSW_BITS_AS_SECONDARY,		\
		.oac2.a = 1					\
	}))							\

static __always_inline int __put_user_fn(void *x, void __user *ptr, unsigned long size)
{
	int rc;

	switch (size) {
	case 1:
		rc = __put_get_user_asm((unsigned char __user *)ptr,
		rc = __put_user_asm((unsigned char __user *)ptr,
				    (unsigned char *)x,
					size, "llilh");
				    size);
		break;
	case 2:
		rc = __put_get_user_asm((unsigned short __user *)ptr,
		rc = __put_user_asm((unsigned short __user *)ptr,
				    (unsigned short *)x,
					size, "llilh");
				    size);
		break;
	case 4:
		rc = __put_get_user_asm((unsigned int __user *)ptr,
		rc = __put_user_asm((unsigned int __user *)ptr,
				    (unsigned int *)x,
					size, "llilh");
				    size);
		break;
	case 8:
		rc = __put_get_user_asm((unsigned long __user *)ptr,
		rc = __put_user_asm((unsigned long __user *)ptr,
				    (unsigned long *)x,
					size, "llilh");
				    size);
		break;
	default:
		__put_user_bad();
@@ -108,24 +142,24 @@ static __always_inline int __get_user_fn(void *x, const void __user *ptr, unsign

	switch (size) {
	case 1:
		rc = __put_get_user_asm((unsigned char *)x,
		rc = __get_user_asm((unsigned char *)x,
				    (unsigned char __user *)ptr,
					size, "lghi");
				    size);
		break;
	case 2:
		rc = __put_get_user_asm((unsigned short *)x,
		rc = __get_user_asm((unsigned short *)x,
				    (unsigned short __user *)ptr,
					size, "lghi");
				    size);
		break;
	case 4:
		rc = __put_get_user_asm((unsigned int *)x,
		rc = __get_user_asm((unsigned int *)x,
				    (unsigned int __user *)ptr,
					size, "lghi");
				    size);
		break;
	case 8:
		rc = __put_get_user_asm((unsigned long *)x,
		rc = __get_user_asm((unsigned long *)x,
				    (unsigned long __user *)ptr,
					size, "lghi");
				    size);
		break;
	default:
		__get_user_bad();
+2 −2
Original line number Diff line number Diff line
@@ -178,7 +178,7 @@ size_t cpum_cf_ctrset_size(enum cpumf_ctr_set ctrset,
	case CPUMF_CTR_SET_CRYPTO:
		if (info->csvn >= 1 && info->csvn <= 5)
			ctrset_size = 16;
		else if (info->csvn == 6)
		else if (info->csvn == 6 || info->csvn == 7)
			ctrset_size = 20;
		break;
	case CPUMF_CTR_SET_EXT:
@@ -188,7 +188,7 @@ size_t cpum_cf_ctrset_size(enum cpumf_ctr_set ctrset,
			ctrset_size = 48;
		else if (info->csvn >= 3 && info->csvn <= 5)
			ctrset_size = 128;
		else if (info->csvn == 6)
		else if (info->csvn == 6 || info->csvn == 7)
			ctrset_size = 160;
		break;
	case CPUMF_CTR_SET_MT_DIAG:
+3 −3
Original line number Diff line number Diff line
@@ -344,7 +344,7 @@ static struct attribute *cpumcf_svn_12345_pmu_event_attr[] __initdata = {
	NULL,
};

static struct attribute *cpumcf_svn_6_pmu_event_attr[] __initdata = {
static struct attribute *cpumcf_svn_67_pmu_event_attr[] __initdata = {
	CPUMF_EVENT_PTR(cf_svn_12345, PRNG_FUNCTIONS),
	CPUMF_EVENT_PTR(cf_svn_12345, PRNG_CYCLES),
	CPUMF_EVENT_PTR(cf_svn_12345, PRNG_BLOCKED_FUNCTIONS),
@@ -715,8 +715,8 @@ __init const struct attribute_group **cpumf_cf_event_group(void)
	case 1 ... 5:
		csvn = cpumcf_svn_12345_pmu_event_attr;
		break;
	case 6:
		csvn = cpumcf_svn_6_pmu_event_attr;
	case 6 ... 7:
		csvn = cpumcf_svn_67_pmu_event_attr;
		break;
	default:
		csvn = none;
Loading