Skip to content

Commit

Permalink
Merge tag 's390-6.6-2' of git://git.kernel.org/pub/scm/linux/kernel/g…
Browse files Browse the repository at this point in the history
…it/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
  • Loading branch information
torvalds committed Sep 7, 2023
2 parents ac2224a + 06fc3b0 commit 4a0fc73
Show file tree
Hide file tree
Showing 21 changed files with 98 additions and 223 deletions.
7 changes: 0 additions & 7 deletions arch/s390/boot/ipl_parm.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ struct parmarea parmarea __section(".parmarea") = {
};

char __bootdata(early_command_line)[COMMAND_LINE_SIZE];
int __bootdata(noexec_disabled);

unsigned int __bootdata_preserved(zlib_dfltcc_support) = ZLIB_DFLTCC_FULL;
struct ipl_parameter_block __bootdata_preserved(ipl_block);
Expand Down Expand Up @@ -290,12 +289,6 @@ void parse_boot_command_line(void)
zlib_dfltcc_support = ZLIB_DFLTCC_FULL_DEBUG;
}

if (!strcmp(param, "noexec")) {
rc = kstrtobool(val, &enabled);
if (!rc && !enabled)
noexec_disabled = 1;
}

if (!strcmp(param, "facilities") && val)
modify_fac_list(val);

Expand Down
4 changes: 1 addition & 3 deletions arch/s390/boot/startup.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,8 @@ static void detect_facilities(void)
}
if (test_facility(78))
machine.has_edat2 = 1;
if (!noexec_disabled && test_facility(130)) {
if (test_facility(130))
machine.has_nx = 1;
__ctl_set_bit(0, 20);
}
}

static void setup_lpp(void)
Expand Down
12 changes: 9 additions & 3 deletions arch/s390/boot/vmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,9 @@ static void pgtable_pte_populate(pmd_t *pmd, unsigned long addr, unsigned long e
if (kasan_pte_populate_zero_shadow(pte, mode))
continue;
entry = __pte(_pa(addr, PAGE_SIZE, mode));
entry = set_pte_bit(entry, PAGE_KERNEL_EXEC);
entry = set_pte_bit(entry, PAGE_KERNEL);
if (!machine.has_nx)
entry = clear_pte_bit(entry, __pgprot(_PAGE_NOEXEC));
set_pte(pte, entry);
pages++;
}
Expand All @@ -311,7 +313,9 @@ static void pgtable_pmd_populate(pud_t *pud, unsigned long addr, unsigned long e
continue;
if (can_large_pmd(pmd, addr, next)) {
entry = __pmd(_pa(addr, _SEGMENT_SIZE, mode));
entry = set_pmd_bit(entry, SEGMENT_KERNEL_EXEC);
entry = set_pmd_bit(entry, SEGMENT_KERNEL);
if (!machine.has_nx)
entry = clear_pmd_bit(entry, __pgprot(_SEGMENT_ENTRY_NOEXEC));
set_pmd(pmd, entry);
pages++;
continue;
Expand Down Expand Up @@ -342,7 +346,9 @@ static void pgtable_pud_populate(p4d_t *p4d, unsigned long addr, unsigned long e
continue;
if (can_large_pud(pud, addr, next)) {
entry = __pud(_pa(addr, _REGION3_SIZE, mode));
entry = set_pud_bit(entry, REGION3_KERNEL_EXEC);
entry = set_pud_bit(entry, REGION3_KERNEL);
if (!machine.has_nx)
entry = clear_pud_bit(entry, __pgprot(_REGION_ENTRY_NOEXEC));
set_pud(pud, entry);
pages++;
continue;
Expand Down
1 change: 0 additions & 1 deletion arch/s390/include/asm/airq.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ struct airq_struct {
struct hlist_node list; /* Handler queueing. */
void (*handler)(struct airq_struct *airq, struct tpi_info *tpi_info);
u8 *lsi_ptr; /* Local-Summary-Indicator pointer */
u8 lsi_mask; /* Local-Summary-Indicator mask */
u8 isc; /* Interrupt-subclass */
u8 flags;
};
Expand Down
2 changes: 1 addition & 1 deletion arch/s390/include/asm/dma.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
* to DMA. It _is_ used for the s390 memory zone split at 2GB caused
* by the 31 bit heritage.
*/
#define MAX_DMA_ADDRESS 0x80000000
#define MAX_DMA_ADDRESS __va(0x80000000)

#endif /* _ASM_S390_DMA_H */
4 changes: 2 additions & 2 deletions arch/s390/include/asm/sections.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
*/
#define __bootdata_preserved(var) __section(".boot.preserved.data." #var) var

extern unsigned long __samode31, __eamode31;
extern unsigned long __stext_amode31, __etext_amode31;
extern char *__samode31, *__eamode31;
extern char *__stext_amode31, *__etext_amode31;

#endif
62 changes: 30 additions & 32 deletions arch/s390/include/asm/set_memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,43 +24,41 @@ enum {
#define SET_MEMORY_INV BIT(_SET_MEMORY_INV_BIT)
#define SET_MEMORY_DEF BIT(_SET_MEMORY_DEF_BIT)

int __set_memory(unsigned long addr, int numpages, unsigned long flags);

static inline int set_memory_ro(unsigned long addr, int numpages)
{
return __set_memory(addr, numpages, SET_MEMORY_RO);
}

static inline int set_memory_rw(unsigned long addr, int numpages)
{
return __set_memory(addr, numpages, SET_MEMORY_RW);
}

static inline int set_memory_nx(unsigned long addr, int numpages)
{
return __set_memory(addr, numpages, SET_MEMORY_NX);
}

static inline int set_memory_x(unsigned long addr, int numpages)
{
return __set_memory(addr, numpages, SET_MEMORY_X);
}
int __set_memory(unsigned long addr, unsigned long numpages, unsigned long flags);

#define set_memory_rox set_memory_rox
static inline int set_memory_rox(unsigned long addr, int numpages)
{
return __set_memory(addr, numpages, SET_MEMORY_RO | SET_MEMORY_X);
}

static inline int set_memory_rwnx(unsigned long addr, int numpages)
{
return __set_memory(addr, numpages, SET_MEMORY_RW | SET_MEMORY_NX);
/*
* Generate two variants of each set_memory() function:
*
* set_memory_yy(unsigned long addr, int numpages);
* __set_memory_yy(void *start, void *end);
*
* The second variant exists for both convenience to avoid the usual
* (unsigned long) casts, but unlike the first variant it can also be used
* for areas larger than 8TB, which may happen at memory initialization.
*/
#define __SET_MEMORY_FUNC(fname, flags) \
static inline int fname(unsigned long addr, int numpages) \
{ \
return __set_memory(addr, numpages, (flags)); \
} \
\
static inline int __##fname(void *start, void *end) \
{ \
unsigned long numpages; \
\
numpages = (end - start) >> PAGE_SHIFT; \
return __set_memory((unsigned long)start, numpages, (flags)); \
}

static inline int set_memory_4k(unsigned long addr, int numpages)
{
return __set_memory(addr, numpages, SET_MEMORY_4K);
}
__SET_MEMORY_FUNC(set_memory_ro, SET_MEMORY_RO)
__SET_MEMORY_FUNC(set_memory_rw, SET_MEMORY_RW)
__SET_MEMORY_FUNC(set_memory_nx, SET_MEMORY_NX)
__SET_MEMORY_FUNC(set_memory_x, SET_MEMORY_X)
__SET_MEMORY_FUNC(set_memory_rox, SET_MEMORY_RO | SET_MEMORY_X)
__SET_MEMORY_FUNC(set_memory_rwnx, SET_MEMORY_RW | SET_MEMORY_NX)
__SET_MEMORY_FUNC(set_memory_4k, SET_MEMORY_4K)

int set_direct_map_invalid_noflush(struct page *page);
int set_direct_map_default_noflush(struct page *page);
Expand Down
1 change: 0 additions & 1 deletion arch/s390/include/asm/setup.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ extern unsigned int zlib_dfltcc_support;
#define ZLIB_DFLTCC_INFLATE_ONLY 3
#define ZLIB_DFLTCC_FULL_DEBUG 4

extern int noexec_disabled;
extern unsigned long ident_map_size;
extern unsigned long max_mappable;

Expand Down
5 changes: 1 addition & 4 deletions arch/s390/kernel/early.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ early_param(#param, ignore_decompressor_param_##param)
decompressor_handled_param(mem);
decompressor_handled_param(vmalloc);
decompressor_handled_param(dfltcc);
decompressor_handled_param(noexec);
decompressor_handled_param(facilities);
decompressor_handled_param(nokaslr);
#if IS_ENABLED(CONFIG_KVM)
Expand Down Expand Up @@ -233,10 +232,8 @@ static __init void detect_machine_facilities(void)
S390_lowcore.machine_flags |= MACHINE_FLAG_VX;
__ctl_set_bit(0, 17);
}
if (test_facility(130) && !noexec_disabled) {
if (test_facility(130))
S390_lowcore.machine_flags |= MACHINE_FLAG_NX;
__ctl_set_bit(0, 20);
}
if (test_facility(133))
S390_lowcore.machine_flags |= MACHINE_FLAG_GS;
if (test_facility(139) && (tod_clock_base.tod >> 63)) {
Expand Down
4 changes: 2 additions & 2 deletions arch/s390/kernel/machine_kexec.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,8 @@ void arch_crash_save_vmcoreinfo(void)
VMCOREINFO_SYMBOL(lowcore_ptr);
VMCOREINFO_SYMBOL(high_memory);
VMCOREINFO_LENGTH(lowcore_ptr, NR_CPUS);
vmcoreinfo_append_str("SAMODE31=%lx\n", __samode31);
vmcoreinfo_append_str("EAMODE31=%lx\n", __eamode31);
vmcoreinfo_append_str("SAMODE31=%lx\n", (unsigned long)__samode31);
vmcoreinfo_append_str("EAMODE31=%lx\n", (unsigned long)__eamode31);
vmcoreinfo_append_str("KERNELOFFSET=%lx\n", kaslr_offset());
abs_lc = get_abs_lowcore();
abs_lc->vmcore_info = paddr_vmcoreinfo_note();
Expand Down
17 changes: 8 additions & 9 deletions arch/s390/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,10 @@ EXPORT_SYMBOL(console_irq);
* relocated above 2 GB, because it has to use 31 bit addresses.
* Such code and data is part of the .amode31 section.
*/
unsigned long __amode31_ref __samode31 = (unsigned long)&_samode31;
unsigned long __amode31_ref __eamode31 = (unsigned long)&_eamode31;
unsigned long __amode31_ref __stext_amode31 = (unsigned long)&_stext_amode31;
unsigned long __amode31_ref __etext_amode31 = (unsigned long)&_etext_amode31;
char __amode31_ref *__samode31 = _samode31;
char __amode31_ref *__eamode31 = _eamode31;
char __amode31_ref *__stext_amode31 = _stext_amode31;
char __amode31_ref *__etext_amode31 = _etext_amode31;
struct exception_table_entry __amode31_ref *__start_amode31_ex_table = _start_amode31_ex_table;
struct exception_table_entry __amode31_ref *__stop_amode31_ex_table = _stop_amode31_ex_table;

Expand Down Expand Up @@ -145,7 +145,6 @@ static u32 __amode31_ref *__ctl_duald = __ctl_duald_amode31;
static u32 __amode31_ref *__ctl_linkage_stack = __ctl_linkage_stack_amode31;
static u32 __amode31_ref *__ctl_duct = __ctl_duct_amode31;

int __bootdata(noexec_disabled);
unsigned long __bootdata_preserved(max_mappable);
unsigned long __bootdata(ident_map_size);
struct physmem_info __bootdata(physmem_info);
Expand Down Expand Up @@ -771,15 +770,15 @@ static void __init setup_memory(void)
static void __init relocate_amode31_section(void)
{
unsigned long amode31_size = __eamode31 - __samode31;
long amode31_offset = physmem_info.reserved[RR_AMODE31].start - __samode31;
long *ptr;
long amode31_offset, *ptr;

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

/* Move original AMODE31 section to the new one */
memmove((void *)physmem_info.reserved[RR_AMODE31].start, (void *)__samode31, amode31_size);
memmove((void *)physmem_info.reserved[RR_AMODE31].start, __samode31, amode31_size);
/* Zero out the old AMODE31 section to catch invalid accesses within it */
memset((void *)__samode31, 0, amode31_size);
memset(__samode31, 0, amode31_size);

/* Update all AMODE31 region references */
for (ptr = _start_amode31_refs; ptr != _end_amode31_refs; ptr++)
Expand Down
3 changes: 2 additions & 1 deletion arch/s390/kvm/interrupt.c
Original file line number Diff line number Diff line change
Expand Up @@ -3398,7 +3398,6 @@ static void gib_alert_irq_handler(struct airq_struct *airq,

static struct airq_struct gib_alert_irq = {
.handler = gib_alert_irq_handler,
.lsi_ptr = &gib_alert_irq.lsi_mask,
};

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

gib->nisc = nisc;
gib_origin = virt_to_phys(gib);
Expand Down
4 changes: 2 additions & 2 deletions arch/s390/mm/dump_pagetables.c
Original file line number Diff line number Diff line change
Expand Up @@ -290,8 +290,8 @@ static int pt_dump_init(void)
max_addr = (S390_lowcore.kernel_asce & _REGION_ENTRY_TYPE_MASK) >> 2;
max_addr = 1UL << (max_addr * 11 + 31);
address_markers[IDENTITY_AFTER_END_NR].start_address = ident_map_size;
address_markers[AMODE31_START_NR].start_address = __samode31;
address_markers[AMODE31_END_NR].start_address = __eamode31;
address_markers[AMODE31_START_NR].start_address = (unsigned long)__samode31;
address_markers[AMODE31_END_NR].start_address = (unsigned long)__eamode31;
address_markers[MODULES_NR].start_address = MODULES_VADDR;
address_markers[MODULES_END_NR].start_address = MODULES_END;
address_markers[ABS_LOWCORE_NR].start_address = __abs_lowcore;
Expand Down
4 changes: 2 additions & 2 deletions arch/s390/mm/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ void __init paging_init(void)
sparse_init();
zone_dma_bits = 31;
memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
max_zone_pfns[ZONE_DMA] = PFN_DOWN(MAX_DMA_ADDRESS);
max_zone_pfns[ZONE_DMA] = virt_to_pfn(MAX_DMA_ADDRESS);
max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
free_area_init(max_zone_pfns);
}
Expand All @@ -107,7 +107,7 @@ void mark_rodata_ro(void)
{
unsigned long size = __end_ro_after_init - __start_ro_after_init;

set_memory_ro((unsigned long)__start_ro_after_init, size >> PAGE_SHIFT);
__set_memory_ro(__start_ro_after_init, __end_ro_after_init);
pr_info("Write protected read-only-after-init data: %luk\n", size >> 10);
debug_checkwx();
}
Expand Down
2 changes: 1 addition & 1 deletion arch/s390/mm/pageattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ static int change_page_attr_alias(unsigned long addr, unsigned long end,
return rc;
}

int __set_memory(unsigned long addr, int numpages, unsigned long flags)
int __set_memory(unsigned long addr, unsigned long numpages, unsigned long flags)
{
unsigned long end;
int rc;
Expand Down
Loading

0 comments on commit 4a0fc73

Please sign in to comment.