Commit 4a0fc73d authored by Linus Torvalds's avatar Linus Torvalds

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
parents ac2224a4 06fc3b0d
...@@ -19,7 +19,6 @@ struct parmarea parmarea __section(".parmarea") = { ...@@ -19,7 +19,6 @@ struct parmarea parmarea __section(".parmarea") = {
}; };
char __bootdata(early_command_line)[COMMAND_LINE_SIZE]; char __bootdata(early_command_line)[COMMAND_LINE_SIZE];
int __bootdata(noexec_disabled);
unsigned int __bootdata_preserved(zlib_dfltcc_support) = ZLIB_DFLTCC_FULL; unsigned int __bootdata_preserved(zlib_dfltcc_support) = ZLIB_DFLTCC_FULL;
struct ipl_parameter_block __bootdata_preserved(ipl_block); struct ipl_parameter_block __bootdata_preserved(ipl_block);
...@@ -290,12 +289,6 @@ void parse_boot_command_line(void) ...@@ -290,12 +289,6 @@ void parse_boot_command_line(void)
zlib_dfltcc_support = ZLIB_DFLTCC_FULL_DEBUG; 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) if (!strcmp(param, "facilities") && val)
modify_fac_list(val); modify_fac_list(val);
......
...@@ -53,10 +53,8 @@ static void detect_facilities(void) ...@@ -53,10 +53,8 @@ static void detect_facilities(void)
} }
if (test_facility(78)) if (test_facility(78))
machine.has_edat2 = 1; machine.has_edat2 = 1;
if (!noexec_disabled && test_facility(130)) { if (test_facility(130))
machine.has_nx = 1; machine.has_nx = 1;
__ctl_set_bit(0, 20);
}
} }
static void setup_lpp(void) static void setup_lpp(void)
......
...@@ -287,7 +287,9 @@ static void pgtable_pte_populate(pmd_t *pmd, unsigned long addr, unsigned long e ...@@ -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)) if (kasan_pte_populate_zero_shadow(pte, mode))
continue; continue;
entry = __pte(_pa(addr, PAGE_SIZE, mode)); 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); set_pte(pte, entry);
pages++; pages++;
} }
...@@ -311,7 +313,9 @@ static void pgtable_pmd_populate(pud_t *pud, unsigned long addr, unsigned long e ...@@ -311,7 +313,9 @@ static void pgtable_pmd_populate(pud_t *pud, unsigned long addr, unsigned long e
continue; continue;
if (can_large_pmd(pmd, addr, next)) { if (can_large_pmd(pmd, addr, next)) {
entry = __pmd(_pa(addr, _SEGMENT_SIZE, mode)); 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); set_pmd(pmd, entry);
pages++; pages++;
continue; continue;
...@@ -342,7 +346,9 @@ static void pgtable_pud_populate(p4d_t *p4d, unsigned long addr, unsigned long e ...@@ -342,7 +346,9 @@ static void pgtable_pud_populate(p4d_t *p4d, unsigned long addr, unsigned long e
continue; continue;
if (can_large_pud(pud, addr, next)) { if (can_large_pud(pud, addr, next)) {
entry = __pud(_pa(addr, _REGION3_SIZE, mode)); 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); set_pud(pud, entry);
pages++; pages++;
continue; continue;
......
...@@ -18,7 +18,6 @@ struct airq_struct { ...@@ -18,7 +18,6 @@ struct airq_struct {
struct hlist_node list; /* Handler queueing. */ struct hlist_node list; /* Handler queueing. */
void (*handler)(struct airq_struct *airq, struct tpi_info *tpi_info); void (*handler)(struct airq_struct *airq, struct tpi_info *tpi_info);
u8 *lsi_ptr; /* Local-Summary-Indicator pointer */ u8 *lsi_ptr; /* Local-Summary-Indicator pointer */
u8 lsi_mask; /* Local-Summary-Indicator mask */
u8 isc; /* Interrupt-subclass */ u8 isc; /* Interrupt-subclass */
u8 flags; u8 flags;
}; };
......
...@@ -9,6 +9,6 @@ ...@@ -9,6 +9,6 @@
* to DMA. It _is_ used for the s390 memory zone split at 2GB caused * to DMA. It _is_ used for the s390 memory zone split at 2GB caused
* by the 31 bit heritage. * by the 31 bit heritage.
*/ */
#define MAX_DMA_ADDRESS 0x80000000 #define MAX_DMA_ADDRESS __va(0x80000000)
#endif /* _ASM_S390_DMA_H */ #endif /* _ASM_S390_DMA_H */
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
*/ */
#define __bootdata_preserved(var) __section(".boot.preserved.data." #var) var #define __bootdata_preserved(var) __section(".boot.preserved.data." #var) var
extern unsigned long __samode31, __eamode31; extern char *__samode31, *__eamode31;
extern unsigned long __stext_amode31, __etext_amode31; extern char *__stext_amode31, *__etext_amode31;
#endif #endif
...@@ -24,43 +24,41 @@ enum { ...@@ -24,43 +24,41 @@ enum {
#define SET_MEMORY_INV BIT(_SET_MEMORY_INV_BIT) #define SET_MEMORY_INV BIT(_SET_MEMORY_INV_BIT)
#define SET_MEMORY_DEF BIT(_SET_MEMORY_DEF_BIT) #define SET_MEMORY_DEF BIT(_SET_MEMORY_DEF_BIT)
int __set_memory(unsigned long addr, int numpages, unsigned long flags); int __set_memory(unsigned long addr, unsigned long 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);
}
#define set_memory_rox set_memory_rox #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) /*
{ * Generate two variants of each set_memory() function:
return __set_memory(addr, numpages, SET_MEMORY_RW | SET_MEMORY_NX); *
* 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) __SET_MEMORY_FUNC(set_memory_ro, SET_MEMORY_RO)
{ __SET_MEMORY_FUNC(set_memory_rw, SET_MEMORY_RW)
return __set_memory(addr, numpages, SET_MEMORY_4K); __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_invalid_noflush(struct page *page);
int set_direct_map_default_noflush(struct page *page); int set_direct_map_default_noflush(struct page *page);
......
...@@ -72,7 +72,6 @@ extern unsigned int zlib_dfltcc_support; ...@@ -72,7 +72,6 @@ extern unsigned int zlib_dfltcc_support;
#define ZLIB_DFLTCC_INFLATE_ONLY 3 #define ZLIB_DFLTCC_INFLATE_ONLY 3
#define ZLIB_DFLTCC_FULL_DEBUG 4 #define ZLIB_DFLTCC_FULL_DEBUG 4
extern int noexec_disabled;
extern unsigned long ident_map_size; extern unsigned long ident_map_size;
extern unsigned long max_mappable; extern unsigned long max_mappable;
......
...@@ -44,7 +44,6 @@ early_param(#param, ignore_decompressor_param_##param) ...@@ -44,7 +44,6 @@ early_param(#param, ignore_decompressor_param_##param)
decompressor_handled_param(mem); decompressor_handled_param(mem);
decompressor_handled_param(vmalloc); decompressor_handled_param(vmalloc);
decompressor_handled_param(dfltcc); decompressor_handled_param(dfltcc);
decompressor_handled_param(noexec);
decompressor_handled_param(facilities); decompressor_handled_param(facilities);
decompressor_handled_param(nokaslr); decompressor_handled_param(nokaslr);
#if IS_ENABLED(CONFIG_KVM) #if IS_ENABLED(CONFIG_KVM)
...@@ -233,10 +232,8 @@ static __init void detect_machine_facilities(void) ...@@ -233,10 +232,8 @@ static __init void detect_machine_facilities(void)
S390_lowcore.machine_flags |= MACHINE_FLAG_VX; S390_lowcore.machine_flags |= MACHINE_FLAG_VX;
__ctl_set_bit(0, 17); __ctl_set_bit(0, 17);
} }
if (test_facility(130) && !noexec_disabled) { if (test_facility(130))
S390_lowcore.machine_flags |= MACHINE_FLAG_NX; S390_lowcore.machine_flags |= MACHINE_FLAG_NX;
__ctl_set_bit(0, 20);
}
if (test_facility(133)) if (test_facility(133))
S390_lowcore.machine_flags |= MACHINE_FLAG_GS; S390_lowcore.machine_flags |= MACHINE_FLAG_GS;
if (test_facility(139) && (tod_clock_base.tod >> 63)) { if (test_facility(139) && (tod_clock_base.tod >> 63)) {
......
...@@ -216,8 +216,8 @@ void arch_crash_save_vmcoreinfo(void) ...@@ -216,8 +216,8 @@ void arch_crash_save_vmcoreinfo(void)
VMCOREINFO_SYMBOL(lowcore_ptr); VMCOREINFO_SYMBOL(lowcore_ptr);
VMCOREINFO_SYMBOL(high_memory); VMCOREINFO_SYMBOL(high_memory);
VMCOREINFO_LENGTH(lowcore_ptr, NR_CPUS); VMCOREINFO_LENGTH(lowcore_ptr, NR_CPUS);
vmcoreinfo_append_str("SAMODE31=%lx\n", __samode31); vmcoreinfo_append_str("SAMODE31=%lx\n", (unsigned long)__samode31);
vmcoreinfo_append_str("EAMODE31=%lx\n", __eamode31); vmcoreinfo_append_str("EAMODE31=%lx\n", (unsigned long)__eamode31);
vmcoreinfo_append_str("KERNELOFFSET=%lx\n", kaslr_offset()); vmcoreinfo_append_str("KERNELOFFSET=%lx\n", kaslr_offset());
abs_lc = get_abs_lowcore(); abs_lc = get_abs_lowcore();
abs_lc->vmcore_info = paddr_vmcoreinfo_note(); abs_lc->vmcore_info = paddr_vmcoreinfo_note();
......
...@@ -97,10 +97,10 @@ EXPORT_SYMBOL(console_irq); ...@@ -97,10 +97,10 @@ EXPORT_SYMBOL(console_irq);
* relocated above 2 GB, because it has to use 31 bit addresses. * relocated above 2 GB, because it has to use 31 bit addresses.
* Such code and data is part of the .amode31 section. * Such code and data is part of the .amode31 section.
*/ */
unsigned long __amode31_ref __samode31 = (unsigned long)&_samode31; char __amode31_ref *__samode31 = _samode31;
unsigned long __amode31_ref __eamode31 = (unsigned long)&_eamode31; char __amode31_ref *__eamode31 = _eamode31;
unsigned long __amode31_ref __stext_amode31 = (unsigned long)&_stext_amode31; char __amode31_ref *__stext_amode31 = _stext_amode31;
unsigned long __amode31_ref __etext_amode31 = (unsigned long)&_etext_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 *__start_amode31_ex_table = _start_amode31_ex_table;
struct exception_table_entry __amode31_ref *__stop_amode31_ex_table = _stop_amode31_ex_table; struct exception_table_entry __amode31_ref *__stop_amode31_ex_table = _stop_amode31_ex_table;
...@@ -145,7 +145,6 @@ static u32 __amode31_ref *__ctl_duald = __ctl_duald_amode31; ...@@ -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_linkage_stack = __ctl_linkage_stack_amode31;
static u32 __amode31_ref *__ctl_duct = __ctl_duct_amode31; static u32 __amode31_ref *__ctl_duct = __ctl_duct_amode31;
int __bootdata(noexec_disabled);
unsigned long __bootdata_preserved(max_mappable); unsigned long __bootdata_preserved(max_mappable);
unsigned long __bootdata(ident_map_size); unsigned long __bootdata(ident_map_size);
struct physmem_info __bootdata(physmem_info); struct physmem_info __bootdata(physmem_info);
...@@ -771,15 +770,15 @@ static void __init setup_memory(void) ...@@ -771,15 +770,15 @@ static void __init setup_memory(void)
static void __init relocate_amode31_section(void) static void __init relocate_amode31_section(void)
{ {
unsigned long amode31_size = __eamode31 - __samode31; unsigned long amode31_size = __eamode31 - __samode31;
long amode31_offset = physmem_info.reserved[RR_AMODE31].start - __samode31; long amode31_offset, *ptr;
long *ptr;
amode31_offset = physmem_info.reserved[RR_AMODE31].start - (unsigned long)__samode31;
pr_info("Relocating AMODE31 section of size 0x%08lx\n", amode31_size); pr_info("Relocating AMODE31 section of size 0x%08lx\n", amode31_size);
/* Move original AMODE31 section to the new one */ /* 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 */ /* 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 */ /* Update all AMODE31 region references */
for (ptr = _start_amode31_refs; ptr != _end_amode31_refs; ptr++) for (ptr = _start_amode31_refs; ptr != _end_amode31_refs; ptr++)
......
...@@ -3398,7 +3398,6 @@ static void gib_alert_irq_handler(struct airq_struct *airq, ...@@ -3398,7 +3398,6 @@ static void gib_alert_irq_handler(struct airq_struct *airq,
static struct airq_struct gib_alert_irq = { static struct airq_struct gib_alert_irq = {
.handler = gib_alert_irq_handler, .handler = gib_alert_irq_handler,
.lsi_ptr = &gib_alert_irq.lsi_mask,
}; };
void kvm_s390_gib_destroy(void) void kvm_s390_gib_destroy(void)
...@@ -3438,6 +3437,8 @@ int __init kvm_s390_gib_init(u8 nisc) ...@@ -3438,6 +3437,8 @@ int __init kvm_s390_gib_init(u8 nisc)
rc = -EIO; rc = -EIO;
goto out_free_gib; 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->nisc = nisc;
gib_origin = virt_to_phys(gib); gib_origin = virt_to_phys(gib);
......
...@@ -290,8 +290,8 @@ static int pt_dump_init(void) ...@@ -290,8 +290,8 @@ static int pt_dump_init(void)
max_addr = (S390_lowcore.kernel_asce & _REGION_ENTRY_TYPE_MASK) >> 2; max_addr = (S390_lowcore.kernel_asce & _REGION_ENTRY_TYPE_MASK) >> 2;
max_addr = 1UL << (max_addr * 11 + 31); max_addr = 1UL << (max_addr * 11 + 31);
address_markers[IDENTITY_AFTER_END_NR].start_address = ident_map_size; address_markers[IDENTITY_AFTER_END_NR].start_address = ident_map_size;
address_markers[AMODE31_START_NR].start_address = __samode31; address_markers[AMODE31_START_NR].start_address = (unsigned long)__samode31;
address_markers[AMODE31_END_NR].start_address = __eamode31; address_markers[AMODE31_END_NR].start_address = (unsigned long)__eamode31;
address_markers[MODULES_NR].start_address = MODULES_VADDR; address_markers[MODULES_NR].start_address = MODULES_VADDR;
address_markers[MODULES_END_NR].start_address = MODULES_END; address_markers[MODULES_END_NR].start_address = MODULES_END;
address_markers[ABS_LOWCORE_NR].start_address = __abs_lowcore; address_markers[ABS_LOWCORE_NR].start_address = __abs_lowcore;
......
...@@ -98,7 +98,7 @@ void __init paging_init(void) ...@@ -98,7 +98,7 @@ void __init paging_init(void)
sparse_init(); sparse_init();
zone_dma_bits = 31; zone_dma_bits = 31;
memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); 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; max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
free_area_init(max_zone_pfns); free_area_init(max_zone_pfns);
} }
...@@ -107,7 +107,7 @@ void mark_rodata_ro(void) ...@@ -107,7 +107,7 @@ void mark_rodata_ro(void)
{ {
unsigned long size = __end_ro_after_init - __start_ro_after_init; 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); pr_info("Write protected read-only-after-init data: %luk\n", size >> 10);
debug_checkwx(); debug_checkwx();
} }
......
...@@ -373,7 +373,7 @@ static int change_page_attr_alias(unsigned long addr, unsigned long end, ...@@ -373,7 +373,7 @@ static int change_page_attr_alias(unsigned long addr, unsigned long end,
return rc; 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; unsigned long end;
int rc; int rc;
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
#include <linux/memory_hotplug.h> #include <linux/memory_hotplug.h>
#include <linux/memblock.h> #include <linux/memblock.h>
#include <linux/kasan.h>
#include <linux/pfn.h> #include <linux/pfn.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/init.h> #include <linux/init.h>
...@@ -291,14 +290,9 @@ static int __ref modify_pmd_table(pud_t *pud, unsigned long addr, ...@@ -291,14 +290,9 @@ static int __ref modify_pmd_table(pud_t *pud, unsigned long addr,
static void try_free_pmd_table(pud_t *pud, unsigned long start) static void try_free_pmd_table(pud_t *pud, unsigned long start)
{ {
const unsigned long end = start + PUD_SIZE;
pmd_t *pmd; pmd_t *pmd;
int i; int i;
/* Don't mess with any tables not fully in 1:1 mapping & vmemmap area */
if (end > VMALLOC_START)
return;
pmd = pmd_offset(pud, start); pmd = pmd_offset(pud, start);
for (i = 0; i < PTRS_PER_PMD; i++, pmd++) for (i = 0; i < PTRS_PER_PMD; i++, pmd++)
if (!pmd_none(*pmd)) if (!pmd_none(*pmd))
...@@ -363,14 +357,9 @@ static int modify_pud_table(p4d_t *p4d, unsigned long addr, unsigned long end, ...@@ -363,14 +357,9 @@ static int modify_pud_table(p4d_t *p4d, unsigned long addr, unsigned long end,
static void try_free_pud_table(p4d_t *p4d, unsigned long start) static void try_free_pud_table(p4d_t *p4d, unsigned long start)
{ {
const unsigned long end = start + P4D_SIZE;
pud_t *pud; pud_t *pud;
int i; int i;
/* Don't mess with any tables not fully in 1:1 mapping & vmemmap area */
if (end > VMALLOC_START)
return;
pud = pud_offset(p4d, start); pud = pud_offset(p4d, start);
for (i = 0; i < PTRS_PER_PUD; i++, pud++) { for (i = 0; i < PTRS_PER_PUD; i++, pud++) {
if (!pud_none(*pud)) if (!pud_none(*pud))
...@@ -413,14 +402,9 @@ static int modify_p4d_table(pgd_t *pgd, unsigned long addr, unsigned long end, ...@@ -413,14 +402,9 @@ static int modify_p4d_table(pgd_t *pgd, unsigned long addr, unsigned long end,
static void try_free_p4d_table(pgd_t *pgd, unsigned long start) static void try_free_p4d_table(pgd_t *pgd, unsigned long start)
{ {
const unsigned long end = start + PGDIR_SIZE;
p4d_t *p4d; p4d_t *p4d;
int i; int i;
/* Don't mess with any tables not fully in 1:1 mapping & vmemmap area */
if (end > VMALLOC_START)
return;
p4d = p4d_offset(pgd, start); p4d = p4d_offset(pgd, start);
for (i = 0; i < PTRS_PER_P4D; i++, p4d++) { for (i = 0; i < PTRS_PER_P4D; i++, p4d++) {
if (!p4d_none(*p4d)) if (!p4d_none(*p4d))
...@@ -440,6 +424,9 @@ static int modify_pagetable(unsigned long start, unsigned long end, bool add, ...@@ -440,6 +424,9 @@ static int modify_pagetable(unsigned long start, unsigned long end, bool add,
if (WARN_ON_ONCE(!PAGE_ALIGNED(start | end))) if (WARN_ON_ONCE(!PAGE_ALIGNED(start | end)))
return -EINVAL; return -EINVAL;
/* Don't mess with any tables not fully in 1:1 mapping & vmemmap area */
if (WARN_ON_ONCE(end > VMALLOC_START))
return -EINVAL;
for (addr = start; addr < end; addr = next) { for (addr = start; addr < end; addr = next) {
next = pgd_addr_end(addr, end); next = pgd_addr_end(addr, end);
pgd = pgd_offset_k(addr); pgd = pgd_offset_k(addr);
...@@ -650,122 +637,29 @@ void vmem_unmap_4k_page(unsigned long addr) ...@@ -650,122 +637,29 @@ void vmem_unmap_4k_page(unsigned long addr)
mutex_unlock(&vmem_mutex); mutex_unlock(&vmem_mutex);
} }
static int __init memblock_region_cmp(const void *a, const void *b)
{
const struct memblock_region *r1 = a;
const struct memblock_region *r2 = b;
if (r1->base < r2->base)
return -1;
if (r1->base > r2->base)
return 1;
return 0;
}
static void __init memblock_region_swap(void *a, void *b, int size)
{
swap(*(struct memblock_region *)a, *(struct memblock_region *)b);
}
#ifdef CONFIG_KASAN
#define __sha(x) ((unsigned long)kasan_mem_to_shadow((void *)x))
static inline int set_memory_kasan(unsigned long start, unsigned long end)
{
start = PAGE_ALIGN_DOWN(__sha(start));
end = PAGE_ALIGN(__sha(end));
return set_memory_rwnx(start, (end - start) >> PAGE_SHIFT);
}
#endif
/*
* map whole physical memory to virtual memory (identity mapping)
* we reserve enough space in the vmalloc area for vmemmap to hotplug
* additional memory segments.
*/
void __init vmem_map_init(void) void __init vmem_map_init(void)
{ {
struct memblock_region memory_rwx_regions[] = { __set_memory_rox(_stext, _etext);
{ __set_memory_ro(_etext, __end_rodata);
.base = 0, __set_memory_rox(_sinittext, _einittext);
.size = sizeof(struct lowcore), __set_memory_rox(__stext_amode31, __etext_amode31);
.flags = MEMBLOCK_NONE,
#ifdef CONFIG_NUMA
.nid = NUMA_NO_NODE,
#endif
},
{
.base = __pa(_stext),
.size = _etext - _stext,
.flags = MEMBLOCK_NONE,
#ifdef CONFIG_NUMA
.nid = NUMA_NO_NODE,
#endif
},
{
.base = __pa(_sinittext),
.size = _einittext - _sinittext,
.flags = MEMBLOCK_NONE,
#ifdef CONFIG_NUMA
.nid = NUMA_NO_NODE,
#endif
},
{
.base = __stext_amode31,
.size = __etext_amode31 - __stext_amode31,
.flags = MEMBLOCK_NONE,
#ifdef CONFIG_NUMA
.nid = NUMA_NO_NODE,
#endif
},
};
struct memblock_type memory_rwx = {
.regions = memory_rwx_regions,
.cnt = ARRAY_SIZE(memory_rwx_regions),
.max = ARRAY_SIZE(memory_rwx_regions),
};
phys_addr_t base, end;
u64 i;
/* /*
* Set RW+NX attribute on all memory, except regions enumerated with * If the BEAR-enhancement facility is not installed the first
* memory_rwx exclude type. These regions need different attributes, * prefix page is used to return to the previous context with
* which are enforced afterwards. * an LPSWE instruction and therefore must be executable.
*
* __for_each_mem_range() iterate and exclude types should be sorted.
* The relative location of _stext and _sinittext is hardcoded in the
* linker script. However a location of __stext_amode31 and the kernel
* image itself are chosen dynamically. Thus, sort the exclude type.
*/ */
sort(&memory_rwx_regions, if (!static_key_enabled(&cpu_has_bear))
ARRAY_SIZE(memory_rwx_regions), sizeof(memory_rwx_regions[0]), set_memory_x(0, 1);
memblock_region_cmp, memblock_region_swap); if (debug_pagealloc_enabled()) {
__for_each_mem_range(i, &memblock.memory, &memory_rwx, /*
NUMA_NO_NODE, MEMBLOCK_NONE, &base, &end, NULL) { * Use RELOC_HIDE() as long as __va(0) translates to NULL,
set_memory_rwnx((unsigned long)__va(base), * since performing pointer arithmetic on a NULL pointer
(end - base) >> PAGE_SHIFT); * has undefined behavior and generates compiler warnings.
*/
__set_memory_4k(__va(0), RELOC_HIDE(__va(0), ident_map_size));
} }
if (MACHINE_HAS_NX)
#ifdef CONFIG_KASAN ctl_set_bit(0, 20);
for_each_mem_range(i, &base, &end)
set_memory_kasan(base, end);
#endif
set_memory_rox((unsigned long)_stext,
(unsigned long)(_etext - _stext) >> PAGE_SHIFT);
set_memory_ro((unsigned long)_etext,
(unsigned long)(__end_rodata - _etext) >> PAGE_SHIFT);
set_memory_rox((unsigned long)_sinittext,
(unsigned long)(_einittext - _sinittext) >> PAGE_SHIFT);
set_memory_rox(__stext_amode31,
(__etext_amode31 - __stext_amode31) >> PAGE_SHIFT);
/* lowcore must be executable for LPSWE */
if (static_key_enabled(&cpu_has_bear))
set_memory_nx(0, 1);
set_memory_nx(PAGE_SIZE, 1);
if (debug_pagealloc_enabled())
set_memory_4k(0, ident_map_size >> PAGE_SHIFT);
pr_info("Write protected kernel read-only data: %luk\n", pr_info("Write protected kernel read-only data: %luk\n",
(unsigned long)(__end_rodata - _stext) >> 10); (unsigned long)(__end_rodata - _stext) >> 10);
} }
...@@ -411,13 +411,13 @@ dcssblk_shared_store(struct device *dev, struct device_attribute *attr, const ch ...@@ -411,13 +411,13 @@ dcssblk_shared_store(struct device *dev, struct device_attribute *attr, const ch
segment_unload(entry->segment_name); segment_unload(entry->segment_name);
} }
list_del(&dev_info->lh); list_del(&dev_info->lh);
up_write(&dcssblk_devices_sem);
dax_remove_host(dev_info->gd); dax_remove_host(dev_info->gd);
kill_dax(dev_info->dax_dev); kill_dax(dev_info->dax_dev);
put_dax(dev_info->dax_dev); put_dax(dev_info->dax_dev);
del_gendisk(dev_info->gd); del_gendisk(dev_info->gd);
put_disk(dev_info->gd); put_disk(dev_info->gd);
up_write(&dcssblk_devices_sem);
if (device_remove_file_self(dev, attr)) { if (device_remove_file_self(dev, attr)) {
device_unregister(dev); device_unregister(dev);
...@@ -790,18 +790,17 @@ dcssblk_remove_store(struct device *dev, struct device_attribute *attr, const ch ...@@ -790,18 +790,17 @@ dcssblk_remove_store(struct device *dev, struct device_attribute *attr, const ch
} }
list_del(&dev_info->lh); list_del(&dev_info->lh);
/* unload all related segments */
list_for_each_entry(entry, &dev_info->seg_list, lh)
segment_unload(entry->segment_name);
up_write(&dcssblk_devices_sem);
dax_remove_host(dev_info->gd); dax_remove_host(dev_info->gd);
kill_dax(dev_info->dax_dev); kill_dax(dev_info->dax_dev);
put_dax(dev_info->dax_dev); put_dax(dev_info->dax_dev);
del_gendisk(dev_info->gd); del_gendisk(dev_info->gd);
put_disk(dev_info->gd); put_disk(dev_info->gd);
/* unload all related segments */
list_for_each_entry(entry, &dev_info->seg_list, lh)
segment_unload(entry->segment_name);
up_write(&dcssblk_devices_sem);
device_unregister(&dev_info->dev); device_unregister(&dev_info->dev);
put_device(&dev_info->dev); put_device(&dev_info->dev);
......
...@@ -111,7 +111,7 @@ static inline unsigned long mon_mca_end(struct mon_msg *monmsg) ...@@ -111,7 +111,7 @@ static inline unsigned long mon_mca_end(struct mon_msg *monmsg)
static inline u8 mon_mca_type(struct mon_msg *monmsg, u8 index) static inline u8 mon_mca_type(struct mon_msg *monmsg, u8 index)
{ {
return *((u8 *) mon_mca_start(monmsg) + monmsg->mca_offset + index); return *((u8 *)__va(mon_mca_start(monmsg)) + monmsg->mca_offset + index);
} }
static inline u32 mon_mca_size(struct mon_msg *monmsg) static inline u32 mon_mca_size(struct mon_msg *monmsg)
...@@ -121,12 +121,12 @@ static inline u32 mon_mca_size(struct mon_msg *monmsg) ...@@ -121,12 +121,12 @@ static inline u32 mon_mca_size(struct mon_msg *monmsg)
static inline u32 mon_rec_start(struct mon_msg *monmsg) static inline u32 mon_rec_start(struct mon_msg *monmsg)
{ {
return *((u32 *) (mon_mca_start(monmsg) + monmsg->mca_offset + 4)); return *((u32 *)(__va(mon_mca_start(monmsg)) + monmsg->mca_offset + 4));
} }
static inline u32 mon_rec_end(struct mon_msg *monmsg) static inline u32 mon_rec_end(struct mon_msg *monmsg)
{ {
return *((u32 *) (mon_mca_start(monmsg) + monmsg->mca_offset + 8)); return *((u32 *)(__va(mon_mca_start(monmsg)) + monmsg->mca_offset + 8));
} }
static int mon_check_mca(struct mon_msg *monmsg) static int mon_check_mca(struct mon_msg *monmsg)
...@@ -392,8 +392,7 @@ static ssize_t mon_read(struct file *filp, char __user *data, ...@@ -392,8 +392,7 @@ static ssize_t mon_read(struct file *filp, char __user *data,
mce_start = mon_mca_start(monmsg) + monmsg->mca_offset; mce_start = mon_mca_start(monmsg) + monmsg->mca_offset;
if ((monmsg->pos >= mce_start) && (monmsg->pos < mce_start + 12)) { if ((monmsg->pos >= mce_start) && (monmsg->pos < mce_start + 12)) {
count = min(count, (size_t) mce_start + 12 - monmsg->pos); count = min(count, (size_t) mce_start + 12 - monmsg->pos);
ret = copy_to_user(data, (void *) (unsigned long) monmsg->pos, ret = copy_to_user(data, __va(monmsg->pos), count);
count);
if (ret) if (ret)
return -EFAULT; return -EFAULT;
monmsg->pos += count; monmsg->pos += count;
...@@ -406,8 +405,7 @@ static ssize_t mon_read(struct file *filp, char __user *data, ...@@ -406,8 +405,7 @@ static ssize_t mon_read(struct file *filp, char __user *data,
if (monmsg->pos <= mon_rec_end(monmsg)) { if (monmsg->pos <= mon_rec_end(monmsg)) {
count = min(count, (size_t) mon_rec_end(monmsg) - monmsg->pos count = min(count, (size_t) mon_rec_end(monmsg) - monmsg->pos
+ 1); + 1);
ret = copy_to_user(data, (void *) (unsigned long) monmsg->pos, ret = copy_to_user(data, __va(monmsg->pos), count);
count);
if (ret) if (ret)
return -EFAULT; return -EFAULT;
monmsg->pos += count; monmsg->pos += count;
......
...@@ -49,8 +49,6 @@ int register_adapter_interrupt(struct airq_struct *airq) ...@@ -49,8 +49,6 @@ int register_adapter_interrupt(struct airq_struct *airq)
return -ENOMEM; return -ENOMEM;
airq->flags |= AIRQ_PTR_ALLOCATED; airq->flags |= AIRQ_PTR_ALLOCATED;
} }
if (!airq->lsi_mask)
airq->lsi_mask = 0xff;
snprintf(dbf_txt, sizeof(dbf_txt), "rairq:%p", airq); snprintf(dbf_txt, sizeof(dbf_txt), "rairq:%p", airq);
CIO_TRACE_EVENT(4, dbf_txt); CIO_TRACE_EVENT(4, dbf_txt);
isc_register(airq->isc); isc_register(airq->isc);
...@@ -98,7 +96,7 @@ static irqreturn_t do_airq_interrupt(int irq, void *dummy) ...@@ -98,7 +96,7 @@ static irqreturn_t do_airq_interrupt(int irq, void *dummy)
head = &airq_lists[tpi_info->isc]; head = &airq_lists[tpi_info->isc];
rcu_read_lock(); rcu_read_lock();
hlist_for_each_entry_rcu(airq, head, list) hlist_for_each_entry_rcu(airq, head, list)
if ((*airq->lsi_ptr & airq->lsi_mask) != 0) if (*airq->lsi_ptr != 0)
airq->handler(airq, tpi_info); airq->handler(airq, tpi_info);
rcu_read_unlock(); rcu_read_unlock();
......
...@@ -366,7 +366,6 @@ static int zcdn_create(const char *name) ...@@ -366,7 +366,6 @@ static int zcdn_create(const char *name)
{ {
dev_t devt; dev_t devt;
int i, rc = 0; int i, rc = 0;
char nodename[ZCDN_MAX_NAME];
struct zcdn_device *zcdndev; struct zcdn_device *zcdndev;
if (mutex_lock_interruptible(&ap_perms_mutex)) if (mutex_lock_interruptible(&ap_perms_mutex))
...@@ -407,13 +406,11 @@ static int zcdn_create(const char *name) ...@@ -407,13 +406,11 @@ static int zcdn_create(const char *name)
zcdndev->device.devt = devt; zcdndev->device.devt = devt;
zcdndev->device.groups = zcdn_dev_attr_groups; zcdndev->device.groups = zcdn_dev_attr_groups;
if (name[0]) if (name[0])
strncpy(nodename, name, sizeof(nodename)); rc = dev_set_name(&zcdndev->device, "%s", name);
else else
snprintf(nodename, sizeof(nodename), rc = dev_set_name(&zcdndev->device, ZCRYPT_NAME "_%d", (int)MINOR(devt));
ZCRYPT_NAME "_%d", (int)MINOR(devt)); if (rc) {
nodename[sizeof(nodename) - 1] = '\0'; kfree(zcdndev);
if (dev_set_name(&zcdndev->device, nodename)) {
rc = -EINVAL;
goto unlockout; goto unlockout;
} }
rc = device_register(&zcdndev->device); rc = device_register(&zcdndev->device);
......
...@@ -250,7 +250,6 @@ static struct airq_info *new_airq_info(int index) ...@@ -250,7 +250,6 @@ static struct airq_info *new_airq_info(int index)
info->airq.handler = virtio_airq_handler; info->airq.handler = virtio_airq_handler;
info->summary_indicator_idx = index; info->summary_indicator_idx = index;
info->airq.lsi_ptr = get_summary_indicator(info); info->airq.lsi_ptr = get_summary_indicator(info);
info->airq.lsi_mask = 0xff;
info->airq.isc = VIRTIO_AIRQ_ISC; info->airq.isc = VIRTIO_AIRQ_ISC;
rc = register_adapter_interrupt(&info->airq); rc = register_adapter_interrupt(&info->airq);
if (rc) { if (rc) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment