Skip to content

Commit 2a8120d

Browse files
committed
Merge tag 's390-6.10-2' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull more s390 updates from Alexander Gordeev: - Switch read and write software bits for PUDs - Add missing hardware bits for PUDs and PMDs - Generate unwind information for C modules to fix GDB unwind error for vDSO functions - Create .build-id links for unstripped vDSO files to enable vDSO debugging with symbols - Use standard stack frame layout for vDSO generated stack frames to manually walk stack frames without DWARF information - Rework perf_callchain_user() and arch_stack_walk_user() functions to reduce code duplication - Skip first stack frame when walking user stack - Add basic checks to identify invalid instruction pointers when walking stack frames - Introduce and use struct stack_frame_vdso_wrapper within vDSO user wrapper code to automatically generate an asm-offset define. Also use STACK_FRAME_USER_OVERHEAD instead of STACK_FRAME_OVERHEAD to document that the code works with user space stack - Clear the backchain of the extra stack frame added by the vDSO user wrapper code. This allows the user stack walker to detect and skip the non-standard stack frame. Without this an incorrect instruction pointer would be added to stack traces. - Rewrite psw_idle() function in C to ease maintenance and further enhancements - Remove get_vtimer() function and use get_cpu_timer() instead - Mark psw variable in __load_psw_mask() as __unitialized to avoid superfluous clearing of PSW - Remove obsolete and superfluous comment about removed TIF_FPU flag - Replace memzero_explicit() and kfree() with kfree_sensitive() to fix warnings reported by Coccinelle - Wipe sensitive data and all copies of protected- or secure-keys from stack when an IOCTL fails - Both do_airq_interrupt() and do_io_interrupt() functions set CIF_NOHZ_DELAY flag. Move it in do_io_irq() to simplify the code - Provide iucv_alloc_device() and iucv_release_device() helpers, which can be used to deduplicate more or less identical IUCV device allocation and release code in four different drivers - Make use of iucv_alloc_device() and iucv_release_device() helpers to get rid of quite some code and also remove a cast to an incompatible function (clang W=1) - There is no user of iucv_root outside of the core IUCV code left. Therefore remove the EXPORT_SYMBOL - __apply_alternatives() contains a runtime check which verifies that the size of the to be patched code area is even. Convert this to a compile time check - Increase size of buffers for sending z/VM CP DIAGNOSE X'008' commands from 128 to 240 - Do not accept z/VM CP DIAGNOSE X'008' commands longer than maximally allowed - Use correct defines IPL_BP_NVME_LEN and IPL_BP0_NVME_LEN instead of IPL_BP_FCP_LEN and IPL_BP0_FCP_LEN ones to initialize NVMe reIPL block on 'scp_data' sysfs attribute update - Initialize the correct fields of the NVMe dump block, which were confused with FCP fields - Refactor macros for 'scp_data' (re-)IPL sysfs attribute to reduce code duplication - Introduce 'scp_data' sysfs attribute for dump IPL to allow tools such as dumpconf passing additional kernel command line parameters to a stand-alone dumper - Rework the CPACF query functions to use the correct RRE or RRF instruction formats and set instruction register fields correctly - Instead of calling BUG() at runtime force a link error during compile when a unsupported opcode is used with __cpacf_query() or __cpacf_check_opcode() functions - Fix a crash in ap_parse_bitmap_str() function on /sys/bus/ap/apmask or /sys/bus/ap/aqmask sysfs file update with a relative mask value - Fix "bindings complete" udev event which should be sent once all AP devices have been bound to device drivers and again when unbind/bind actions take place and all AP devices are bound again - Facility list alt_stfle_fac_list is nowhere used in the decompressor, therefore remove it there - Remove custom kprobes insn slot allocator in favour of the standard module_alloc() one, since kernel image and module areas are located within 4GB - Use kvcalloc() instead of kvmalloc_array() in zcrypt driver to avoid calling memset() with a large byte count and get rid of the sparse warning as result * tag 's390-6.10-2' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (39 commits) s390/zcrypt: Use kvcalloc() instead of kvmalloc_array() s390/kprobes: Remove custom insn slot allocator s390/boot: Remove alt_stfle_fac_list from decompressor s390/ap: Fix bind complete udev event sent after each AP bus scan s390/ap: Fix crash in AP internal function modify_bitmap() s390/cpacf: Make use of invalid opcode produce a link error s390/cpacf: Split and rework cpacf query functions s390/ipl: Introduce sysfs attribute 'scp_data' for dump ipl s390/ipl: Introduce macros for (re)ipl sysfs attribute 'scp_data' s390/ipl: Fix incorrect initialization of nvme dump block s390/ipl: Fix incorrect initialization of len fields in nvme reipl block s390/ipl: Do not accept z/VM CP diag X'008' cmds longer than max length s390/ipl: Fix size of vmcmd buffers for sending z/VM CP diag X'008' cmds s390/alternatives: Convert runtime sanity check into compile time check s390/iucv: Unexport iucv_root tty: hvc-iucv: Make use of iucv_alloc_device() s390/smsgiucv_app: Make use of iucv_alloc_device() s390/netiucv: Make use of iucv_alloc_device() s390/vmlogrdr: Make use of iucv_alloc_device() s390/iucv: Provide iucv_alloc_device() / iucv_release_device() ...
2 parents 334e563 + c124863 commit 2a8120d

