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: Vasily Gorbik <gor@linux.ibm.com>
|
||||||
M: Christian Borntraeger <borntraeger@linux.ibm.com>
|
M: Christian Borntraeger <borntraeger@linux.ibm.com>
|
||||||
R: Alexander Gordeev <agordeev@linux.ibm.com>
|
R: Alexander Gordeev <agordeev@linux.ibm.com>
|
||||||
|
R: Sven Schnelle <svens@linux.ibm.com>
|
||||||
L: linux-s390@vger.kernel.org
|
L: linux-s390@vger.kernel.org
|
||||||
S: Supported
|
S: Supported
|
||||||
W: http://www.ibm.com/developerworks/linux/linux390/
|
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 AS:2; /* 29-30 PSW address-space control */
|
||||||
unsigned int I:1; /* 31 entry valid or invalid */
|
unsigned int I:1; /* 31 entry valid or invalid */
|
||||||
unsigned int CL:2; /* 32-33 Configuration Level */
|
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 int prim_asn:16; /* primary ASN */
|
||||||
unsigned long long ia; /* Instruction Address */
|
unsigned long long ia; /* Instruction Address */
|
||||||
unsigned long long gpp; /* Guest Program Parameter */
|
unsigned long long gpp; /* Guest Program Parameter */
|
||||||
|
@ -49,12 +49,34 @@ int __get_user_bad(void) __attribute__((noreturn));
|
|||||||
|
|
||||||
#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES
|
#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; \
|
int __rc; \
|
||||||
\
|
\
|
||||||
asm volatile( \
|
asm volatile( \
|
||||||
insn " 0,%[spec]\n" \
|
" lr 0,%[spec]\n" \
|
||||||
"0: mvcos %[_to],%[_from],%[_size]\n" \
|
"0: mvcos %[_to],%[_from],%[_size]\n" \
|
||||||
"1: xr %[rc],%[rc]\n" \
|
"1: xr %[rc],%[rc]\n" \
|
||||||
"2:\n" \
|
"2:\n" \
|
||||||
@ -65,35 +87,47 @@ int __get_user_bad(void) __attribute__((noreturn));
|
|||||||
EX_TABLE(0b,3b) EX_TABLE(1b,3b) \
|
EX_TABLE(0b,3b) EX_TABLE(1b,3b) \
|
||||||
: [rc] "=&d" (__rc), [_to] "+Q" (*(to)) \
|
: [rc] "=&d" (__rc), [_to] "+Q" (*(to)) \
|
||||||
: [_size] "d" (size), [_from] "Q" (*(from)), \
|
: [_size] "d" (size), [_from] "Q" (*(from)), \
|
||||||
[retval] "K" (-EFAULT), [spec] "K" (0x81UL) \
|
[retval] "K" (-EFAULT), [spec] "d" (oac_spec.val) \
|
||||||
: "cc", "0"); \
|
: "cc", "0"); \
|
||||||
__rc; \
|
__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)
|
static __always_inline int __put_user_fn(void *x, void __user *ptr, unsigned long size)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
switch (size) {
|
switch (size) {
|
||||||
case 1:
|
case 1:
|
||||||
rc = __put_get_user_asm((unsigned char __user *)ptr,
|
rc = __put_user_asm((unsigned char __user *)ptr,
|
||||||
(unsigned char *)x,
|
(unsigned char *)x,
|
||||||
size, "llilh");
|
size);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
rc = __put_get_user_asm((unsigned short __user *)ptr,
|
rc = __put_user_asm((unsigned short __user *)ptr,
|
||||||
(unsigned short *)x,
|
(unsigned short *)x,
|
||||||
size, "llilh");
|
size);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
rc = __put_get_user_asm((unsigned int __user *)ptr,
|
rc = __put_user_asm((unsigned int __user *)ptr,
|
||||||
(unsigned int *)x,
|
(unsigned int *)x,
|
||||||
size, "llilh");
|
size);
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
rc = __put_get_user_asm((unsigned long __user *)ptr,
|
rc = __put_user_asm((unsigned long __user *)ptr,
|
||||||
(unsigned long *)x,
|
(unsigned long *)x,
|
||||||
size, "llilh");
|
size);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
__put_user_bad();
|
__put_user_bad();
|
||||||
@ -108,24 +142,24 @@ static __always_inline int __get_user_fn(void *x, const void __user *ptr, unsign
|
|||||||
|
|
||||||
switch (size) {
|
switch (size) {
|
||||||
case 1:
|
case 1:
|
||||||
rc = __put_get_user_asm((unsigned char *)x,
|
rc = __get_user_asm((unsigned char *)x,
|
||||||
(unsigned char __user *)ptr,
|
(unsigned char __user *)ptr,
|
||||||
size, "lghi");
|
size);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
rc = __put_get_user_asm((unsigned short *)x,
|
rc = __get_user_asm((unsigned short *)x,
|
||||||
(unsigned short __user *)ptr,
|
(unsigned short __user *)ptr,
|
||||||
size, "lghi");
|
size);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
rc = __put_get_user_asm((unsigned int *)x,
|
rc = __get_user_asm((unsigned int *)x,
|
||||||
(unsigned int __user *)ptr,
|
(unsigned int __user *)ptr,
|
||||||
size, "lghi");
|
size);
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
rc = __put_get_user_asm((unsigned long *)x,
|
rc = __get_user_asm((unsigned long *)x,
|
||||||
(unsigned long __user *)ptr,
|
(unsigned long __user *)ptr,
|
||||||
size, "lghi");
|
size);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
__get_user_bad();
|
__get_user_bad();
|
||||||
|
@ -178,7 +178,7 @@ size_t cpum_cf_ctrset_size(enum cpumf_ctr_set ctrset,
|
|||||||
case CPUMF_CTR_SET_CRYPTO:
|
case CPUMF_CTR_SET_CRYPTO:
|
||||||
if (info->csvn >= 1 && info->csvn <= 5)
|
if (info->csvn >= 1 && info->csvn <= 5)
|
||||||
ctrset_size = 16;
|
ctrset_size = 16;
|
||||||
else if (info->csvn == 6)
|
else if (info->csvn == 6 || info->csvn == 7)
|
||||||
ctrset_size = 20;
|
ctrset_size = 20;
|
||||||
break;
|
break;
|
||||||
case CPUMF_CTR_SET_EXT:
|
case CPUMF_CTR_SET_EXT:
|
||||||
@ -188,7 +188,7 @@ size_t cpum_cf_ctrset_size(enum cpumf_ctr_set ctrset,
|
|||||||
ctrset_size = 48;
|
ctrset_size = 48;
|
||||||
else if (info->csvn >= 3 && info->csvn <= 5)
|
else if (info->csvn >= 3 && info->csvn <= 5)
|
||||||
ctrset_size = 128;
|
ctrset_size = 128;
|
||||||
else if (info->csvn == 6)
|
else if (info->csvn == 6 || info->csvn == 7)
|
||||||
ctrset_size = 160;
|
ctrset_size = 160;
|
||||||
break;
|
break;
|
||||||
case CPUMF_CTR_SET_MT_DIAG:
|
case CPUMF_CTR_SET_MT_DIAG:
|
||||||
|
@ -344,7 +344,7 @@ static struct attribute *cpumcf_svn_12345_pmu_event_attr[] __initdata = {
|
|||||||
NULL,
|
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_FUNCTIONS),
|
||||||
CPUMF_EVENT_PTR(cf_svn_12345, PRNG_CYCLES),
|
CPUMF_EVENT_PTR(cf_svn_12345, PRNG_CYCLES),
|
||||||
CPUMF_EVENT_PTR(cf_svn_12345, PRNG_BLOCKED_FUNCTIONS),
|
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:
|
case 1 ... 5:
|
||||||
csvn = cpumcf_svn_12345_pmu_event_attr;
|
csvn = cpumcf_svn_12345_pmu_event_attr;
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6 ... 7:
|
||||||
csvn = cpumcf_svn_6_pmu_event_attr;
|
csvn = cpumcf_svn_67_pmu_event_attr;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
csvn = none;
|
csvn = none;
|
||||||
|
@ -1179,7 +1179,7 @@ static void hw_collect_samples(struct perf_event *event, unsigned long *sdbt,
|
|||||||
sample = (struct hws_basic_entry *) *sdbt;
|
sample = (struct hws_basic_entry *) *sdbt;
|
||||||
while ((unsigned long *) sample < (unsigned long *) te) {
|
while ((unsigned long *) sample < (unsigned long *) te) {
|
||||||
/* Check for an empty sample */
|
/* Check for an empty sample */
|
||||||
if (!sample->def)
|
if (!sample->def || sample->LS)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Update perf event period */
|
/* 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 size)
|
||||||
{
|
{
|
||||||
unsigned long tmp1, tmp2;
|
unsigned long tmp1, tmp2;
|
||||||
|
union oac spec = {
|
||||||
|
.oac2.as = PSW_BITS_AS_SECONDARY,
|
||||||
|
.oac2.a = 1,
|
||||||
|
};
|
||||||
|
|
||||||
tmp1 = -4096UL;
|
tmp1 = -4096UL;
|
||||||
asm volatile(
|
asm volatile(
|
||||||
" lghi 0,%[spec]\n"
|
" lr 0,%[spec]\n"
|
||||||
"0: .insn ss,0xc80000000000,0(%0,%2),0(%1),0\n"
|
"0: .insn ss,0xc80000000000,0(%0,%2),0(%1),0\n"
|
||||||
"6: jz 4f\n"
|
"6: jz 4f\n"
|
||||||
"1: algr %0,%3\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"
|
"5:\n"
|
||||||
EX_TABLE(0b,2b) EX_TABLE(3b,5b) EX_TABLE(6b,2b) EX_TABLE(7b,5b)
|
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)
|
: "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
|
||||||
: [spec] "K" (0x81UL)
|
: [spec] "d" (spec.val)
|
||||||
: "cc", "memory", "0");
|
: "cc", "memory", "0");
|
||||||
return size;
|
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 size)
|
||||||
{
|
{
|
||||||
unsigned long tmp1, tmp2;
|
unsigned long tmp1, tmp2;
|
||||||
|
union oac spec = {
|
||||||
|
.oac1.as = PSW_BITS_AS_SECONDARY,
|
||||||
|
.oac1.a = 1,
|
||||||
|
};
|
||||||
|
|
||||||
tmp1 = -4096UL;
|
tmp1 = -4096UL;
|
||||||
asm volatile(
|
asm volatile(
|
||||||
" llilh 0,%[spec]\n"
|
" lr 0,%[spec]\n"
|
||||||
"0: .insn ss,0xc80000000000,0(%0,%1),0(%2),0\n"
|
"0: .insn ss,0xc80000000000,0(%0,%1),0(%2),0\n"
|
||||||
"6: jz 4f\n"
|
"6: jz 4f\n"
|
||||||
"1: algr %0,%3\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"
|
"5:\n"
|
||||||
EX_TABLE(0b,2b) EX_TABLE(3b,5b) EX_TABLE(6b,2b) EX_TABLE(7b,5b)
|
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)
|
: "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
|
||||||
: [spec] "K" (0x81UL)
|
: [spec] "d" (spec.val)
|
||||||
: "cc", "memory", "0");
|
: "cc", "memory", "0");
|
||||||
return size;
|
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)
|
static inline unsigned long clear_user_mvcos(void __user *to, unsigned long size)
|
||||||
{
|
{
|
||||||
unsigned long tmp1, tmp2;
|
unsigned long tmp1, tmp2;
|
||||||
|
union oac spec = {
|
||||||
|
.oac1.as = PSW_BITS_AS_SECONDARY,
|
||||||
|
.oac1.a = 1,
|
||||||
|
};
|
||||||
|
|
||||||
tmp1 = -4096UL;
|
tmp1 = -4096UL;
|
||||||
asm volatile(
|
asm volatile(
|
||||||
" llilh 0,%[spec]\n"
|
" lr 0,%[spec]\n"
|
||||||
"0: .insn ss,0xc80000000000,0(%0,%1),0(%4),0\n"
|
"0: .insn ss,0xc80000000000,0(%0,%1),0(%4),0\n"
|
||||||
" jz 4f\n"
|
" jz 4f\n"
|
||||||
"1: algr %0,%2\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"
|
"5:\n"
|
||||||
EX_TABLE(0b,2b) EX_TABLE(3b,5b)
|
EX_TABLE(0b,2b) EX_TABLE(3b,5b)
|
||||||
: "+a" (size), "+a" (to), "+a" (tmp1), "=a" (tmp2)
|
: "+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");
|
: "cc", "memory", "0");
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user