Skip to content

Commit 85e67d5

Browse files
committed
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
2 parents 31d9497 + 5754f90 commit 85e67d5

File tree

7 files changed

+105
-56
lines changed

7 files changed

+105
-56
lines changed

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16807,6 +16807,7 @@ M: Heiko Carstens <[email protected]>
1680716807
M: Vasily Gorbik <[email protected]>
1680816808
M: Christian Borntraeger <[email protected]>
1680916809
R: Alexander Gordeev <[email protected]>
16810+
R: Sven Schnelle <[email protected]>
1681016811
1681116812
S: Supported
1681216813
W: http://www.ibm.com/developerworks/linux/linux390/

arch/s390/include/asm/cpu_mf.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,9 @@ struct hws_basic_entry {
109109
unsigned int AS:2; /* 29-30 PSW address-space control */
110110
unsigned int I:1; /* 31 entry valid or invalid */
111111
unsigned int CL:2; /* 32-33 Configuration Level */
112-
unsigned int:14;
112+
unsigned int H:1; /* 34 Host Indicator */
113+
unsigned int LS:1; /* 35 Limited Sampling */
114+
unsigned int:12;
113115
unsigned int prim_asn:16; /* primary ASN */
114116
unsigned long long ia; /* Instruction Address */
115117
unsigned long long gpp; /* Guest Program Parameter */

arch/s390/include/asm/uaccess.h

Lines changed: 77 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -49,51 +49,85 @@ int __get_user_bad(void) __attribute__((noreturn));
4949

5050
#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES
5151

52-
#define __put_get_user_asm(to, from, size, insn) \
53-
({ \
54-
int __rc; \
55-
\
56-
asm volatile( \
57-
insn " 0,%[spec]\n" \
58-
"0: mvcos %[_to],%[_from],%[_size]\n" \
59-
"1: xr %[rc],%[rc]\n" \
60-
"2:\n" \
61-
".pushsection .fixup, \"ax\"\n" \
62-
"3: lhi %[rc],%[retval]\n" \
63-
" jg 2b\n" \
64-
".popsection\n" \
65-
EX_TABLE(0b,3b) EX_TABLE(1b,3b) \
66-
: [rc] "=&d" (__rc), [_to] "+Q" (*(to)) \
67-
: [_size] "d" (size), [_from] "Q" (*(from)), \
68-
[retval] "K" (-EFAULT), [spec] "K" (0x81UL) \
69-
: "cc", "0"); \
70-
__rc; \
52+
union oac {
53+
unsigned int val;
54+
struct {
55+
struct {
56+
unsigned short key : 4;
57+
unsigned short : 4;
58+
unsigned short as : 2;
59+
unsigned short : 4;
60+
unsigned short k : 1;
61+
unsigned short a : 1;
62+
} oac1;
63+
struct {
64+
unsigned short key : 4;
65+
unsigned short : 4;
66+
unsigned short as : 2;
67+
unsigned short : 4;
68+
unsigned short k : 1;
69+
unsigned short a : 1;
70+
} oac2;
71+
};
72+
};
73+
74+
#define __put_get_user_asm(to, from, size, oac_spec) \
75+
({ \
76+
int __rc; \
77+
\
78+
asm volatile( \
79+
" lr 0,%[spec]\n" \
80+
"0: mvcos %[_to],%[_from],%[_size]\n" \
81+
"1: xr %[rc],%[rc]\n" \
82+
"2:\n" \
83+
".pushsection .fixup, \"ax\"\n" \
84+
"3: lhi %[rc],%[retval]\n" \
85+
" jg 2b\n" \
86+
".popsection\n" \
87+
EX_TABLE(0b,3b) EX_TABLE(1b,3b) \
88+
: [rc] "=&d" (__rc), [_to] "+Q" (*(to)) \
89+
: [_size] "d" (size), [_from] "Q" (*(from)), \
90+
[retval] "K" (-EFAULT), [spec] "d" (oac_spec.val) \
91+
: "cc", "0"); \
92+
__rc; \
7193
})
7294

95+
#define __put_user_asm(to, from, size) \
96+
__put_get_user_asm(to, from, size, ((union oac) { \
97+
.oac1.as = PSW_BITS_AS_SECONDARY, \
98+
.oac1.a = 1 \
99+
}))
100+
101+
#define __get_user_asm(to, from, size) \
102+
__put_get_user_asm(to, from, size, ((union oac) { \
103+
.oac2.as = PSW_BITS_AS_SECONDARY, \
104+
.oac2.a = 1 \
105+
})) \
106+
73107
static __always_inline int __put_user_fn(void *x, void __user *ptr, unsigned long size)
74108
{
75109
int rc;
76110

77111
switch (size) {
78112
case 1:
79-
rc = __put_get_user_asm((unsigned char __user *)ptr,
80-
(unsigned char *)x,
81-
size, "llilh");
113+
rc = __put_user_asm((unsigned char __user *)ptr,
114+
(unsigned char *)x,
115+
size);
82116
break;
83117
case 2:
84-
rc = __put_get_user_asm((unsigned short __user *)ptr,
85-
(unsigned short *)x,
86-
size, "llilh");
118+
rc = __put_user_asm((unsigned short __user *)ptr,
119+
(unsigned short *)x,
120+
size);
87121
break;
88122
case 4:
89-
rc = __put_get_user_asm((unsigned int __user *)ptr,
90-
(unsigned int *)x,
91-
size, "llilh");
123+
rc = __put_user_asm((unsigned int __user *)ptr,
124+
(unsigned int *)x,
125+
size);
92126
break;
93127
case 8:
94-
rc = __put_get_user_asm((unsigned long __user *)ptr,
95-
(unsigned long *)x,
96-
size, "llilh");
128+
rc = __put_user_asm((unsigned long __user *)ptr,
129+
(unsigned long *)x,
130+
size);
97131
break;
98132
default:
99133
__put_user_bad();
@@ -108,24 +142,24 @@ static __always_inline int __get_user_fn(void *x, const void __user *ptr, unsign
108142

109143
switch (size) {
110144
case 1:
111-
rc = __put_get_user_asm((unsigned char *)x,
112-
(unsigned char __user *)ptr,
113-
size, "lghi");
145+
rc = __get_user_asm((unsigned char *)x,
146+
(unsigned char __user *)ptr,
147+
size);
114148
break;
115149
case 2:
116-
rc = __put_get_user_asm((unsigned short *)x,
117-
(unsigned short __user *)ptr,
118-
size, "lghi");
150+
rc = __get_user_asm((unsigned short *)x,
151+
(unsigned short __user *)ptr,
152+
size);
119153
break;
120154
case 4:
121-
rc = __put_get_user_asm((unsigned int *)x,
122-
(unsigned int __user *)ptr,
123-
size, "lghi");
155+
rc = __get_user_asm((unsigned int *)x,
156+
(unsigned int __user *)ptr,
157+
size);
124158
break;
125159
case 8:
126-
rc = __put_get_user_asm((unsigned long *)x,
127-
(unsigned long __user *)ptr,
128-
size, "lghi");
160+
rc = __get_user_asm((unsigned long *)x,
161+
(unsigned long __user *)ptr,
162+
size);
129163
break;
130164
default:
131165
__get_user_bad();

arch/s390/kernel/perf_cpum_cf_common.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ size_t cpum_cf_ctrset_size(enum cpumf_ctr_set ctrset,
178178
case CPUMF_CTR_SET_CRYPTO:
179179
if (info->csvn >= 1 && info->csvn <= 5)
180180
ctrset_size = 16;
181-
else if (info->csvn == 6)
181+
else if (info->csvn == 6 || info->csvn == 7)
182182
ctrset_size = 20;
183183
break;
184184
case CPUMF_CTR_SET_EXT:
@@ -188,7 +188,7 @@ size_t cpum_cf_ctrset_size(enum cpumf_ctr_set ctrset,
188188
ctrset_size = 48;
189189
else if (info->csvn >= 3 && info->csvn <= 5)
190190
ctrset_size = 128;
191-
else if (info->csvn == 6)
191+
else if (info->csvn == 6 || info->csvn == 7)
192192
ctrset_size = 160;
193193
break;
194194
case CPUMF_CTR_SET_MT_DIAG:

arch/s390/kernel/perf_cpum_cf_events.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ static struct attribute *cpumcf_svn_12345_pmu_event_attr[] __initdata = {
344344
NULL,
345345
};
346346

347-
static struct attribute *cpumcf_svn_6_pmu_event_attr[] __initdata = {
347+
static struct attribute *cpumcf_svn_67_pmu_event_attr[] __initdata = {
348348
CPUMF_EVENT_PTR(cf_svn_12345, PRNG_FUNCTIONS),
349349
CPUMF_EVENT_PTR(cf_svn_12345, PRNG_CYCLES),
350350
CPUMF_EVENT_PTR(cf_svn_12345, PRNG_BLOCKED_FUNCTIONS),
@@ -715,8 +715,8 @@ __init const struct attribute_group **cpumf_cf_event_group(void)
715715
case 1 ... 5:
716716
csvn = cpumcf_svn_12345_pmu_event_attr;
717717
break;
718-
case 6:
719-
csvn = cpumcf_svn_6_pmu_event_attr;
718+
case 6 ... 7:
719+
csvn = cpumcf_svn_67_pmu_event_attr;
720720
break;
721721
default:
722722
csvn = none;

arch/s390/kernel/perf_cpum_sf.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1179,7 +1179,7 @@ static void hw_collect_samples(struct perf_event *event, unsigned long *sdbt,
11791179
sample = (struct hws_basic_entry *) *sdbt;
11801180
while ((unsigned long *) sample < (unsigned long *) te) {
11811181
/* Check for an empty sample */
1182-
if (!sample->def)
1182+
if (!sample->def || sample->LS)
11831183
break;
11841184

11851185
/* Update perf event period */

arch/s390/lib/uaccess.c

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,14 @@ static inline unsigned long copy_from_user_mvcos(void *x, const void __user *ptr
6262
unsigned long size)
6363
{
6464
unsigned long tmp1, tmp2;
65+
union oac spec = {
66+
.oac2.as = PSW_BITS_AS_SECONDARY,
67+
.oac2.a = 1,
68+
};
6569

6670
tmp1 = -4096UL;
6771
asm volatile(
68-
" lghi 0,%[spec]\n"
72+
" lr 0,%[spec]\n"
6973
"0: .insn ss,0xc80000000000,0(%0,%2),0(%1),0\n"
7074
"6: jz 4f\n"
7175
"1: algr %0,%3\n"
@@ -84,7 +88,7 @@ static inline unsigned long copy_from_user_mvcos(void *x, const void __user *ptr
8488
"5:\n"
8589
EX_TABLE(0b,2b) EX_TABLE(3b,5b) EX_TABLE(6b,2b) EX_TABLE(7b,5b)
8690
: "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
87-
: [spec] "K" (0x81UL)
91+
: [spec] "d" (spec.val)
8892
: "cc", "memory", "0");
8993
return size;
9094
}
@@ -135,10 +139,14 @@ static inline unsigned long copy_to_user_mvcos(void __user *ptr, const void *x,
135139
unsigned long size)
136140
{
137141
unsigned long tmp1, tmp2;
142+
union oac spec = {
143+
.oac1.as = PSW_BITS_AS_SECONDARY,
144+
.oac1.a = 1,
145+
};
138146

139147
tmp1 = -4096UL;
140148
asm volatile(
141-
" llilh 0,%[spec]\n"
149+
" lr 0,%[spec]\n"
142150
"0: .insn ss,0xc80000000000,0(%0,%1),0(%2),0\n"
143151
"6: jz 4f\n"
144152
"1: algr %0,%3\n"
@@ -157,7 +165,7 @@ static inline unsigned long copy_to_user_mvcos(void __user *ptr, const void *x,
157165
"5:\n"
158166
EX_TABLE(0b,2b) EX_TABLE(3b,5b) EX_TABLE(6b,2b) EX_TABLE(7b,5b)
159167
: "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
160-
: [spec] "K" (0x81UL)
168+
: [spec] "d" (spec.val)
161169
: "cc", "memory", "0");
162170
return size;
163171
}
@@ -207,10 +215,14 @@ EXPORT_SYMBOL(raw_copy_to_user);
207215
static inline unsigned long clear_user_mvcos(void __user *to, unsigned long size)
208216
{
209217
unsigned long tmp1, tmp2;
218+
union oac spec = {
219+
.oac1.as = PSW_BITS_AS_SECONDARY,
220+
.oac1.a = 1,
221+
};
210222

211223
tmp1 = -4096UL;
212224
asm volatile(
213-
" llilh 0,%[spec]\n"
225+
" lr 0,%[spec]\n"
214226
"0: .insn ss,0xc80000000000,0(%0,%1),0(%4),0\n"
215227
" jz 4f\n"
216228
"1: algr %0,%2\n"
@@ -228,7 +240,7 @@ static inline unsigned long clear_user_mvcos(void __user *to, unsigned long size
228240
"5:\n"
229241
EX_TABLE(0b,2b) EX_TABLE(3b,5b)
230242
: "+a" (size), "+a" (to), "+a" (tmp1), "=a" (tmp2)
231-
: "a" (empty_zero_page), [spec] "K" (0x81UL)
243+
: "a" (empty_zero_page), [spec] "d" (spec.val)
232244
: "cc", "memory", "0");
233245
return size;
234246
}

0 commit comments

Comments
 (0)