40 files changed

+517
-555
lines changed

arch/s390/boot/startup.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ unsigned long __bootdata_preserved(MODULES_END);
3232
unsigned long __bootdata_preserved(max_mappable);
3333

3434
u64 __bootdata_preserved(stfle_fac_list[16]);
35-
u64 __bootdata_preserved(alt_stfle_fac_list[16]);
3635
struct oldmem_data __bootdata_preserved(oldmem_data);
3736

3837
struct machine_info machine;

arch/s390/include/asm/alternative-asm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
.long \alt_start - .
1616
.word \feature
1717
.byte \orig_end - \orig_start
18+
.org . - ( \orig_end - \orig_start ) & 1
1819
.org . - ( \orig_end - \orig_start ) + ( \alt_end - \alt_start )
1920
.org . - ( \alt_end - \alt_start ) + ( \orig_end - \orig_start )
2021
.endm

arch/s390/include/asm/alternative.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
5353
"\t.long " b_altinstr(num)"b - .\n" /* alt instruction */ \
5454
"\t.word " __stringify(facility) "\n" /* facility bit */ \
5555
"\t.byte " oldinstr_len "\n" /* instruction len */ \
56+
"\t.org . - (" oldinstr_len ") & 1\n" \
5657
"\t.org . - (" oldinstr_len ") + (" altinstr_len(num) ")\n" \
5758
"\t.org . - (" altinstr_len(num) ") + (" oldinstr_len ")\n"
5859

arch/s390/include/asm/cpacf.h

Lines changed: 89 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -166,28 +166,86 @@
166166

167167
typedef struct { unsigned char bytes[16]; } cpacf_mask_t;
168168

169-
/**
170-
* cpacf_query() - check if a specific CPACF function is available
171-
* @opcode: the opcode of the crypto instruction
172-
* @func: the function code to test for
173-
*
174-
* Executes the query function for the given crypto instruction @opcode
175-
* and checks if @func is available
176-
*
177-
* Returns 1 if @func is available for @opcode, 0 otherwise
169+
/*
170+
* Prototype for a not existing function to produce a link
171+
* error if __cpacf_query() or __cpacf_check_opcode() is used
172+
* with an invalid compile time const opcode.
178173
*/
179-
static __always_inline void __cpacf_query(unsigned int opcode, cpacf_mask_t *mask)
174+
void __cpacf_bad_opcode(void);
175+
176+
static __always_inline void __cpacf_query_rre(u32 opc, u8 r1, u8 r2,
177+
cpacf_mask_t *mask)
180178
{
181179
asm volatile(
182-
" lghi 0,0\n" /* query function */
183-
" lgr 1,%[mask]\n"
184-
" spm 0\n" /* pckmo doesn't change the cc */
185-
/* Parameter regs are ignored, but must be nonzero and unique */
186-
"0: .insn rrf,%[opc] << 16,2,4,6,0\n"
187-
" brc 1,0b\n" /* handle partial completion */
188-
: "=m" (*mask)
189-
: [mask] "d" ((unsigned long)mask), [opc] "i" (opcode)
190-
: "cc", "0", "1");
180+
" la %%r1,%[mask]\n"
181+
" xgr %%r0,%%r0\n"
182+
" .insn rre,%[opc] << 16,%[r1],%[r2]\n"
183+
: [mask] "=R" (*mask)
184+
: [opc] "i" (opc),
185+
[r1] "i" (r1), [r2] "i" (r2)
186+
: "cc", "r0", "r1");
187+
}
188+
189+
static __always_inline void __cpacf_query_rrf(u32 opc,
190+
u8 r1, u8 r2, u8 r3, u8 m4,
191+
cpacf_mask_t *mask)
192+
{
193+
asm volatile(
194+
" la %%r1,%[mask]\n"
195+
" xgr %%r0,%%r0\n"
196+
" .insn rrf,%[opc] << 16,%[r1],%[r2],%[r3],%[m4]\n"
197+
: [mask] "=R" (*mask)
198+
: [opc] "i" (opc), [r1] "i" (r1), [r2] "i" (r2),
199+
[r3] "i" (r3), [m4] "i" (m4)
200+
: "cc", "r0", "r1");
201+
}
202+
203+
static __always_inline void __cpacf_query(unsigned int opcode,
204+
cpacf_mask_t *mask)
205+
{
206+
switch (opcode) {
207+
case CPACF_KDSA:
208+
__cpacf_query_rre(CPACF_KDSA, 0, 2, mask);
209+
break;
210+
case CPACF_KIMD:
211+
__cpacf_query_rre(CPACF_KIMD, 0, 2, mask);
212+
break;
213+
case CPACF_KLMD:
214+
__cpacf_query_rre(CPACF_KLMD, 0, 2, mask);
215+
break;
216+
case CPACF_KM:
217+
__cpacf_query_rre(CPACF_KM, 2, 4, mask);
218+
break;
219+
case CPACF_KMA:
220+
__cpacf_query_rrf(CPACF_KMA, 2, 4, 6, 0, mask);
221+
break;
222+
case CPACF_KMAC:
223+
__cpacf_query_rre(CPACF_KMAC, 0, 2, mask);
224+
break;
225+
case CPACF_KMC:
226+
__cpacf_query_rre(CPACF_KMC, 2, 4, mask);
227+
break;
228+
case CPACF_KMCTR:
229+
__cpacf_query_rrf(CPACF_KMCTR, 2, 4, 6, 0, mask);
230+
break;
231+
case CPACF_KMF:
232+
__cpacf_query_rre(CPACF_KMF, 2, 4, mask);
233+
break;
234+
case CPACF_KMO:
235+
__cpacf_query_rre(CPACF_KMO, 2, 4, mask);
236+
break;
237+
case CPACF_PCC:
238+
__cpacf_query_rre(CPACF_PCC, 0, 0, mask);
239+
break;
240+
case CPACF_PCKMO:
241+
__cpacf_query_rre(CPACF_PCKMO, 0, 0, mask);
242+
break;
243+
case CPACF_PRNO:
244+
__cpacf_query_rre(CPACF_PRNO, 2, 4, mask);
245+
break;
246+
default:
247+
__cpacf_bad_opcode();
248+
}
191249
}
192250

193251
static __always_inline int __cpacf_check_opcode(unsigned int opcode)
@@ -211,10 +269,21 @@ static __always_inline int __cpacf_check_opcode(unsigned int opcode)
211269
case CPACF_KMA:
212270
return test_facility(146); /* check for MSA8 */
213271
default:
214-
BUG();
272+
__cpacf_bad_opcode();
273+
return 0;
215274
}
216275
}
217276

277+
/**
278+
* cpacf_query() - check if a specific CPACF function is available
279+
* @opcode: the opcode of the crypto instruction
280+
* @func: the function code to test for
281+
*
282+
* Executes the query function for the given crypto instruction @opcode
283+
* and checks if @func is available
284+
*
285+
* Returns 1 if @func is available for @opcode, 0 otherwise
286+
*/
218287
static __always_inline int cpacf_query(unsigned int opcode, cpacf_mask_t *mask)
219288
{
220289
if (__cpacf_check_opcode(opcode)) {

arch/s390/include/asm/pgtable.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -268,12 +268,14 @@ static inline int is_module_addr(void *addr)
268268
#define _REGION3_ENTRY (_REGION_ENTRY_TYPE_R3 | _REGION_ENTRY_LENGTH)
269269
#define _REGION3_ENTRY_EMPTY (_REGION_ENTRY_TYPE_R3 | _REGION_ENTRY_INVALID)
270270

271+
#define _REGION3_ENTRY_HARDWARE_BITS 0xfffffffffffff6ffUL
272+
#define _REGION3_ENTRY_HARDWARE_BITS_LARGE 0xffffffff8001073cUL
271273
#define _REGION3_ENTRY_ORIGIN_LARGE ~0x7fffffffUL /* large page address */
272274
#define _REGION3_ENTRY_DIRTY 0x2000 /* SW region dirty bit */
273275
#define _REGION3_ENTRY_YOUNG 0x1000 /* SW region young bit */
274276
#define _REGION3_ENTRY_LARGE 0x0400 /* RTTE-format control, large page */
275-
#define _REGION3_ENTRY_READ 0x0002 /* SW region read bit */
276-
#define _REGION3_ENTRY_WRITE 0x0001 /* SW region write bit */
277+
#define _REGION3_ENTRY_WRITE 0x0002 /* SW region write bit */
278+
#define _REGION3_ENTRY_READ 0x0001 /* SW region read bit */
277279

278280
#ifdef CONFIG_MEM_SOFT_DIRTY
279281
#define _REGION3_ENTRY_SOFT_DIRTY 0x4000 /* SW region soft dirty bit */
@@ -284,9 +286,9 @@ static inline int is_module_addr(void *addr)
284286
#define _REGION_ENTRY_BITS 0xfffffffffffff22fUL
285287

286288
/* Bits in the segment table entry */
287-
#define _SEGMENT_ENTRY_BITS 0xfffffffffffffe33UL
288-
#define _SEGMENT_ENTRY_HARDWARE_BITS 0xfffffffffffffe30UL
289-
#define _SEGMENT_ENTRY_HARDWARE_BITS_LARGE 0xfffffffffff00730UL
289+
#define _SEGMENT_ENTRY_BITS 0xfffffffffffffe3fUL
290+
#define _SEGMENT_ENTRY_HARDWARE_BITS 0xfffffffffffffe3cUL
291+
#define _SEGMENT_ENTRY_HARDWARE_BITS_LARGE 0xfffffffffff1073cUL
290292
#define _SEGMENT_ENTRY_ORIGIN_LARGE ~0xfffffUL /* large page address */
291293
#define _SEGMENT_ENTRY_ORIGIN ~0x7ffUL/* page table origin */
292294
#define _SEGMENT_ENTRY_PROTECT 0x200 /* segment protection bit */

arch/s390/include/asm/processor.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include <asm/setup.h>
4141
#include <asm/runtime_instr.h>
4242
#include <asm/irqflags.h>
43+
#include <asm/alternative.h>
4344

4445
typedef long (*sys_call_ptr_t)(struct pt_regs *regs);
4546

@@ -92,12 +93,21 @@ static inline void get_cpu_id(struct cpuid *ptr)
9293
asm volatile("stidp %0" : "=Q" (*ptr));
9394
}
9495

96+
static __always_inline unsigned long get_cpu_timer(void)
97+
{
98+
unsigned long timer;
99+
100+
asm volatile("stpt %[timer]" : [timer] "=Q" (timer));
101+
return timer;
102+
}
103+
95104
void s390_adjust_jiffies(void);
96105
void s390_update_cpu_mhz(void);
97106
void cpu_detect_mhz_feature(void);
98107

99108
extern const struct seq_operations cpuinfo_op;
100109
extern void execve_tail(void);
110+
unsigned long vdso_text_size(void);
101111
unsigned long vdso_size(void);
102112

103113
/*
@@ -304,8 +314,8 @@ static inline void __load_psw(psw_t psw)
304314
*/
305315
static __always_inline void __load_psw_mask(unsigned long mask)
306316
{
317+
psw_t psw __uninitialized;
307318
unsigned long addr;
308-
psw_t psw;
309319

310320
psw.mask = mask;
311321

@@ -393,6 +403,11 @@ static __always_inline bool regs_irqs_disabled(struct pt_regs *regs)
393403
return arch_irqs_disabled_flags(regs->psw.mask);
394404
}
395405

406+
static __always_inline void bpon(void)
407+
{
408+
asm volatile(ALTERNATIVE("nop", ".insn rrf,0xb2e80000,0,0,13,0", 82));
409+
}
410+
396411
#endif /* __ASSEMBLY__ */
397412

398413
#endif /* __ASM_S390_PROCESSOR_H */

arch/s390/include/asm/stacktrace.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#ifndef _ASM_S390_STACKTRACE_H
33
#define _ASM_S390_STACKTRACE_H
44

5+
#include <linux/stacktrace.h>
56
#include <linux/uaccess.h>
67
#include <linux/ptrace.h>
78

@@ -12,6 +13,17 @@ struct stack_frame_user {
1213
unsigned long empty2[4];
1314
};
1415

16+
struct stack_frame_vdso_wrapper {
17+
struct stack_frame_user sf;
18+
unsigned long return_address;
19+
};
20+
21+
struct perf_callchain_entry_ctx;
22+
23+
void arch_stack_walk_user_common(stack_trace_consume_fn consume_entry, void *cookie,
24+
struct perf_callchain_entry_ctx *entry,
25+
const struct pt_regs *regs, bool perf);
26+
1527
enum stack_type {
1628
STACK_TYPE_UNKNOWN,
1729
STACK_TYPE_TASK,

arch/s390/kernel/Makefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ obj-$(CONFIG_COMPAT) += compat_linux.o compat_signal.o
5959
obj-$(CONFIG_COMPAT) += $(compat-obj-y)
6060
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
6161
obj-$(CONFIG_KPROBES) += kprobes.o
62-
obj-$(CONFIG_KPROBES) += kprobes_insn_page.o
6362
obj-$(CONFIG_KPROBES) += mcount.o
6463
obj-$(CONFIG_RETHOOK) += rethook.o
6564
obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o

arch/s390/kernel/alternative.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,6 @@ static void __init_or_module __apply_alternatives(struct alt_instr *start,
3333

3434
if (!__test_facility(a->facility, alt_stfle_fac_list))
3535
continue;
36-
37-
if (unlikely(a->instrlen % 2)) {
38-
WARN_ONCE(1, "cpu alternatives instructions length is "
39-
"odd, skipping patching\n");
40-
continue;
41-
}
42-
4336
s390_kernel_write(instr, replacement, a->instrlen);
4437
}
4538
}

arch/s390/kernel/asm-offsets.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
#include <linux/purgatory.h>
1414
#include <linux/pgtable.h>
1515
#include <linux/ftrace.h>
16-
#include <asm/idle.h>
1716
#include <asm/gmap.h>
1817
#include <asm/stacktrace.h>
1918

@@ -66,10 +65,10 @@ int main(void)
6665
OFFSET(__SF_SIE_CONTROL_PHYS, stack_frame, sie_control_block_phys);
6766
DEFINE(STACK_FRAME_OVERHEAD, sizeof(struct stack_frame));
6867
BLANK();
69-
/* idle data offsets */
70-
OFFSET(__CLOCK_IDLE_ENTER, s390_idle_data, clock_idle_enter);
71-
OFFSET(__TIMER_IDLE_ENTER, s390_idle_data, timer_idle_enter);
72-
OFFSET(__MT_CYCLES_ENTER, s390_idle_data, mt_cycles_enter);
68+
OFFSET(__SFUSER_BACKCHAIN, stack_frame_user, back_chain);
69+
DEFINE(STACK_FRAME_USER_OVERHEAD, sizeof(struct stack_frame_user));
70+
OFFSET(__SFVDSO_RETURN_ADDRESS, stack_frame_vdso_wrapper, return_address);
71+
DEFINE(STACK_FRAME_VDSO_OVERHEAD, sizeof(struct stack_frame_vdso_wrapper));
7372
BLANK();
7473
/* hardware defined lowcore locations 0x000 - 0x1ff */
7574
OFFSET(__LC_EXT_PARAMS, lowcore, ext_params);

0 commit comments

Comments
 (0)