Skip to content

Commit 4a0fc73

Browse files
committedSep 7, 2023
Merge tag 's390-6.6-2' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull more s390 updates from Heiko Carstens: - A couple of virtual vs physical address confusion fixes - Rework locking in dcssblk driver to address a lockdep warning - Remove support for "noexec" kernel command line option since there is no use case where it would make sense - Simplify kernel mapping setup and get rid of quite a bit of code - Add architecture specific __set_memory_yy() functions which allow us to modify kernel mappings. Unlike the set_memory_xx() variants they take void pointer start and end parameters, which allows using them without the usual casts, and also to use them on areas larger than 8TB. Note that the set_memory_xx() family comes with an int num_pages parameter which overflows with 8TB. This could be addressed by changing the num_pages parameter to unsigned long, however requires to change all architectures, since the module code expects an int parameter (see module_set_memory()). This was indeed an issue since for debug_pagealloc() we call set_memory_4k() on the whole identity mapping. Therefore address this for now with the __set_memory_yy() variant, and address common code later - Use dev_set_name() and also fix memory leak in zcrypt driver error handling - Remove unused lsi_mask from airq_struct - Add warning for invalid kernel mapping requests * tag 's390-6.6-2' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: s390/vmem: do not silently ignore mapping limit s390/zcrypt: utilize dev_set_name() ability to use a formatted string s390/zcrypt: don't leak memory if dev_set_name() fails s390/mm: fix MAX_DMA_ADDRESS physical vs virtual confusion s390/airq: remove lsi_mask from airq_struct s390/mm: use __set_memory() variants where useful s390/set_memory: add __set_memory() variant s390/set_memory: generate all set_memory() functions s390/mm: improve description of mapping permissions of prefix pages s390/amode31: change type of __samode31, __eamode31, etc s390/mm: simplify kernel mapping setup s390: remove "noexec" option s390/vmem: fix virtual vs physical address confusion s390/dcssblk: fix lockdep warning s390/monreader: fix virtual vs physical address confusion
2 parents ac2224a + 06fc3b0 commit 4a0fc73

21 files changed

+98
-223
lines changed
 

‎arch/s390/boot/ipl_parm.c

-7
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ struct parmarea parmarea __section(".parmarea") = {
1919
};
2020

2121
char __bootdata(early_command_line)[COMMAND_LINE_SIZE];
22-
int __bootdata(noexec_disabled);
2322

2423
unsigned int __bootdata_preserved(zlib_dfltcc_support) = ZLIB_DFLTCC_FULL;
2524
struct ipl_parameter_block __bootdata_preserved(ipl_block);
@@ -290,12 +289,6 @@ void parse_boot_command_line(void)
290289
zlib_dfltcc_support = ZLIB_DFLTCC_FULL_DEBUG;
291290
}
292291

293-
if (!strcmp(param, "noexec")) {
294-
rc = kstrtobool(val, &enabled);
295-
if (!rc && !enabled)
296-
noexec_disabled = 1;
297-
}
298-
299292
if (!strcmp(param, "facilities") && val)
300293
modify_fac_list(val);
301294

‎arch/s390/boot/startup.c

+1-3
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,8 @@ static void detect_facilities(void)
5353
}
5454
if (test_facility(78))
5555
machine.has_edat2 = 1;
56-
if (!noexec_disabled && test_facility(130)) {
56+
if (test_facility(130))
5757
machine.has_nx = 1;
58-
__ctl_set_bit(0, 20);
59-
}
6058
}
6159

6260
static void setup_lpp(void)

‎arch/s390/boot/vmem.c

+9-3
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,9 @@ static void pgtable_pte_populate(pmd_t *pmd, unsigned long addr, unsigned long e
287287
if (kasan_pte_populate_zero_shadow(pte, mode))
288288
continue;
289289
entry = __pte(_pa(addr, PAGE_SIZE, mode));
290-
entry = set_pte_bit(entry, PAGE_KERNEL_EXEC);
290+
entry = set_pte_bit(entry, PAGE_KERNEL);
291+
if (!machine.has_nx)
292+
entry = clear_pte_bit(entry, __pgprot(_PAGE_NOEXEC));
291293
set_pte(pte, entry);
292294
pages++;
293295
}
@@ -311,7 +313,9 @@ static void pgtable_pmd_populate(pud_t *pud, unsigned long addr, unsigned long e
311313
continue;
312314
if (can_large_pmd(pmd, addr, next)) {
313315
entry = __pmd(_pa(addr, _SEGMENT_SIZE, mode));
314-
entry = set_pmd_bit(entry, SEGMENT_KERNEL_EXEC);
316+
entry = set_pmd_bit(entry, SEGMENT_KERNEL);
317+
if (!machine.has_nx)
318+
entry = clear_pmd_bit(entry, __pgprot(_SEGMENT_ENTRY_NOEXEC));
315319
set_pmd(pmd, entry);
316320
pages++;
317321
continue;
@@ -342,7 +346,9 @@ static void pgtable_pud_populate(p4d_t *p4d, unsigned long addr, unsigned long e
342346
continue;
343347
if (can_large_pud(pud, addr, next)) {
344348
entry = __pud(_pa(addr, _REGION3_SIZE, mode));
345-
entry = set_pud_bit(entry, REGION3_KERNEL_EXEC);
349+
entry = set_pud_bit(entry, REGION3_KERNEL);
350+
if (!machine.has_nx)
351+
entry = clear_pud_bit(entry, __pgprot(_REGION_ENTRY_NOEXEC));
346352
set_pud(pud, entry);
347353
pages++;
348354
continue;

‎arch/s390/include/asm/airq.h

-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ struct airq_struct {
1818
struct hlist_node list; /* Handler queueing. */
1919
void (*handler)(struct airq_struct *airq, struct tpi_info *tpi_info);
2020
u8 *lsi_ptr; /* Local-Summary-Indicator pointer */
21-
u8 lsi_mask; /* Local-Summary-Indicator mask */
2221
u8 isc; /* Interrupt-subclass */
2322
u8 flags;
2423
};

‎arch/s390/include/asm/dma.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@
99
* to DMA. It _is_ used for the s390 memory zone split at 2GB caused
1010
* by the 31 bit heritage.
1111
*/
12-
#define MAX_DMA_ADDRESS 0x80000000
12+
#define MAX_DMA_ADDRESS __va(0x80000000)
1313

1414
#endif /* _ASM_S390_DMA_H */

‎arch/s390/include/asm/sections.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
*/
2424
#define __bootdata_preserved(var) __section(".boot.preserved.data." #var) var
2525

26-
extern unsigned long __samode31, __eamode31;
27-
extern unsigned long __stext_amode31, __etext_amode31;
26+
extern char *__samode31, *__eamode31;
27+
extern char *__stext_amode31, *__etext_amode31;
2828

2929
#endif

‎arch/s390/include/asm/set_memory.h

+30-32
Original file line numberDiff line numberDiff line change
@@ -24,43 +24,41 @@ enum {
2424
#define SET_MEMORY_INV BIT(_SET_MEMORY_INV_BIT)
2525
#define SET_MEMORY_DEF BIT(_SET_MEMORY_DEF_BIT)
2626

27-
int __set_memory(unsigned long addr, int numpages, unsigned long flags);
28-
29-
static inline int set_memory_ro(unsigned long addr, int numpages)
30-
{
31-
return __set_memory(addr, numpages, SET_MEMORY_RO);
32-
}
33-
34-
static inline int set_memory_rw(unsigned long addr, int numpages)
35-
{
36-
return __set_memory(addr, numpages, SET_MEMORY_RW);
37-
}
38-
39-
static inline int set_memory_nx(unsigned long addr, int numpages)
40-
{
41-
return __set_memory(addr, numpages, SET_MEMORY_NX);
42-
}
43-
44-
static inline int set_memory_x(unsigned long addr, int numpages)
45-
{
46-
return __set_memory(addr, numpages, SET_MEMORY_X);
47-
}
27+
int __set_memory(unsigned long addr, unsigned long numpages, unsigned long flags);
4828

4929
#define set_memory_rox set_memory_rox
50-
static inline int set_memory_rox(unsigned long addr, int numpages)
51-
{
52-
return __set_memory(addr, numpages, SET_MEMORY_RO | SET_MEMORY_X);
53-
}
5430

55-
static inline int set_memory_rwnx(unsigned long addr, int numpages)
56-
{
57-
return __set_memory(addr, numpages, SET_MEMORY_RW | SET_MEMORY_NX);
31+
/*
32+
* Generate two variants of each set_memory() function:
33+
*
34+
* set_memory_yy(unsigned long addr, int numpages);
35+
* __set_memory_yy(void *start, void *end);
36+
*
37+
* The second variant exists for both convenience to avoid the usual
38+
* (unsigned long) casts, but unlike the first variant it can also be used
39+
* for areas larger than 8TB, which may happen at memory initialization.
40+
*/
41+
#define __SET_MEMORY_FUNC(fname, flags) \
42+
static inline int fname(unsigned long addr, int numpages) \
43+
{ \
44+
return __set_memory(addr, numpages, (flags)); \
45+
} \
46+
\
47+
static inline int __##fname(void *start, void *end) \
48+
{ \
49+
unsigned long numpages; \
50+
\
51+
numpages = (end - start) >> PAGE_SHIFT; \
52+
return __set_memory((unsigned long)start, numpages, (flags)); \
5853
}
5954

60-
static inline int set_memory_4k(unsigned long addr, int numpages)
61-
{
62-
return __set_memory(addr, numpages, SET_MEMORY_4K);
63-
}
55+
__SET_MEMORY_FUNC(set_memory_ro, SET_MEMORY_RO)
56+
__SET_MEMORY_FUNC(set_memory_rw, SET_MEMORY_RW)
57+
__SET_MEMORY_FUNC(set_memory_nx, SET_MEMORY_NX)
58+
__SET_MEMORY_FUNC(set_memory_x, SET_MEMORY_X)
59+
__SET_MEMORY_FUNC(set_memory_rox, SET_MEMORY_RO | SET_MEMORY_X)
60+
__SET_MEMORY_FUNC(set_memory_rwnx, SET_MEMORY_RW | SET_MEMORY_NX)
61+
__SET_MEMORY_FUNC(set_memory_4k, SET_MEMORY_4K)
6462

6563
int set_direct_map_invalid_noflush(struct page *page);
6664
int set_direct_map_default_noflush(struct page *page);

‎arch/s390/include/asm/setup.h

-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ extern unsigned int zlib_dfltcc_support;
7272
#define ZLIB_DFLTCC_INFLATE_ONLY 3
7373
#define ZLIB_DFLTCC_FULL_DEBUG 4
7474

75-
extern int noexec_disabled;
7675
extern unsigned long ident_map_size;
7776
extern unsigned long max_mappable;
7877

‎arch/s390/kernel/early.c

+1-4
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ early_param(#param, ignore_decompressor_param_##param)
4444
decompressor_handled_param(mem);
4545
decompressor_handled_param(vmalloc);
4646
decompressor_handled_param(dfltcc);
47-
decompressor_handled_param(noexec);
4847
decompressor_handled_param(facilities);
4948
decompressor_handled_param(nokaslr);
5049
#if IS_ENABLED(CONFIG_KVM)
@@ -233,10 +232,8 @@ static __init void detect_machine_facilities(void)
233232
S390_lowcore.machine_flags |= MACHINE_FLAG_VX;
234233
__ctl_set_bit(0, 17);
235234
}
236-
if (test_facility(130) && !noexec_disabled) {
235+
if (test_facility(130))
237236
S390_lowcore.machine_flags |= MACHINE_FLAG_NX;
238-
__ctl_set_bit(0, 20);
239-
}
240237
if (test_facility(133))
241238
S390_lowcore.machine_flags |= MACHINE_FLAG_GS;
242239
if (test_facility(139) && (tod_clock_base.tod >> 63)) {

‎arch/s390/kernel/machine_kexec.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,8 @@ void arch_crash_save_vmcoreinfo(void)
216216
VMCOREINFO_SYMBOL(lowcore_ptr);
217217
VMCOREINFO_SYMBOL(high_memory);
218218
VMCOREINFO_LENGTH(lowcore_ptr, NR_CPUS);
219-
vmcoreinfo_append_str("SAMODE31=%lx\n", __samode31);
220-
vmcoreinfo_append_str("EAMODE31=%lx\n", __eamode31);
219+
vmcoreinfo_append_str("SAMODE31=%lx\n", (unsigned long)__samode31);
220+
vmcoreinfo_append_str("EAMODE31=%lx\n", (unsigned long)__eamode31);
221221
vmcoreinfo_append_str("KERNELOFFSET=%lx\n", kaslr_offset());
222222
abs_lc = get_abs_lowcore();
223223
abs_lc->vmcore_info = paddr_vmcoreinfo_note();

‎arch/s390/kernel/setup.c

+8-9
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,10 @@ EXPORT_SYMBOL(console_irq);
9797
* relocated above 2 GB, because it has to use 31 bit addresses.
9898
* Such code and data is part of the .amode31 section.
9999
*/
100-
unsigned long __amode31_ref __samode31 = (unsigned long)&_samode31;
101-
unsigned long __amode31_ref __eamode31 = (unsigned long)&_eamode31;
102-
unsigned long __amode31_ref __stext_amode31 = (unsigned long)&_stext_amode31;
103-
unsigned long __amode31_ref __etext_amode31 = (unsigned long)&_etext_amode31;
100+
char __amode31_ref *__samode31 = _samode31;
101+
char __amode31_ref *__eamode31 = _eamode31;
102+
char __amode31_ref *__stext_amode31 = _stext_amode31;
103+
char __amode31_ref *__etext_amode31 = _etext_amode31;
104104
struct exception_table_entry __amode31_ref *__start_amode31_ex_table = _start_amode31_ex_table;
105105
struct exception_table_entry __amode31_ref *__stop_amode31_ex_table = _stop_amode31_ex_table;
106106

@@ -145,7 +145,6 @@ static u32 __amode31_ref *__ctl_duald = __ctl_duald_amode31;
145145
static u32 __amode31_ref *__ctl_linkage_stack = __ctl_linkage_stack_amode31;
146146
static u32 __amode31_ref *__ctl_duct = __ctl_duct_amode31;
147147

148-
int __bootdata(noexec_disabled);
149148
unsigned long __bootdata_preserved(max_mappable);
150149
unsigned long __bootdata(ident_map_size);
151150
struct physmem_info __bootdata(physmem_info);
@@ -771,15 +770,15 @@ static void __init setup_memory(void)
771770
static void __init relocate_amode31_section(void)
772771
{
773772
unsigned long amode31_size = __eamode31 - __samode31;
774-
long amode31_offset = physmem_info.reserved[RR_AMODE31].start - __samode31;
775-
long *ptr;
773+
long amode31_offset, *ptr;
776774

775+
amode31_offset = physmem_info.reserved[RR_AMODE31].start - (unsigned long)__samode31;
777776
pr_info("Relocating AMODE31 section of size 0x%08lx\n", amode31_size);
778777

779778
/* Move original AMODE31 section to the new one */
780-
memmove((void *)physmem_info.reserved[RR_AMODE31].start, (void *)__samode31, amode31_size);
779+
memmove((void *)physmem_info.reserved[RR_AMODE31].start, __samode31, amode31_size);
781780
/* Zero out the old AMODE31 section to catch invalid accesses within it */
782-
memset((void *)__samode31, 0, amode31_size);
781+
memset(__samode31, 0, amode31_size);
783782

784783
/* Update all AMODE31 region references */
785784
for (ptr = _start_amode31_refs; ptr != _end_amode31_refs; ptr++)

‎arch/s390/kvm/interrupt.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -3398,7 +3398,6 @@ static void gib_alert_irq_handler(struct airq_struct *airq,
33983398

33993399
static struct airq_struct gib_alert_irq = {
34003400
.handler = gib_alert_irq_handler,
3401-
.lsi_ptr = &gib_alert_irq.lsi_mask,
34023401
};
34033402

34043403
void kvm_s390_gib_destroy(void)
@@ -3438,6 +3437,8 @@ int __init kvm_s390_gib_init(u8 nisc)
34383437
rc = -EIO;
34393438
goto out_free_gib;
34403439
}
3440+
/* adapter interrupts used for AP (applicable here) don't use the LSI */
3441+
*gib_alert_irq.lsi_ptr = 0xff;
34413442

34423443
gib->nisc = nisc;
34433444
gib_origin = virt_to_phys(gib);

‎arch/s390/mm/dump_pagetables.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -290,8 +290,8 @@ static int pt_dump_init(void)
290290
max_addr = (S390_lowcore.kernel_asce & _REGION_ENTRY_TYPE_MASK) >> 2;
291291
max_addr = 1UL << (max_addr * 11 + 31);
292292
address_markers[IDENTITY_AFTER_END_NR].start_address = ident_map_size;
293-
address_markers[AMODE31_START_NR].start_address = __samode31;
294-
address_markers[AMODE31_END_NR].start_address = __eamode31;
293+
address_markers[AMODE31_START_NR].start_address = (unsigned long)__samode31;
294+
address_markers[AMODE31_END_NR].start_address = (unsigned long)__eamode31;
295295
address_markers[MODULES_NR].start_address = MODULES_VADDR;
296296
address_markers[MODULES_END_NR].start_address = MODULES_END;
297297
address_markers[ABS_LOWCORE_NR].start_address = __abs_lowcore;

‎arch/s390/mm/init.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ void __init paging_init(void)
9898
sparse_init();
9999
zone_dma_bits = 31;
100100
memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
101-
max_zone_pfns[ZONE_DMA] = PFN_DOWN(MAX_DMA_ADDRESS);
101+
max_zone_pfns[ZONE_DMA] = virt_to_pfn(MAX_DMA_ADDRESS);
102102
max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
103103
free_area_init(max_zone_pfns);
104104
}
@@ -107,7 +107,7 @@ void mark_rodata_ro(void)
107107
{
108108
unsigned long size = __end_ro_after_init - __start_ro_after_init;
109109

110-
set_memory_ro((unsigned long)__start_ro_after_init, size >> PAGE_SHIFT);
110+
__set_memory_ro(__start_ro_after_init, __end_ro_after_init);
111111
pr_info("Write protected read-only-after-init data: %luk\n", size >> 10);
112112
debug_checkwx();
113113
}

‎arch/s390/mm/pageattr.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ static int change_page_attr_alias(unsigned long addr, unsigned long end,
373373
return rc;
374374
}
375375

376-
int __set_memory(unsigned long addr, int numpages, unsigned long flags)
376+
int __set_memory(unsigned long addr, unsigned long numpages, unsigned long flags)
377377
{
378378
unsigned long end;
379379
int rc;

0 commit comments

Comments
 (0)