more s390 updates for 5.17 merge window
- 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 -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEECMNfWEw3SLnmiLkZIg7DeRspbsIFAmHprPAACgkQIg7DeRsp bsLqkQ//ZWeZpN8YUS1VRoV0yPl2FX1LC19DXu5kat5UeUgeCSAG4COVv1XejD33 RP6zLFVBTVncdA4qrAsMJZnPpT/RSUS6fk0t0zETj6n0orjJYqekRnGuhQSATlzK yceIamg9tyqZgTCeBlCLF0ThFB5tsHVDQnrqRLECsY/Q24/2q04/97BFIak7iVAv D+0xivhf6rLufbw1SfxO7xXvtUBtdZcJUC1y9OhRp5Io1tGNkaKUziYwsnBicePg 6RGFtYv95QqQ1XqC47sFyntp7FK3RFK0DnQx7cWcAknAEOqNN/IUT/GnJlywSNK+ 4ZtCG7kIIBmCXZbPiF5uhrf5vrRCv9zCoxHmZvubpeNF06SKLVl5Nx9Wbqe4eC0w 5+CmSX+oO4JNJ4GN6hHURtgf0veYCZPDTtQ4pOuIGYxRtOmeFYlNcrCC3imgbZfx JRRFgaaX7mbUkq95acgbWowLMbWJR/TWC/caA9hh7awOzSlkhmAmnHg2s5kTnDjE n6+WTH9a9qn7k6mMFaA7Vfot/GYHValgl5FGQO5LXN+Y2/xMi3zS6hhYGi+JXMyR NlsQO9CRehUU4ApkyHDqH2q7G04Ko63DJ2DUZAHixrCM+c76EGzEN90bTGtVDwvk X72WpRpMvoD5Aqu2RVq0GyrlHH7MTFmURyz9Sqy8T5CtwAa/6As= =IQZX -----END PGP SIGNATURE----- Merge tag 's390-5.17-2' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux 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
This commit is contained in:
commit
85e67d56eb
|
@ -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/
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -49,51 +49,85 @@ int __get_user_bad(void) __attribute__((noreturn));
|
|||
|
||||
#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES
|
||||
|
||||
#define __put_get_user_asm(to, from, size, insn) \
|
||||
({ \
|
||||
int __rc; \
|
||||
\
|
||||
asm volatile( \
|
||||
insn " 0,%[spec]\n" \
|
||||
"0: mvcos %[_to],%[_from],%[_size]\n" \
|
||||
"1: xr %[rc],%[rc]\n" \
|
||||
"2:\n" \
|
||||
".pushsection .fixup, \"ax\"\n" \
|
||||
"3: lhi %[rc],%[retval]\n" \
|
||||
" jg 2b\n" \
|
||||
".popsection\n" \
|
||||
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) \
|
||||
: "cc", "0"); \
|
||||
__rc; \
|
||||
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( \
|
||||
" lr 0,%[spec]\n" \
|
||||
"0: mvcos %[_to],%[_from],%[_size]\n" \
|
||||
"1: xr %[rc],%[rc]\n" \
|
||||
"2:\n" \
|
||||
".pushsection .fixup, \"ax\"\n" \
|
||||
"3: lhi %[rc],%[retval]\n" \
|
||||
" jg 2b\n" \
|
||||
".popsection\n" \
|
||||
EX_TABLE(0b,3b) EX_TABLE(1b,3b) \
|
||||
: [rc] "=&d" (__rc), [_to] "+Q" (*(to)) \
|
||||
: [_size] "d" (size), [_from] "Q" (*(from)), \
|
||||
[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,
|
||||
(unsigned char *)x,
|
||||
size, "llilh");
|
||||
rc = __put_user_asm((unsigned char __user *)ptr,
|
||||
(unsigned char *)x,
|
||||
size);
|
||||
break;
|
||||
case 2:
|
||||
rc = __put_get_user_asm((unsigned short __user *)ptr,
|
||||
(unsigned short *)x,
|
||||
size, "llilh");
|
||||
rc = __put_user_asm((unsigned short __user *)ptr,
|
||||
(unsigned short *)x,
|
||||
size);
|
||||
break;
|
||||
case 4:
|
||||
rc = __put_get_user_asm((unsigned int __user *)ptr,
|
||||
(unsigned int *)x,
|
||||
size, "llilh");
|
||||
rc = __put_user_asm((unsigned int __user *)ptr,
|
||||
(unsigned int *)x,
|
||||
size);
|
||||
break;
|
||||
case 8:
|
||||
rc = __put_get_user_asm((unsigned long __user *)ptr,
|
||||
(unsigned long *)x,
|
||||
size, "llilh");
|
||||
rc = __put_user_asm((unsigned long __user *)ptr,
|
||||
(unsigned long *)x,
|
||||
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,
|
||||
(unsigned char __user *)ptr,
|
||||
size, "lghi");
|
||||
rc = __get_user_asm((unsigned char *)x,
|
||||
(unsigned char __user *)ptr,
|
||||
size);
|
||||
break;
|
||||
case 2:
|
||||
rc = __put_get_user_asm((unsigned short *)x,
|
||||
(unsigned short __user *)ptr,
|
||||
size, "lghi");
|
||||
rc = __get_user_asm((unsigned short *)x,
|
||||
(unsigned short __user *)ptr,
|
||||
size);
|
||||
break;
|
||||
case 4:
|
||||
rc = __put_get_user_asm((unsigned int *)x,
|
||||
(unsigned int __user *)ptr,
|
||||
size, "lghi");
|
||||
rc = __get_user_asm((unsigned int *)x,
|
||||
(unsigned int __user *)ptr,
|
||||
size);
|
||||
break;
|
||||
case 8:
|
||||
rc = __put_get_user_asm((unsigned long *)x,
|
||||
(unsigned long __user *)ptr,
|
||||
size, "lghi");
|
||||
rc = __get_user_asm((unsigned long *)x,
|
||||
(unsigned long __user *)ptr,
|
||||
size);
|
||||
break;
|
||||
default:
|
||||
__get_user_bad();
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -1179,7 +1179,7 @@ static void hw_collect_samples(struct perf_event *event, unsigned long *sdbt,
|
|||
sample = (struct hws_basic_entry *) *sdbt;
|
||||
while ((unsigned long *) sample < (unsigned long *) te) {
|
||||
/* Check for an empty sample */
|
||||
if (!sample->def)
|
||||
if (!sample->def || sample->LS)
|
||||
break;
|
||||
|
||||
/* Update perf event period */
|
||||
|
|
|
@ -62,10 +62,14 @@ static inline unsigned long copy_from_user_mvcos(void *x, const void __user *ptr
|
|||
unsigned long size)
|
||||
{
|
||||
unsigned long tmp1, tmp2;
|
||||
union oac spec = {
|
||||
.oac2.as = PSW_BITS_AS_SECONDARY,
|
||||
.oac2.a = 1,
|
||||
};
|
||||
|
||||
tmp1 = -4096UL;
|
||||
asm volatile(
|
||||
" lghi 0,%[spec]\n"
|
||||
" lr 0,%[spec]\n"
|
||||
"0: .insn ss,0xc80000000000,0(%0,%2),0(%1),0\n"
|
||||
"6: jz 4f\n"
|
||||
"1: algr %0,%3\n"
|
||||
|
@ -84,7 +88,7 @@ static inline unsigned long copy_from_user_mvcos(void *x, const void __user *ptr
|
|||
"5:\n"
|
||||
EX_TABLE(0b,2b) EX_TABLE(3b,5b) EX_TABLE(6b,2b) EX_TABLE(7b,5b)
|
||||
: "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
|
||||
: [spec] "K" (0x81UL)
|
||||
: [spec] "d" (spec.val)
|
||||
: "cc", "memory", "0");
|
||||
return size;
|
||||
}
|
||||
|
@ -135,10 +139,14 @@ static inline unsigned long copy_to_user_mvcos(void __user *ptr, const void *x,
|
|||
unsigned long size)
|
||||
{
|
||||
unsigned long tmp1, tmp2;
|
||||
union oac spec = {
|
||||
.oac1.as = PSW_BITS_AS_SECONDARY,
|
||||
.oac1.a = 1,
|
||||
};
|
||||
|
||||
tmp1 = -4096UL;
|
||||
asm volatile(
|
||||
" llilh 0,%[spec]\n"
|
||||
" lr 0,%[spec]\n"
|
||||
"0: .insn ss,0xc80000000000,0(%0,%1),0(%2),0\n"
|
||||
"6: jz 4f\n"
|
||||
"1: algr %0,%3\n"
|
||||
|
@ -157,7 +165,7 @@ static inline unsigned long copy_to_user_mvcos(void __user *ptr, const void *x,
|
|||
"5:\n"
|
||||
EX_TABLE(0b,2b) EX_TABLE(3b,5b) EX_TABLE(6b,2b) EX_TABLE(7b,5b)
|
||||
: "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
|
||||
: [spec] "K" (0x81UL)
|
||||
: [spec] "d" (spec.val)
|
||||
: "cc", "memory", "0");
|
||||
return size;
|
||||
}
|
||||
|
@ -207,10 +215,14 @@ EXPORT_SYMBOL(raw_copy_to_user);
|
|||
static inline unsigned long clear_user_mvcos(void __user *to, unsigned long size)
|
||||
{
|
||||
unsigned long tmp1, tmp2;
|
||||
union oac spec = {
|
||||
.oac1.as = PSW_BITS_AS_SECONDARY,
|
||||
.oac1.a = 1,
|
||||
};
|
||||
|
||||
tmp1 = -4096UL;
|
||||
asm volatile(
|
||||
" llilh 0,%[spec]\n"
|
||||
" lr 0,%[spec]\n"
|
||||
"0: .insn ss,0xc80000000000,0(%0,%1),0(%4),0\n"
|
||||
" jz 4f\n"
|
||||
"1: algr %0,%2\n"
|
||||
|
@ -228,7 +240,7 @@ static inline unsigned long clear_user_mvcos(void __user *to, unsigned long size
|
|||
"5:\n"
|
||||
EX_TABLE(0b,2b) EX_TABLE(3b,5b)
|
||||
: "+a" (size), "+a" (to), "+a" (tmp1), "=a" (tmp2)
|
||||
: "a" (empty_zero_page), [spec] "K" (0x81UL)
|
||||
: "a" (empty_zero_page), [spec] "d" (spec.val)
|
||||
: "cc", "memory", "0");
|
||||
return size;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue