Skip to content

Commit 0bdf4a8

Browse files
committed
Merge tag 's390-6.3-2' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull more s390 updates from Heiko Carstens: - Add empty command line parameter handling stubs to kernel for all command line parameters which are handled in the decompressor. This avoids invalid "Unknown kernel command line parameters" messages from the kernel, and also avoids that these will be incorrectly passed to user space. This caused already confusion, therefore add the empty stubs - Add missing phys_to_virt() handling to machine check handler - Introduce and use a union to be used for zcrypt inline assemblies. This makes sure that only a register wide member of the union is passed as input and output parameter to inline assemblies, while usual C code uses other members of the union to access bit fields of it - Add and use a READ_ONCE_ALIGNED_128() macro, which can be used to atomically read a 128-bit value from memory. This replaces the (mis-)use of the 128-bit cmpxchg operation to do the same in cpum_sf code. Currently gcc does not generate the used lpq instruction if __READ_ONCE() is used for aligned 128-bit accesses, therefore use this s390 specific helper - Simplify machine check handler code if a task needs to be killed because of e.g. register corruption due to a machine malfunction - Perform CPU reset to clear pending interrupts and TLB entries on an already stopped target CPU before delegating work to it - Generate arch/s390/boot/vmlinux.map link map for the decompressor, when CONFIG_VMLINUX_MAP is enabled for debugging purposes - Fix segment type handling for dcssblk devices. It incorrectly always returned type "READ/WRITE" even for read-only segements, which can result in a kernel panic if somebody tries to write to a read-only device - Sort config S390 select list again - Fix two kprobe reenter bugs revealed by a recently added kprobe kunit test * tag 's390-6.3-2' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: s390/kprobes: fix current_kprobe never cleared after kprobes reenter s390/kprobes: fix irq mask clobbering on kprobe reenter from post_handler s390/Kconfig: sort config S390 select list again s390/extmem: return correct segment type in __segment_load() s390/decompressor: add link map saving s390/smp: perform cpu reset before delegating work to target cpu s390/mcck: cleanup user process termination path s390/cpum_sf: use READ_ONCE_ALIGNED_128() instead of 128-bit cmpxchg s390/rwonce: add READ_ONCE_ALIGNED_128() macro s390/ap,zcrypt,vfio: introduce and use ap_queue_status_reg union s390/nmi: fix virtual-physical address confusion s390/setup: do not complain about parameters handled in decompressor
2 parents bf1a1ba + cd57953 commit 0bdf4a8

File tree

14 files changed

+131
-102
lines changed

14 files changed

+131
-102
lines changed

arch/s390/Kconfig

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,8 @@ config S390
125125
select ARCH_WANTS_DYNAMIC_TASK_STRUCT
126126
select ARCH_WANTS_NO_INSTR
127127
select ARCH_WANT_DEFAULT_BPF_JIT
128-
select ARCH_WANT_IPC_PARSE_VERSION
129128
select ARCH_WANT_HUGETLB_PAGE_OPTIMIZE_VMEMMAP
129+
select ARCH_WANT_IPC_PARSE_VERSION
130130
select BUILDTIME_TABLE_SORT
131131
select CLONE_BACKWARDS2
132132
select DMA_OPS if PCI
@@ -187,7 +187,6 @@ config S390
187187
select HAVE_KPROBES
188188
select HAVE_KPROBES_ON_FTRACE
189189
select HAVE_KRETPROBES
190-
select HAVE_RETHOOK
191190
select HAVE_KVM
192191
select HAVE_LIVEPATCH
193192
select HAVE_MEMBLOCK_PHYS_MAP
@@ -200,6 +199,7 @@ config S390
200199
select HAVE_PERF_USER_STACK_DUMP
201200
select HAVE_REGS_AND_STACK_ACCESS_API
202201
select HAVE_RELIABLE_STACKTRACE
202+
select HAVE_RETHOOK
203203
select HAVE_RSEQ
204204
select HAVE_SAMPLE_FTRACE_DIRECT
205205
select HAVE_SAMPLE_FTRACE_DIRECT_MULTI
@@ -210,9 +210,9 @@ config S390
210210
select HAVE_VIRT_CPU_ACCOUNTING_IDLE
211211
select IOMMU_HELPER if PCI
212212
select IOMMU_SUPPORT if PCI
213+
select MMU_GATHER_MERGE_VMAS
213214
select MMU_GATHER_NO_GATHER
214215
select MMU_GATHER_RCU_TABLE_FREE
215-
select MMU_GATHER_MERGE_VMAS
216216
select MODULES_USE_ELF_RELA
217217
select NEED_DMA_MAP_STATE if PCI
218218
select NEED_PER_CPU_EMBED_FIRST_CHUNK

arch/s390/boot/Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ targets += vmlinux.bin.zst info.bin syms.bin vmlinux.syms $(obj-all)
5252
OBJECTS := $(addprefix $(obj)/,$(obj-y))
5353
OBJECTS_ALL := $(addprefix $(obj)/,$(obj-all))
5454

55+
clean-files += vmlinux.map
56+
5557
quiet_cmd_section_cmp = SECTCMP $*
5658
define cmd_section_cmp
5759
s1=`$(OBJDUMP) -t -j "$*" "$<" | sort | \
@@ -71,7 +73,7 @@ $(obj)/bzImage: $(obj)/vmlinux $(obj)/section_cmp.boot.data $(obj)/section_cmp.b
7173
$(obj)/section_cmp%: vmlinux $(obj)/vmlinux FORCE
7274
$(call if_changed,section_cmp)
7375

74-
LDFLAGS_vmlinux := --oformat $(LD_BFD) -e startup --build-id=sha1 -T
76+
LDFLAGS_vmlinux := --oformat $(LD_BFD) -e startup $(if $(CONFIG_VMLINUX_MAP),-Map=$(obj)/vmlinux.map) --build-id=sha1 -T
7577
$(obj)/vmlinux: $(obj)/vmlinux.lds $(OBJECTS_ALL) FORCE
7678
$(call if_changed,ld)
7779

arch/s390/include/asm/ap.h

Lines changed: 52 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,19 @@ struct ap_queue_status {
4949
unsigned int _pad2 : 16;
5050
};
5151

52+
/*
53+
* AP queue status reg union to access the reg1
54+
* register with the lower 32 bits comprising the
55+
* ap queue status.
56+
*/
57+
union ap_queue_status_reg {
58+
unsigned long value;
59+
struct {
60+
u32 _pad;
61+
struct ap_queue_status status;
62+
};
63+
};
64+
5265
/**
5366
* ap_intructions_available() - Test if AP instructions are available.
5467
*
@@ -82,7 +95,7 @@ static inline bool ap_instructions_available(void)
8295
*/
8396
static inline struct ap_queue_status ap_tapq(ap_qid_t qid, unsigned long *info)
8497
{
85-
struct ap_queue_status reg1;
98+
union ap_queue_status_reg reg1;
8699
unsigned long reg2;
87100

88101
asm volatile(
@@ -91,12 +104,12 @@ static inline struct ap_queue_status ap_tapq(ap_qid_t qid, unsigned long *info)
91104
" .insn rre,0xb2af0000,0,0\n" /* PQAP(TAPQ) */
92105
" lgr %[reg1],1\n" /* gr1 (status) into reg1 */
93106
" lgr %[reg2],2\n" /* gr2 into reg2 */
94-
: [reg1] "=&d" (reg1), [reg2] "=&d" (reg2)
107+
: [reg1] "=&d" (reg1.value), [reg2] "=&d" (reg2)
95108
: [qid] "d" (qid)
96109
: "cc", "0", "1", "2");
97110
if (info)
98111
*info = reg2;
99-
return reg1;
112+
return reg1.status;
100113
}
101114

102115
/**
@@ -125,16 +138,16 @@ static inline struct ap_queue_status ap_test_queue(ap_qid_t qid,
125138
static inline struct ap_queue_status ap_rapq(ap_qid_t qid)
126139
{
127140
unsigned long reg0 = qid | (1UL << 24); /* fc 1UL is RAPQ */
128-
struct ap_queue_status reg1;
141+
union ap_queue_status_reg reg1;
129142

130143
asm volatile(
131144
" lgr 0,%[reg0]\n" /* qid arg into gr0 */
132145
" .insn rre,0xb2af0000,0,0\n" /* PQAP(RAPQ) */
133146
" lgr %[reg1],1\n" /* gr1 (status) into reg1 */
134-
: [reg1] "=&d" (reg1)
147+
: [reg1] "=&d" (reg1.value)
135148
: [reg0] "d" (reg0)
136149
: "cc", "0", "1");
137-
return reg1;
150+
return reg1.status;
138151
}
139152

140153
/**
@@ -146,16 +159,16 @@ static inline struct ap_queue_status ap_rapq(ap_qid_t qid)
146159
static inline struct ap_queue_status ap_zapq(ap_qid_t qid)
147160
{
148161
unsigned long reg0 = qid | (2UL << 24); /* fc 2UL is ZAPQ */
149-
struct ap_queue_status reg1;
162+
union ap_queue_status_reg reg1;
150163

151164
asm volatile(
152165
" lgr 0,%[reg0]\n" /* qid arg into gr0 */
153166
" .insn rre,0xb2af0000,0,0\n" /* PQAP(ZAPQ) */
154167
" lgr %[reg1],1\n" /* gr1 (status) into reg1 */
155-
: [reg1] "=&d" (reg1)
168+
: [reg1] "=&d" (reg1.value)
156169
: [reg0] "d" (reg0)
157170
: "cc", "0", "1");
158-
return reg1;
171+
return reg1.status;
159172
}
160173

161174
/**
@@ -209,18 +222,21 @@ static inline int ap_qci(struct ap_config_info *config)
209222
* parameter to the PQAP(AQIC) instruction. For details please
210223
* see the AR documentation.
211224
*/
212-
struct ap_qirq_ctrl {
213-
unsigned int _res1 : 8;
214-
unsigned int zone : 8; /* zone info */
215-
unsigned int ir : 1; /* ir flag: enable (1) or disable (0) irq */
216-
unsigned int _res2 : 4;
217-
unsigned int gisc : 3; /* guest isc field */
218-
unsigned int _res3 : 6;
219-
unsigned int gf : 2; /* gisa format */
220-
unsigned int _res4 : 1;
221-
unsigned int gisa : 27; /* gisa origin */
222-
unsigned int _res5 : 1;
223-
unsigned int isc : 3; /* irq sub class */
225+
union ap_qirq_ctrl {
226+
unsigned long value;
227+
struct {
228+
unsigned int : 8;
229+
unsigned int zone : 8; /* zone info */
230+
unsigned int ir : 1; /* ir flag: enable (1) or disable (0) irq */
231+
unsigned int : 4;
232+
unsigned int gisc : 3; /* guest isc field */
233+
unsigned int : 6;
234+
unsigned int gf : 2; /* gisa format */
235+
unsigned int : 1;
236+
unsigned int gisa : 27; /* gisa origin */
237+
unsigned int : 1;
238+
unsigned int isc : 3; /* irq sub class */
239+
};
224240
};
225241

226242
/**
@@ -232,29 +248,22 @@ struct ap_qirq_ctrl {
232248
* Returns AP queue status.
233249
*/
234250
static inline struct ap_queue_status ap_aqic(ap_qid_t qid,
235-
struct ap_qirq_ctrl qirqctrl,
251+
union ap_qirq_ctrl qirqctrl,
236252
phys_addr_t pa_ind)
237253
{
238254
unsigned long reg0 = qid | (3UL << 24); /* fc 3UL is AQIC */
239-
union {
240-
unsigned long value;
241-
struct ap_qirq_ctrl qirqctrl;
242-
struct {
243-
u32 _pad;
244-
struct ap_queue_status status;
245-
};
246-
} reg1;
255+
union ap_queue_status_reg reg1;
247256
unsigned long reg2 = pa_ind;
248257

249-
reg1.qirqctrl = qirqctrl;
258+
reg1.value = qirqctrl.value;
250259

251260
asm volatile(
252261
" lgr 0,%[reg0]\n" /* qid param into gr0 */
253262
" lgr 1,%[reg1]\n" /* irq ctrl into gr1 */
254263
" lgr 2,%[reg2]\n" /* ni addr into gr2 */
255264
" .insn rre,0xb2af0000,0,0\n" /* PQAP(AQIC) */
256265
" lgr %[reg1],1\n" /* gr1 (status) into reg1 */
257-
: [reg1] "+&d" (reg1)
266+
: [reg1] "+&d" (reg1.value)
258267
: [reg0] "d" (reg0), [reg2] "d" (reg2)
259268
: "cc", "memory", "0", "1", "2");
260269

@@ -291,13 +300,7 @@ static inline struct ap_queue_status ap_qact(ap_qid_t qid, int ifbit,
291300
union ap_qact_ap_info *apinfo)
292301
{
293302
unsigned long reg0 = qid | (5UL << 24) | ((ifbit & 0x01) << 22);
294-
union {
295-
unsigned long value;
296-
struct {
297-
u32 _pad;
298-
struct ap_queue_status status;
299-
};
300-
} reg1;
303+
union ap_queue_status_reg reg1;
301304
unsigned long reg2;
302305

303306
reg1.value = apinfo->val;
@@ -308,7 +311,7 @@ static inline struct ap_queue_status ap_qact(ap_qid_t qid, int ifbit,
308311
" .insn rre,0xb2af0000,0,0\n" /* PQAP(QACT) */
309312
" lgr %[reg1],1\n" /* gr1 (status) into reg1 */
310313
" lgr %[reg2],2\n" /* qact out info into reg2 */
311-
: [reg1] "+&d" (reg1), [reg2] "=&d" (reg2)
314+
: [reg1] "+&d" (reg1.value), [reg2] "=&d" (reg2)
312315
: [reg0] "d" (reg0)
313316
: "cc", "0", "1", "2");
314317
apinfo->val = reg2;
@@ -333,7 +336,7 @@ static inline struct ap_queue_status ap_nqap(ap_qid_t qid,
333336
{
334337
unsigned long reg0 = qid | 0x40000000UL; /* 0x4... is last msg part */
335338
union register_pair nqap_r1, nqap_r2;
336-
struct ap_queue_status reg1;
339+
union ap_queue_status_reg reg1;
337340

338341
nqap_r1.even = (unsigned int)(psmid >> 32);
339342
nqap_r1.odd = psmid & 0xffffffff;
@@ -345,11 +348,11 @@ static inline struct ap_queue_status ap_nqap(ap_qid_t qid,
345348
"0: .insn rre,0xb2ad0000,%[nqap_r1],%[nqap_r2]\n"
346349
" brc 2,0b\n" /* handle partial completion */
347350
" lgr %[reg1],1\n" /* gr1 (status) into reg1 */
348-
: [reg0] "+&d" (reg0), [reg1] "=&d" (reg1),
351+
: [reg0] "+&d" (reg0), [reg1] "=&d" (reg1.value),
349352
[nqap_r2] "+&d" (nqap_r2.pair)
350353
: [nqap_r1] "d" (nqap_r1.pair)
351354
: "cc", "memory", "0", "1");
352-
return reg1;
355+
return reg1.status;
353356
}
354357

355358
/**
@@ -389,7 +392,7 @@ static inline struct ap_queue_status ap_dqap(ap_qid_t qid,
389392
unsigned long *resgr0)
390393
{
391394
unsigned long reg0 = resgr0 && *resgr0 ? *resgr0 : qid | 0x80000000UL;
392-
struct ap_queue_status reg1;
395+
union ap_queue_status_reg reg1;
393396
unsigned long reg2;
394397
union register_pair rp1, rp2;
395398

@@ -408,8 +411,9 @@ static inline struct ap_queue_status ap_dqap(ap_qid_t qid,
408411
"2: lgr %[reg0],0\n" /* gr0 (qid + info) into reg0 */
409412
" lgr %[reg1],1\n" /* gr1 (status) into reg1 */
410413
" lgr %[reg2],2\n" /* gr2 (res length) into reg2 */
411-
: [reg0] "+&d" (reg0), [reg1] "=&d" (reg1), [reg2] "=&d" (reg2),
412-
[rp1] "+&d" (rp1.pair), [rp2] "+&d" (rp2.pair)
414+
: [reg0] "+&d" (reg0), [reg1] "=&d" (reg1.value),
415+
[reg2] "=&d" (reg2), [rp1] "+&d" (rp1.pair),
416+
[rp2] "+&d" (rp2.pair)
413417
:
414418
: "cc", "memory", "0", "1", "2");
415419

@@ -421,7 +425,7 @@ static inline struct ap_queue_status ap_dqap(ap_qid_t qid,
421425
* Signal the caller that this dqap is only partially received
422426
* with a special status response code 0xFF and *resgr0 updated
423427
*/
424-
reg1.response_code = 0xFF;
428+
reg1.status.response_code = 0xFF;
425429
if (resgr0)
426430
*resgr0 = reg0;
427431
} else {
@@ -430,7 +434,7 @@ static inline struct ap_queue_status ap_dqap(ap_qid_t qid,
430434
*resgr0 = 0;
431435
}
432436

433-
return reg1;
437+
return reg1.status;
434438
}
435439

436440
/*

arch/s390/include/asm/nmi.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,8 @@ void nmi_alloc_mcesa_early(u64 *mcesad);
101101
int nmi_alloc_mcesa(u64 *mcesad);
102102
void nmi_free_mcesa(u64 *mcesad);
103103

104-
void s390_handle_mcck(struct pt_regs *regs);
105-
void __s390_handle_mcck(void);
106-
int s390_do_machine_check(struct pt_regs *regs);
104+
void s390_handle_mcck(void);
105+
void s390_do_machine_check(struct pt_regs *regs);
107106

108107
#endif /* __ASSEMBLY__ */
109108
#endif /* _ASM_S390_NMI_H */

arch/s390/include/asm/rwonce.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
3+
#ifndef __ASM_S390_RWONCE_H
4+
#define __ASM_S390_RWONCE_H
5+
6+
#include <linux/compiler_types.h>
7+
8+
/*
9+
* Use READ_ONCE_ALIGNED_128() for 128-bit block concurrent (atomic) read
10+
* accesses. Note that x must be 128-bit aligned, otherwise a specification
11+
* exception is generated.
12+
*/
13+
#define READ_ONCE_ALIGNED_128(x) \
14+
({ \
15+
union { \
16+
typeof(x) __x; \
17+
__uint128_t val; \
18+
} __u; \
19+
\
20+
BUILD_BUG_ON(sizeof(x) != 16); \
21+
asm volatile( \
22+
" lpq %[val],%[_x]\n" \
23+
: [val] "=d" (__u.val) \
24+
: [_x] "QS" (x) \
25+
: "memory"); \
26+
__u.__x; \
27+
})
28+
29+
#include <asm-generic/rwonce.h>
30+
31+
#endif /* __ASM_S390_RWONCE_H */

arch/s390/kernel/early.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,23 @@
3636

3737
int __bootdata(is_full_image);
3838

39+
#define decompressor_handled_param(param) \
40+
static int __init ignore_decompressor_param_##param(char *s) \
41+
{ \
42+
return 0; \
43+
} \
44+
early_param(#param, ignore_decompressor_param_##param)
45+
46+
decompressor_handled_param(mem);
47+
decompressor_handled_param(vmalloc);
48+
decompressor_handled_param(dfltcc);
49+
decompressor_handled_param(noexec);
50+
decompressor_handled_param(facilities);
51+
decompressor_handled_param(nokaslr);
52+
#if IS_ENABLED(CONFIG_KVM)
53+
decompressor_handled_param(prot_virt);
54+
#endif
55+
3956
static void __init reset_tod_clock(void)
4057
{
4158
union tod_clock clk;

arch/s390/kernel/entry.S

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -562,16 +562,6 @@ ENTRY(mcck_int_handler)
562562
xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
563563
lgr %r2,%r11 # pass pointer to pt_regs
564564
brasl %r14,s390_do_machine_check
565-
cghi %r2,0
566-
je .Lmcck_return
567-
lg %r1,__LC_KERNEL_STACK # switch to kernel stack
568-
mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
569-
xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
570-
la %r11,STACK_FRAME_OVERHEAD(%r1)
571-
lgr %r2,%r11
572-
lgr %r15,%r1
573-
brasl %r14,s390_handle_mcck
574-
.Lmcck_return:
575565
lctlg %c1,%c1,__PT_CR1(%r11)
576566
lmg %r0,%r10,__PT_R0(%r11)
577567
mvc __LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW

arch/s390/kernel/kprobes.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ static void pop_kprobe(struct kprobe_ctlblk *kcb)
278278
{
279279
__this_cpu_write(current_kprobe, kcb->prev_kprobe.kp);
280280
kcb->kprobe_status = kcb->prev_kprobe.status;
281+
kcb->prev_kprobe.kp = NULL;
281282
}
282283
NOKPROBE_SYMBOL(pop_kprobe);
283284

@@ -402,12 +403,11 @@ static int post_kprobe_handler(struct pt_regs *regs)
402403
if (!p)
403404
return 0;
404405

406+
resume_execution(p, regs);
405407
if (kcb->kprobe_status != KPROBE_REENTER && p->post_handler) {
406408
kcb->kprobe_status = KPROBE_HIT_SSDONE;
407409
p->post_handler(p, regs, 0);
408410
}
409-
410-
resume_execution(p, regs);
411411
pop_kprobe(kcb);
412412
preempt_enable_no_resched();
413413

0 commit comments

Comments
 (0)