From d5e88d32de4e4ce289d107939da970763669d631 Mon Sep 17 00:00:00 2001 From: Sumanth Korikkar Date: Fri, 10 Oct 2025 10:51:44 +0200 Subject: [PATCH 01/92] s390/mm: Support removal of boot-allocated virtual memory map On s390, memory blocks are not currently removed via arch_remove_memory(). With upcoming dynamic memory (de)configuration support, runtime removal of memory blocks is possible. This internally involves tearing down identity mapping, virtual memory mappings and freeing the physical memory backing the struct pages metadata. During early boot, physical memory used to back the struct pages metadata in vmemmap is allocated through: setup_arch() -> sparse_init() -> sparse_init_nid() -> __populate_section_memmap() -> vmemmap_alloc_block_buf() -> sparse_buffer_alloc() -> memblock_alloc() Here, sparse_init_nid() sets up virtual-to-physical mapping for struct pages backed by memblock_alloc(). This differs from runtime addition of hotplug memory which uses the buddy allocator later. To correctly free identity mappings, vmemmap mappings during hot-remove, boot-time and runtime allocations must be distinguished using the PageReserved bit: * Boot-time memory, such as identity-mapped page tables allocated via boot_crst_alloc() and reserved via reserve_pgtables() is marked PageReserved in memmap_init_reserved_pages(). * Physical memory backing vmemmap (struct pages from memblock_alloc()) is also marked PageReserved similarly. During teardown, PageReserved bit is checked to distinguish between boot-time allocation or buddy allocation. This is similar to commit 645d5ce2f7d6 ("powerpc/mm/radix: Fix PTE/PMD fragment count for early page table mappings") Reviewed-by: Heiko Carstens Signed-off-by: Sumanth Korikkar Signed-off-by: Heiko Carstens --- arch/s390/mm/pgalloc.c | 2 ++ arch/s390/mm/vmem.c | 21 ++++++++++++--------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/arch/s390/mm/pgalloc.c b/arch/s390/mm/pgalloc.c index 626fca116cd7..7df23528c01b 100644 --- a/arch/s390/mm/pgalloc.c +++ b/arch/s390/mm/pgalloc.c @@ -164,6 +164,8 @@ void page_table_free(struct mm_struct *mm, unsigned long *table) { struct ptdesc *ptdesc = virt_to_ptdesc(table); + if (pagetable_is_reserved(ptdesc)) + return free_reserved_ptdesc(ptdesc); pagetable_dtor_free(ptdesc); } diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c index f48ef361bc83..d96587b84e81 100644 --- a/arch/s390/mm/vmem.c +++ b/arch/s390/mm/vmem.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include @@ -39,15 +40,21 @@ static void __ref *vmem_alloc_pages(unsigned int order) static void vmem_free_pages(unsigned long addr, int order, struct vmem_altmap *altmap) { + unsigned int nr_pages = 1 << order; + struct page *page; + if (altmap) { vmem_altmap_free(altmap, 1 << order); return; } - /* We don't expect boot memory to be removed ever. */ - if (!slab_is_available() || - WARN_ON_ONCE(PageReserved(virt_to_page((void *)addr)))) - return; - free_pages(addr, order); + page = virt_to_page((void *)addr); + if (PageReserved(page)) { + /* allocated from memblock */ + while (nr_pages--) + free_bootmem_page(page++); + } else { + free_pages(addr, order); + } } void *vmem_crst_alloc(unsigned long val) @@ -79,10 +86,6 @@ pte_t __ref *vmem_pte_alloc(void) static void vmem_pte_free(unsigned long *table) { - /* We don't expect boot memory to be removed ever. */ - if (!slab_is_available() || - WARN_ON_ONCE(PageReserved(virt_to_page(table)))) - return; page_table_free(&init_mm, table); } From ff18dcb19aab83edbe15b1a88ed9520d92e276f5 Mon Sep 17 00:00:00 2001 From: Sumanth Korikkar Date: Fri, 10 Oct 2025 10:51:45 +0200 Subject: [PATCH 02/92] s390/sclp: Add support for dynamic (de)configuration of memory Provide a new interface for dynamic configuration and deconfiguration of hotplug memory, allowing with/without memmap_on_memory support. It is a follow up on the discussion with David when introducing memmap_on_memory support for s390 and support dynamic (de)configuration of memory: https://lore.kernel.org/all/ee492da8-74b4-4a97-8b24-73e07257f01d@redhat.com/ https://lore.kernel.org/all/20241202082732.3959803-1-sumanthk@linux.ibm.com/ The original motivation for introducing memmap_on_memory on s390 was to avoid using online memory to store struct pages metadata, particularly for standby memory blocks. This became critical in cases where there was an imbalance between standby and online memory, potentially leading to boot failures due to insufficient memory for metadata allocation. To address this, memmap_on_memory was utilized on s390. However, in its current form, it adds struct pages metadata at the start of each memory block at the time of addition and this configuration is static. It cannot be changed at runtime. (When the user needs continuous physical memory). Inorder to provide more flexibility to the user and overcome the above limitation, add option to dynamically configure and deconfigure hotpluggable memory block with/without memmap_on_memory. With the new interface, s390 will not add all possible hotplug memory in advance, like before, to make it visible in sysfs for online/offline actions. Instead, before memory block can be set online, it has to be configured via a new interface in /sys/firmware/memory/memoryX/config, which makes s390 similar to others. i.e. Adding of hotpluggable memory is controlled by the user instead of adding it at boottime. The s390 kernel sysfs interface to configure and deconfigure memory is as follows (considering the upcoming lsmem changes): * Initial memory layout: lsmem -o RANGE,SIZE,STATE,BLOCK,CONFIGURED,MEMMAP_ON_MEMORY RANGE SIZE STATE BLOCK CONFIGURED MEMMAP_ON_MEMORY 0x00000000-0x7fffffff 2G online 0-15 yes no 0x80000000-0xffffffff 2G offline 16-31 no yes * Configure memory sys="/sys" echo 1 > $sys/firmware/memory/memory16/config lsmem -o RANGE,SIZE,STATE,BLOCK,CONFIGURED,MEMMAP_ON_MEMORY RANGE SIZE STATE BLOCK CONFIGURED MEMMAP_ON_MEMORY 0x00000000-0x7fffffff 2G online 0-15 yes no 0x80000000-0x87ffffff 128M offline 16 yes yes 0x88000000-0xffffffff 1.9G offline 17-31 no yes * Deconfigure memory echo 0 > $sys/firmware/memory/memory16/config lsmem -o RANGE,SIZE,STATE,BLOCK,CONFIGURED,MEMMAP_ON_MEMORY RANGE SIZE STATE BLOCK CONFIGURED MEMMAP_ON_MEMORY 0x00000000-0x7fffffff 2G online 0-15 yes no 0x80000000-0xffffffff 2G offline 16-31 no yes 3. Enable memmap_on_memory and online it. echo 0 > $sys/devices/system/memory/memory5/online echo 0 > $sys/firmware/memory/memory5/config lsmem -o RANGE,SIZE,STATE,BLOCK,CONFIGURED,MEMMAP_ON_MEMORY RANGE SIZE STATE BLOCK CONFIGURED MEMMAP_ON_MEMORY 0x00000000-0x27ffffff 640M online 0-4 yes no 0x28000000-0x2fffffff 128M offline 5 no no 0x30000000-0x7fffffff 1.3G online 6-15 yes no 0x80000000-0xffffffff 2G offline 16-31 no yes echo 1 > $sys/firmware/memory/memory5/memmap_on_memory echo 1 > $sys/firmware/memory/memory5/config echo 1 > $sys/devices/system/memory/memory5/online lsmem -o RANGE,SIZE,STATE,BLOCK,CONFIGURED,MEMMAP_ON_MEMORY RANGE SIZE STATE BLOCK CONFIGURED MEMMAP_ON_MEMORY 0x00000000-0x27ffffff 640M online 0-4 yes no 0x28000000-0x2fffffff 128M online 5 yes yes 0x30000000-0x7fffffff 1.3G online 6-15 yes no 0x80000000-0xffffffff 2G offline 16-31 no yes 4. Disable memmap_on_memory and online it. echo 0 > $sys/devices/system/memory/memory5/online echo 0 > $sys/firmware/memory/memory5/config lsmem -o RANGE,SIZE,STATE,BLOCK,CONFIGURED,MEMMAP_ON_MEMORY RANGE SIZE STATE BLOCK CONFIGURED MEMMAP_ON_MEMORY 0x00000000-0x27ffffff 640M online 0-4 yes no 0x28000000-0x2fffffff 128M offline 5 no yes 0x30000000-0x7fffffff 1.3G online 6-15 yes no 0x80000000-0xffffffff 2G offline 16-31 no yes echo 0 > $sys/firmware/memory/memory5/memmap_on_memory echo 1 > $sys/firmware/memory/memory5/config echo 1 > $sys/devices/system/memory/memory5/online lsmem -o RANGE,SIZE,STATE,BLOCK,CONFIGURED,MEMMAP_ON_MEMORY RANGE SIZE STATE BLOCK CONFIGURED MEMMAP_ON_MEMORY 0x00000000-0x7fffffff 2G online 0-15 yes no 0x80000000-0xffffffff 2G offline 16-31 no yes Acked-by: Heiko Carstens Acked-by: David Hildenbrand Signed-off-by: Sumanth Korikkar Signed-off-by: Heiko Carstens --- drivers/s390/char/sclp_mem.c | 287 +++++++++++++++++++++++++---------- 1 file changed, 204 insertions(+), 83 deletions(-) diff --git a/drivers/s390/char/sclp_mem.c b/drivers/s390/char/sclp_mem.c index 27f49f5fd358..100d776bdffe 100644 --- a/drivers/s390/char/sclp_mem.c +++ b/drivers/s390/char/sclp_mem.c @@ -9,9 +9,12 @@ #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt #include +#include #include #include #include +#include +#include #include #include #include @@ -27,7 +30,6 @@ #define SCLP_CMDW_ASSIGN_STORAGE 0x000d0001 #define SCLP_CMDW_UNASSIGN_STORAGE 0x000c0001 -static DEFINE_MUTEX(sclp_mem_mutex); static LIST_HEAD(sclp_mem_list); static u8 sclp_max_storage_id; static DECLARE_BITMAP(sclp_storage_ids, 256); @@ -38,6 +40,18 @@ struct memory_increment { int standby; }; +struct sclp_mem { + struct kobject kobj; + unsigned int id; + unsigned int memmap_on_memory; + unsigned int config; +}; + +struct sclp_mem_arg { + struct sclp_mem *sclp_mems; + struct kset *kset; +}; + struct assign_storage_sccb { struct sccb_header header; u16 rn; @@ -163,92 +177,166 @@ static int sclp_mem_change_state(unsigned long start, unsigned long size, return rc ? -EIO : 0; } -static bool contains_standby_increment(unsigned long start, unsigned long end) +static ssize_t sclp_config_mem_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { - struct memory_increment *incr; - unsigned long istart; + struct sclp_mem *sclp_mem = container_of(kobj, struct sclp_mem, kobj); - list_for_each_entry(incr, &sclp_mem_list, list) { - istart = rn2addr(incr->rn); - if (end - 1 < istart) - continue; - if (start > istart + sclp.rzm - 1) - continue; - if (incr->standby) - return true; - } - return false; + return sysfs_emit(buf, "%u\n", READ_ONCE(sclp_mem->config)); } -static int sclp_mem_notifier(struct notifier_block *nb, - unsigned long action, void *data) +static ssize_t sclp_config_mem_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) { - unsigned long start, size; - struct memory_notify *arg; + unsigned long addr, block_size; + struct sclp_mem *sclp_mem; + struct memory_block *mem; unsigned char id; - int rc = 0; + bool value; + int rc; - arg = data; - start = arg->start_pfn << PAGE_SHIFT; - size = arg->nr_pages << PAGE_SHIFT; - mutex_lock(&sclp_mem_mutex); + rc = kstrtobool(buf, &value); + if (rc) + return rc; + sclp_mem = container_of(kobj, struct sclp_mem, kobj); + block_size = memory_block_size_bytes(); + addr = sclp_mem->id * block_size; + /* + * Hold device_hotplug_lock when adding/removing memory blocks. + * Additionally, also protect calls to find_memory_block() and + * sclp_attach_storage(). + */ + rc = lock_device_hotplug_sysfs(); + if (rc) + goto out; for_each_clear_bit(id, sclp_storage_ids, sclp_max_storage_id + 1) sclp_attach_storage(id); - switch (action) { - case MEM_GOING_OFFLINE: + if (value) { + if (sclp_mem->config) + goto out_unlock; + rc = sclp_mem_change_state(addr, block_size, 1); + if (rc) + goto out_unlock; /* - * Do not allow to set memory blocks offline that contain - * standby memory. This is done to simplify the "memory online" - * case. + * Set entire memory block CMMA state to nodat. Later, when + * page tables pages are allocated via __add_memory(), those + * regions are marked __arch_set_page_dat(). */ - if (contains_standby_increment(start, start + size)) - rc = -EPERM; - break; - case MEM_PREPARE_ONLINE: - /* - * Access the altmap_start_pfn and altmap_nr_pages fields - * within the struct memory_notify specifically when dealing - * with only MEM_PREPARE_ONLINE/MEM_FINISH_OFFLINE notifiers. - * - * When altmap is in use, take the specified memory range - * online, which includes the altmap. - */ - if (arg->altmap_nr_pages) { - start = PFN_PHYS(arg->altmap_start_pfn); - size += PFN_PHYS(arg->altmap_nr_pages); + __arch_set_page_nodat((void *)__va(addr), block_size >> PAGE_SHIFT); + rc = __add_memory(0, addr, block_size, + sclp_mem->memmap_on_memory ? + MHP_MEMMAP_ON_MEMORY | MHP_OFFLINE_INACCESSIBLE : MHP_NONE); + if (rc) { + sclp_mem_change_state(addr, block_size, 0); + goto out_unlock; } - rc = sclp_mem_change_state(start, size, 1); - if (rc || !arg->altmap_nr_pages) - break; - /* - * Set CMMA state to nodat here, since the struct page memory - * at the beginning of the memory block will not go through the - * buddy allocator later. - */ - __arch_set_page_nodat((void *)__va(start), arg->altmap_nr_pages); - break; - case MEM_FINISH_OFFLINE: - /* - * When altmap is in use, take the specified memory range - * offline, which includes the altmap. - */ - if (arg->altmap_nr_pages) { - start = PFN_PHYS(arg->altmap_start_pfn); - size += PFN_PHYS(arg->altmap_nr_pages); + mem = find_memory_block(pfn_to_section_nr(PFN_DOWN(addr))); + put_device(&mem->dev); + WRITE_ONCE(sclp_mem->config, 1); + } else { + if (!sclp_mem->config) + goto out_unlock; + mem = find_memory_block(pfn_to_section_nr(PFN_DOWN(addr))); + if (mem->state != MEM_OFFLINE) { + put_device(&mem->dev); + rc = -EBUSY; + goto out_unlock; } - sclp_mem_change_state(start, size, 0); - break; - default: - break; + /* drop the ref just got via find_memory_block() */ + put_device(&mem->dev); + sclp_mem_change_state(addr, block_size, 0); + __remove_memory(addr, block_size); + WRITE_ONCE(sclp_mem->config, 0); } - mutex_unlock(&sclp_mem_mutex); - return rc ? NOTIFY_BAD : NOTIFY_OK; +out_unlock: + unlock_device_hotplug(); +out: + return rc ? rc : count; } -static struct notifier_block sclp_mem_nb = { - .notifier_call = sclp_mem_notifier, +static struct kobj_attribute sclp_config_mem_attr = + __ATTR(config, 0644, sclp_config_mem_show, sclp_config_mem_store); + +static ssize_t sclp_memmap_on_memory_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + struct sclp_mem *sclp_mem = container_of(kobj, struct sclp_mem, kobj); + + return sysfs_emit(buf, "%u\n", READ_ONCE(sclp_mem->memmap_on_memory)); +} + +static ssize_t sclp_memmap_on_memory_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) +{ + struct sclp_mem *sclp_mem; + unsigned long block_size; + struct memory_block *mem; + bool value; + int rc; + + rc = kstrtobool(buf, &value); + if (rc) + return rc; + rc = lock_device_hotplug_sysfs(); + if (rc) + return rc; + block_size = memory_block_size_bytes(); + sclp_mem = container_of(kobj, struct sclp_mem, kobj); + mem = find_memory_block(pfn_to_section_nr(PFN_DOWN(sclp_mem->id * block_size))); + if (!mem) { + WRITE_ONCE(sclp_mem->memmap_on_memory, value); + } else { + put_device(&mem->dev); + rc = -EBUSY; + } + unlock_device_hotplug(); + return rc ? rc : count; +} + +static const struct kobj_type ktype = { + .sysfs_ops = &kobj_sysfs_ops, }; +static struct kobj_attribute sclp_memmap_attr = + __ATTR(memmap_on_memory, 0644, sclp_memmap_on_memory_show, sclp_memmap_on_memory_store); + +static struct attribute *sclp_mem_attrs[] = { + &sclp_config_mem_attr.attr, + &sclp_memmap_attr.attr, + NULL, +}; + +static struct attribute_group sclp_mem_attr_group = { + .attrs = sclp_mem_attrs, +}; + +static int sclp_create_mem(struct sclp_mem *sclp_mem, struct kset *kset, + unsigned int id, bool config, bool memmap_on_memory) +{ + int rc; + + sclp_mem->memmap_on_memory = memmap_on_memory; + sclp_mem->config = config; + sclp_mem->id = id; + kobject_init(&sclp_mem->kobj, &ktype); + rc = kobject_add(&sclp_mem->kobj, &kset->kobj, "memory%d", id); + if (rc) + return rc; + return sysfs_create_group(&sclp_mem->kobj, &sclp_mem_attr_group); +} + +static int sclp_create_configured_mem(struct memory_block *mem, void *argument) +{ + struct sclp_mem *sclp_mems; + struct sclp_mem_arg *arg; + struct kset *kset; + unsigned int id; + + id = mem->dev.id; + arg = (struct sclp_mem_arg *)argument; + sclp_mems = arg->sclp_mems; + kset = arg->kset; + return sclp_create_mem(&sclp_mems[id], kset, id, true, false); +} + static void __init align_to_block_size(unsigned long *start, unsigned long *size, unsigned long alignment) @@ -264,14 +352,17 @@ static void __init align_to_block_size(unsigned long *start, *size = size_align; } -static void __init add_memory_merged(u16 rn) +static int __init sclp_create_standby_mems_merged(struct sclp_mem *sclp_mems, + struct kset *kset, u16 rn) { unsigned long start, size, addr, block_size; static u16 first_rn, num; + unsigned int id; + int rc = 0; if (rn && first_rn && (first_rn + num == rn)) { num++; - return; + return rc; } if (!first_rn) goto skip_add; @@ -286,24 +377,57 @@ static void __init add_memory_merged(u16 rn) if (!size) goto skip_add; for (addr = start; addr < start + size; addr += block_size) { - add_memory(0, addr, block_size, - cpu_has_edat1() ? - MHP_MEMMAP_ON_MEMORY | MHP_OFFLINE_INACCESSIBLE : MHP_NONE); + id = addr / block_size; + rc = sclp_create_mem(&sclp_mems[id], kset, id, false, + mhp_supports_memmap_on_memory()); + if (rc) + break; } skip_add: first_rn = rn; num = 1; + return rc; } -static void __init sclp_add_standby_memory(void) +static int __init sclp_create_standby_mems(struct sclp_mem *sclp_mems, struct kset *kset) { struct memory_increment *incr; + int rc = 0; list_for_each_entry(incr, &sclp_mem_list, list) { if (incr->standby) - add_memory_merged(incr->rn); + rc = sclp_create_standby_mems_merged(sclp_mems, kset, incr->rn); + if (rc) + return rc; } - add_memory_merged(0); + return sclp_create_standby_mems_merged(sclp_mems, kset, 0); +} + +static int __init sclp_init_mem(void) +{ + const unsigned long block_size = memory_block_size_bytes(); + unsigned int max_sclp_mems; + struct sclp_mem *sclp_mems; + struct sclp_mem_arg arg; + struct kset *kset; + int rc; + + max_sclp_mems = roundup(sclp.rnmax * sclp.rzm, block_size) / block_size; + /* Allocate memory for all blocks ahead of time. */ + sclp_mems = kcalloc(max_sclp_mems, sizeof(struct sclp_mem), GFP_KERNEL); + if (!sclp_mems) + return -ENOMEM; + kset = kset_create_and_add("memory", NULL, firmware_kobj); + if (!kset) + return -ENOMEM; + /* Initial memory is in the "configured" state already. */ + arg.sclp_mems = sclp_mems; + arg.kset = kset; + rc = for_each_memory_block(&arg, sclp_create_configured_mem); + if (rc) + return rc; + /* Standby memory is "deconfigured". */ + return sclp_create_standby_mems(sclp_mems, kset); } static void __init insert_increment(u16 rn, int standby, int assigned) @@ -336,7 +460,7 @@ static void __init insert_increment(u16 rn, int standby, int assigned) list_add(&new_incr->list, prev); } -static int __init sclp_detect_standby_memory(void) +static int __init sclp_setup_memory(void) { struct read_storage_sccb *sccb; int i, id, assigned, rc; @@ -388,12 +512,9 @@ static int __init sclp_detect_standby_memory(void) goto out; for (i = 1; i <= sclp.rnmax - assigned; i++) insert_increment(0, 1, 0); - rc = register_memory_notifier(&sclp_mem_nb); - if (rc) - goto out; - sclp_add_standby_memory(); + rc = sclp_init_mem(); out: free_page((unsigned long)sccb); return rc; } -__initcall(sclp_detect_standby_memory); +__initcall(sclp_setup_memory); From ce2071e02d84a133c2985e80f5a84473642de983 Mon Sep 17 00:00:00 2001 From: Sumanth Korikkar Date: Fri, 10 Oct 2025 10:51:46 +0200 Subject: [PATCH 03/92] s390/sclp: Remove MHP_OFFLINE_INACCESSIBLE mhp_flag MHP_OFFLINE_INACCESSIBLE was used to mark memory as not accessible until memory hotplug online phase begins. Earlier, standby memory blocks were added upfront during boottime and MHP_OFFLINE_INACCESSIBLE flag avoided page_init_poison() on memmap during mhp addition phase. However with dynamic runtime configuration of memory, standby memory can be brought to accessible state before performing add_memory(). Hence, remove MHP_OFFLINE_INACCESSIBLE. Acked-by: Heiko Carstens Reviewed-by: David Hildenbrand Signed-off-by: Sumanth Korikkar Signed-off-by: Heiko Carstens --- drivers/s390/char/sclp_mem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/s390/char/sclp_mem.c b/drivers/s390/char/sclp_mem.c index 100d776bdffe..3a7a69615d99 100644 --- a/drivers/s390/char/sclp_mem.c +++ b/drivers/s390/char/sclp_mem.c @@ -224,7 +224,7 @@ static ssize_t sclp_config_mem_store(struct kobject *kobj, struct kobj_attribute __arch_set_page_nodat((void *)__va(addr), block_size >> PAGE_SHIFT); rc = __add_memory(0, addr, block_size, sclp_mem->memmap_on_memory ? - MHP_MEMMAP_ON_MEMORY | MHP_OFFLINE_INACCESSIBLE : MHP_NONE); + MHP_MEMMAP_ON_MEMORY : MHP_NONE); if (rc) { sclp_mem_change_state(addr, block_size, 0); goto out_unlock; From 300709fbefd19ff7293c7d0ded9b56e69216e634 Mon Sep 17 00:00:00 2001 From: Sumanth Korikkar Date: Fri, 10 Oct 2025 10:51:47 +0200 Subject: [PATCH 04/92] mm/memory_hotplug: Remove MEM_PREPARE_ONLINE/MEM_FINISH_OFFLINE notifiers MEM_PREPARE_ONLINE/MEM_FINISH_OFFLINE memory notifiers were introduced to prepare the transition of memory to and from a physically accessible state. This enhancement was crucial for implementing the "memmap on memory" feature for s390. With introduction of dynamic (de)configuration of hotpluggable memory, memory can be brought to accessible state before add_memory(). Memory can be brought to inaccessible state before remove_memory(). Hence, there is no need of MEM_PREPARE_ONLINE/MEM_FINISH_OFFLINE memory notifiers anymore. This basically reverts commit c5f1e2d18909 ("mm/memory_hotplug: introduce MEM_PREPARE_ONLINE/MEM_FINISH_OFFLINE notifiers") Additionally, apply minor adjustments to the function parameters of move_pfn_range_to_zone() and mhp_supports_memmap_on_memory() to ensure compatibility with the latest branch. Acked-by: David Hildenbrand Signed-off-by: Sumanth Korikkar Signed-off-by: Heiko Carstens --- drivers/base/memory.c | 23 +---------------------- include/linux/memory.h | 9 --------- include/linux/memory_hotplug.h | 18 +----------------- include/linux/memremap.h | 1 - mm/memory_hotplug.c | 17 +++-------------- mm/sparse.c | 3 +-- 6 files changed, 6 insertions(+), 65 deletions(-) diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 6d84a02cfa5d..fc43f2703ae0 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -226,7 +226,6 @@ static int memory_block_online(struct memory_block *mem) unsigned long start_pfn = section_nr_to_pfn(mem->start_section_nr); unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block; unsigned long nr_vmemmap_pages = 0; - struct memory_notify arg; struct zone *zone; int ret; @@ -246,19 +245,9 @@ static int memory_block_online(struct memory_block *mem) if (mem->altmap) nr_vmemmap_pages = mem->altmap->free; - arg.altmap_start_pfn = start_pfn; - arg.altmap_nr_pages = nr_vmemmap_pages; - arg.start_pfn = start_pfn + nr_vmemmap_pages; - arg.nr_pages = nr_pages - nr_vmemmap_pages; mem_hotplug_begin(); - ret = memory_notify(MEM_PREPARE_ONLINE, &arg); - ret = notifier_to_errno(ret); - if (ret) - goto out_notifier; - if (nr_vmemmap_pages) { - ret = mhp_init_memmap_on_memory(start_pfn, nr_vmemmap_pages, - zone, mem->altmap->inaccessible); + ret = mhp_init_memmap_on_memory(start_pfn, nr_vmemmap_pages, zone); if (ret) goto out; } @@ -280,11 +269,7 @@ static int memory_block_online(struct memory_block *mem) nr_vmemmap_pages); mem->zone = zone; - mem_hotplug_done(); - return ret; out: - memory_notify(MEM_FINISH_OFFLINE, &arg); -out_notifier: mem_hotplug_done(); return ret; } @@ -297,7 +282,6 @@ static int memory_block_offline(struct memory_block *mem) unsigned long start_pfn = section_nr_to_pfn(mem->start_section_nr); unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block; unsigned long nr_vmemmap_pages = 0; - struct memory_notify arg; int ret; if (!mem->zone) @@ -329,11 +313,6 @@ static int memory_block_offline(struct memory_block *mem) mhp_deinit_memmap_on_memory(start_pfn, nr_vmemmap_pages); mem->zone = NULL; - arg.altmap_start_pfn = start_pfn; - arg.altmap_nr_pages = nr_vmemmap_pages; - arg.start_pfn = start_pfn + nr_vmemmap_pages; - arg.nr_pages = nr_pages - nr_vmemmap_pages; - memory_notify(MEM_FINISH_OFFLINE, &arg); out: mem_hotplug_done(); return ret; diff --git a/include/linux/memory.h b/include/linux/memory.h index 0c214256216f..ba1515160894 100644 --- a/include/linux/memory.h +++ b/include/linux/memory.h @@ -96,17 +96,8 @@ int set_memory_block_size_order(unsigned int order); #define MEM_GOING_ONLINE (1<<3) #define MEM_CANCEL_ONLINE (1<<4) #define MEM_CANCEL_OFFLINE (1<<5) -#define MEM_PREPARE_ONLINE (1<<6) -#define MEM_FINISH_OFFLINE (1<<7) struct memory_notify { - /* - * The altmap_start_pfn and altmap_nr_pages fields are designated for - * specifying the altmap range and are exclusively intended for use in - * MEM_PREPARE_ONLINE/MEM_FINISH_OFFLINE notifiers. - */ - unsigned long altmap_start_pfn; - unsigned long altmap_nr_pages; unsigned long start_pfn; unsigned long nr_pages; }; diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h index 23f038a16231..f2f16cdd73ee 100644 --- a/include/linux/memory_hotplug.h +++ b/include/linux/memory_hotplug.h @@ -58,22 +58,6 @@ typedef int __bitwise mhp_t; * implies the node id (nid). */ #define MHP_NID_IS_MGID ((__force mhp_t)BIT(2)) -/* - * The hotplugged memory is completely inaccessible while the memory is - * offline. The memory provider will handle MEM_PREPARE_ONLINE / - * MEM_FINISH_OFFLINE notifications and make the memory accessible. - * - * This flag is only relevant when used along with MHP_MEMMAP_ON_MEMORY, - * because the altmap cannot be written (e.g., poisoned) when adding - * memory -- before it is set online. - * - * This allows for adding memory with an altmap that is not currently - * made available by a hypervisor. When onlining that memory, the - * hypervisor can be instructed to make that memory available, and - * the onlining phase will not require any memory allocations, which is - * helpful in low-memory situations. - */ -#define MHP_OFFLINE_INACCESSIBLE ((__force mhp_t)BIT(3)) /* * Extended parameters for memory hotplug: @@ -123,7 +107,7 @@ extern void adjust_present_page_count(struct page *page, long nr_pages); /* VM interface that may be used by firmware interface */ extern int mhp_init_memmap_on_memory(unsigned long pfn, unsigned long nr_pages, - struct zone *zone, bool mhp_off_inaccessible); + struct zone *zone); extern void mhp_deinit_memmap_on_memory(unsigned long pfn, unsigned long nr_pages); extern int online_pages(unsigned long pfn, unsigned long nr_pages, struct zone *zone, struct memory_group *group); diff --git a/include/linux/memremap.h b/include/linux/memremap.h index e5951ba12a28..30c7aecbd245 100644 --- a/include/linux/memremap.h +++ b/include/linux/memremap.h @@ -25,7 +25,6 @@ struct vmem_altmap { unsigned long free; unsigned long align; unsigned long alloc; - bool inaccessible; }; /* diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 0be83039c3b5..238a6712738e 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -1088,7 +1088,7 @@ void adjust_present_page_count(struct page *page, struct memory_group *group, } int mhp_init_memmap_on_memory(unsigned long pfn, unsigned long nr_pages, - struct zone *zone, bool mhp_off_inaccessible) + struct zone *zone) { unsigned long end_pfn = pfn + nr_pages; int ret, i; @@ -1097,15 +1097,6 @@ int mhp_init_memmap_on_memory(unsigned long pfn, unsigned long nr_pages, if (ret) return ret; - /* - * Memory block is accessible at this stage and hence poison the struct - * pages now. If the memory block is accessible during memory hotplug - * addition phase, then page poisining is already performed in - * sparse_add_section(). - */ - if (mhp_off_inaccessible) - page_init_poison(pfn_to_page(pfn), sizeof(struct page) * nr_pages); - move_pfn_range_to_zone(zone, pfn, nr_pages, NULL, MIGRATE_UNMOVABLE, false); @@ -1444,7 +1435,7 @@ static void remove_memory_blocks_and_altmaps(u64 start, u64 size) } static int create_altmaps_and_memory_blocks(int nid, struct memory_group *group, - u64 start, u64 size, mhp_t mhp_flags) + u64 start, u64 size) { unsigned long memblock_size = memory_block_size_bytes(); u64 cur_start; @@ -1460,8 +1451,6 @@ static int create_altmaps_and_memory_blocks(int nid, struct memory_group *group, }; mhp_altmap.free = memory_block_memmap_on_memory_pages(); - if (mhp_flags & MHP_OFFLINE_INACCESSIBLE) - mhp_altmap.inaccessible = true; params.altmap = kmemdup(&mhp_altmap, sizeof(struct vmem_altmap), GFP_KERNEL); if (!params.altmap) { @@ -1555,7 +1544,7 @@ int add_memory_resource(int nid, struct resource *res, mhp_t mhp_flags) */ if ((mhp_flags & MHP_MEMMAP_ON_MEMORY) && mhp_supports_memmap_on_memory()) { - ret = create_altmaps_and_memory_blocks(nid, group, start, size, mhp_flags); + ret = create_altmaps_and_memory_blocks(nid, group, start, size); if (ret) goto error; } else { diff --git a/mm/sparse.c b/mm/sparse.c index 17c50a6415c2..b5b2b6f7041b 100644 --- a/mm/sparse.c +++ b/mm/sparse.c @@ -951,8 +951,7 @@ int __meminit sparse_add_section(int nid, unsigned long start_pfn, * Poison uninitialized struct pages in order to catch invalid flags * combinations. */ - if (!altmap || !altmap->inaccessible) - page_init_poison(memmap, sizeof(struct page) * nr_pages); + page_init_poison(memmap, sizeof(struct page) * nr_pages); ms = __nr_to_section(section_nr); set_section_nid(section_nr, nid); From dd7d1d34ae484ba2caed8e01e03bdc4c263b1442 Mon Sep 17 00:00:00 2001 From: Josephine Pfeiffer Date: Wed, 1 Oct 2025 18:36:22 +0200 Subject: [PATCH 05/92] s390/cmm: Replace sprintf() with scnprintf() for buffer safety Replace sprintf() with scnprintf() in cmm_timeout_handler() to prevent potential buffer overflow. The scnprintf() function ensures we don't write beyond the buffer size and provides safer string formatting. Signed-off-by: Josephine Pfeiffer Signed-off-by: Heiko Carstens --- arch/s390/mm/cmm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c index e2a6eb92420f..eb7ef63fab1e 100644 --- a/arch/s390/mm/cmm.c +++ b/arch/s390/mm/cmm.c @@ -321,8 +321,8 @@ static int cmm_timeout_handler(const struct ctl_table *ctl, int write, cmm_set_timeout(nr, seconds); *ppos += *lenp; } else { - len = sprintf(buf, "%ld %ld\n", - cmm_timeout_pages, cmm_timeout_seconds); + len = scnprintf(buf, sizeof(buf), "%ld %ld\n", + cmm_timeout_pages, cmm_timeout_seconds); if (len > *lenp) len = *lenp; memcpy(buffer, buf, len); From 5379879a76e25998d56c2136fef7d67eae33418f Mon Sep 17 00:00:00 2001 From: Josephine Pfeiffer Date: Wed, 1 Oct 2025 21:14:04 +0200 Subject: [PATCH 06/92] s390/extmem: Replace sprintf() with snprintf() for buffer safety Replace unsafe sprintf() calls with snprintf() in segment_save() to prevent potential buffer overflows. The function builds command strings by repeatedly appending to a fixed-size buffer, which could overflow if segment ranges are numerous or values are large. Signed-off-by: Josephine Pfeiffer Signed-off-by: Heiko Carstens --- arch/s390/mm/extmem.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c index f7da53e212f5..b6464a322eb1 100644 --- a/arch/s390/mm/extmem.c +++ b/arch/s390/mm/extmem.c @@ -598,14 +598,16 @@ segment_save(char *name) goto out; } - sprintf(cmd1, "DEFSEG %s", name); + snprintf(cmd1, sizeof(cmd1), "DEFSEG %s", name); for (i=0; isegcnt; i++) { - sprintf(cmd1+strlen(cmd1), " %lX-%lX %s", - seg->range[i].start >> PAGE_SHIFT, - seg->range[i].end >> PAGE_SHIFT, - segtype_string[seg->range[i].start & 0xff]); + size_t len = strlen(cmd1); + + snprintf(cmd1 + len, sizeof(cmd1) - len, " %lX-%lX %s", + seg->range[i].start >> PAGE_SHIFT, + seg->range[i].end >> PAGE_SHIFT, + segtype_string[seg->range[i].start & 0xff]); } - sprintf(cmd2, "SAVESEG %s", name); + snprintf(cmd2, sizeof(cmd2), "SAVESEG %s", name); response = 0; cpcmd(cmd1, NULL, 0, &response); if (response) { From 4738e1166260fd812faf5fef624b0f9308d8c4d4 Mon Sep 17 00:00:00 2001 From: Josephine Pfeiffer Date: Wed, 1 Oct 2025 19:41:04 +0200 Subject: [PATCH 07/92] s390/sysinfo: Replace sprintf() with snprintf() for buffer safety Replace sprintf() with snprintf() when formatting symlink target name to prevent potential buffer overflow. The link_to buffer is only 10 bytes, and using snprintf() ensures proper bounds checking if the topology nesting limit value is unexpectedly large. Signed-off-by: Josephine Pfeiffer Signed-off-by: Heiko Carstens --- arch/s390/kernel/sysinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/kernel/sysinfo.c b/arch/s390/kernel/sysinfo.c index 1ea84e942bd4..33ca3e47a0e6 100644 --- a/arch/s390/kernel/sysinfo.c +++ b/arch/s390/kernel/sysinfo.c @@ -526,7 +526,7 @@ static __init int stsi_init_debugfs(void) if (IS_ENABLED(CONFIG_SCHED_TOPOLOGY) && cpu_has_topology()) { char link_to[10]; - sprintf(link_to, "15_1_%d", topology_mnest_limit()); + snprintf(link_to, sizeof(link_to), "15_1_%d", topology_mnest_limit()); debugfs_create_symlink("topology", stsi_root, link_to); } return 0; From 4d065f3c80cc6c20437c75bec841eacc9488e360 Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Wed, 8 Oct 2025 09:00:21 +0200 Subject: [PATCH 08/92] s390/pai_crypto: Adjust paicrypt_copy() return statement Adjust the return statement in paicrypt_copy() to the same statement as in paiext_copy(). Use one common style. No functional change. Signed-off-by: Thomas Richter Reviewed-by: Jan Polensky Signed-off-by: Heiko Carstens --- arch/s390/kernel/perf_pai_crypto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/kernel/perf_pai_crypto.c b/arch/s390/kernel/perf_pai_crypto.c index 62bf8a15bf32..9b06b8a83342 100644 --- a/arch/s390/kernel/perf_pai_crypto.c +++ b/arch/s390/kernel/perf_pai_crypto.c @@ -428,7 +428,7 @@ static size_t paicrypt_copy(struct pai_userdata *userdata, unsigned long *page, outidx++; } } - return outidx * sizeof(struct pai_userdata); + return outidx * sizeof(*userdata); } static int paicrypt_push_sample(size_t rawsize, struct paicrypt_map *cpump, From 68502211161d56e5d4185e4953648e02351dc633 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 7 Oct 2025 11:05:01 +0200 Subject: [PATCH 09/92] s390/early: Use scnprintf() instead of sprintf() Use scnprintf() instead of sprintf() for those cases where the destination is an array and the size of the array is known at compile time. This prevents theoretical buffer overflows, but also avoids that people again and again spend time to figure out if the code is actually safe. Reviewed-by: Jan Polensky Signed-off-by: Heiko Carstens --- arch/s390/kernel/early.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index 544e5403dd91..f4cab46a3e66 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c @@ -120,21 +120,21 @@ static noinline __init void setup_arch_string(void) EBCASC(mach->type, sizeof(mach->type)); EBCASC(mach->model, sizeof(mach->model)); EBCASC(mach->model_capacity, sizeof(mach->model_capacity)); - sprintf(mstr, "%-16.16s %-4.4s %-16.16s %-16.16s", - mach->manufacturer, mach->type, - mach->model, mach->model_capacity); + scnprintf(mstr, sizeof(mstr), "%-16.16s %-4.4s %-16.16s %-16.16s", + mach->manufacturer, mach->type, + mach->model, mach->model_capacity); strim_all(mstr); if (stsi(vm, 3, 2, 2) == 0 && vm->count) { EBCASC(vm->vm[0].cpi, sizeof(vm->vm[0].cpi)); - sprintf(hvstr, "%-16.16s", vm->vm[0].cpi); + scnprintf(hvstr, sizeof(hvstr), "%-16.16s", vm->vm[0].cpi); strim_all(hvstr); } else { - sprintf(hvstr, "%s", - machine_is_lpar() ? "LPAR" : - machine_is_vm() ? "z/VM" : - machine_is_kvm() ? "KVM" : "unknown"); + scnprintf(hvstr, sizeof(hvstr), "%s", + machine_is_lpar() ? "LPAR" : + machine_is_vm() ? "z/VM" : + machine_is_kvm() ? "KVM" : "unknown"); } - sprintf(arch_hw_string, "HW: %s (%s)", mstr, hvstr); + scnprintf(arch_hw_string, sizeof(arch_hw_string), "HW: %s (%s)", mstr, hvstr); dump_stack_set_arch_desc("%s (%s)", mstr, hvstr); } From ba06238bbe6a8697e281e2839fc54bcec45ae143 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 7 Oct 2025 11:05:02 +0200 Subject: [PATCH 10/92] s390/cio: Use scnprintf() instead of sprintf() Use scnprintf() instead of sprintf() for those cases where the destination is an array and the size of the array is known at compile time. This prevents theoretical buffer overflows, but also avoids that people again and again spend time to figure out if the code is actually safe. Reviewed-by: Jan Polensky Signed-off-by: Heiko Carstens --- drivers/s390/cio/ccwgroup.c | 6 +++--- drivers/s390/cio/chp.c | 5 +++-- drivers/s390/cio/chsc.c | 10 +++++----- drivers/s390/cio/cio.c | 2 +- drivers/s390/cio/device_status.c | 2 +- 5 files changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index 2fc2ea4b2e3b..185c99c5d4cc 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c @@ -41,7 +41,7 @@ static void __ccwgroup_remove_symlinks(struct ccwgroup_device *gdev) char str[16]; for (i = 0; i < gdev->count; i++) { - sprintf(str, "cdev%d", i); + scnprintf(str, sizeof(str), "cdev%d", i); sysfs_remove_link(&gdev->dev.kobj, str); sysfs_remove_link(&gdev->cdev[i]->dev.kobj, "group_device"); } @@ -249,12 +249,12 @@ static int __ccwgroup_create_symlinks(struct ccwgroup_device *gdev) } } for (i = 0; i < gdev->count; i++) { - sprintf(str, "cdev%d", i); + scnprintf(str, sizeof(str), "cdev%d", i); rc = sysfs_create_link(&gdev->dev.kobj, &gdev->cdev[i]->dev.kobj, str); if (rc) { while (i--) { - sprintf(str, "cdev%d", i); + scnprintf(str, sizeof(str), "cdev%d", i); sysfs_remove_link(&gdev->dev.kobj, str); } for (i = 0; i < gdev->count; i++) diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c index caa300160b17..c10e2444507e 100644 --- a/drivers/s390/cio/chp.c +++ b/drivers/s390/cio/chp.c @@ -111,8 +111,9 @@ static int s390_vary_chpid(struct chp_id chpid, int on) char dbf_text[15]; int status; - sprintf(dbf_text, on?"varyon%x.%02x":"varyoff%x.%02x", chpid.cssid, - chpid.id); + scnprintf(dbf_text, sizeof(dbf_text), + on ? "varyon%x.%02x" : "varyoff%x.%02x", + chpid.cssid, chpid.id); CIO_TRACE_EVENT(2, dbf_text); status = chp_get_status(chpid); diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index 239c92d4ec11..edebb0d06ab7 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c @@ -253,7 +253,7 @@ void chsc_chp_offline(struct chp_id chpid) struct chp_link link; char dbf_txt[15]; - sprintf(dbf_txt, "chpr%x.%02x", chpid.cssid, chpid.id); + scnprintf(dbf_txt, sizeof(dbf_txt), "chpr%x.%02x", chpid.cssid, chpid.id); CIO_TRACE_EVENT(2, dbf_txt); if (chp_get_status(chpid) <= 0) @@ -284,11 +284,11 @@ static void s390_process_res_acc(struct chp_link *link) { char dbf_txt[15]; - sprintf(dbf_txt, "accpr%x.%02x", link->chpid.cssid, - link->chpid.id); + scnprintf(dbf_txt, sizeof(dbf_txt), "accpr%x.%02x", link->chpid.cssid, + link->chpid.id); CIO_TRACE_EVENT( 2, dbf_txt); if (link->fla != 0) { - sprintf(dbf_txt, "fla%x", link->fla); + scnprintf(dbf_txt, sizeof(dbf_txt), "fla%x", link->fla); CIO_TRACE_EVENT( 2, dbf_txt); } /* Wait until previous actions have settled. */ @@ -757,7 +757,7 @@ void chsc_chp_online(struct chp_id chpid) struct chp_link link; char dbf_txt[15]; - sprintf(dbf_txt, "cadd%x.%02x", chpid.cssid, chpid.id); + scnprintf(dbf_txt, sizeof(dbf_txt), "cadd%x.%02x", chpid.cssid, chpid.id); CIO_TRACE_EVENT(2, dbf_txt); if (chp_get_status(chpid) != 0) { diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 21508e4606d5..6bcc8e58e5f9 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -113,7 +113,7 @@ cio_start_handle_notoper(struct subchannel *sch, __u8 lpm) if (cio_update_schib(sch)) return -ENODEV; - sprintf(dbf_text, "no%s", dev_name(&sch->dev)); + scnprintf(dbf_text, sizeof(dbf_text), "no%s", dev_name(&sch->dev)); CIO_TRACE_EVENT(0, dbf_text); CIO_HEX_EVENT(0, &sch->schib, sizeof (struct schib)); diff --git a/drivers/s390/cio/device_status.c b/drivers/s390/cio/device_status.c index 0ff8482a7b15..f4096373c8c0 100644 --- a/drivers/s390/cio/device_status.c +++ b/drivers/s390/cio/device_status.c @@ -42,7 +42,7 @@ ccw_device_msg_control_check(struct ccw_device *cdev, struct irb *irb) cdev->private->dev_id.devno, sch->schid.ssid, sch->schid.sch_no, scsw_dstat(&irb->scsw), scsw_cstat(&irb->scsw)); - sprintf(dbf_text, "chk%x", sch->schid.sch_no); + scnprintf(dbf_text, sizeof(dbf_text), "chk%x", sch->schid.sch_no); CIO_TRACE_EVENT(0, dbf_text); CIO_HEX_EVENT(0, irb, sizeof(struct irb)); } From ffb5d3af5e2b52472f236f8bb13414c7fab99797 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 7 Oct 2025 11:05:03 +0200 Subject: [PATCH 11/92] s390/dcss: Use scnprintf() instead of sprintf() Use scnprintf() instead of sprintf() for those cases where the destination is an array and the size of the array is known at compile time. This prevents theoretical buffer overflows, but also avoids that people again and again spend time to figure out if the code is actually safe. Reviewed-by: Jan Polensky Signed-off-by: Heiko Carstens --- drivers/s390/block/dcssblk.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c index 86fef4b15015..57d691ed0a63 100644 --- a/drivers/s390/block/dcssblk.c +++ b/drivers/s390/block/dcssblk.c @@ -674,8 +674,8 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char rc = dcssblk_assign_free_minor(dev_info); if (rc) goto release_gd; - sprintf(dev_info->gd->disk_name, "dcssblk%d", - dev_info->gd->first_minor); + scnprintf(dev_info->gd->disk_name, sizeof(dev_info->gd->disk_name), + "dcssblk%d", dev_info->gd->first_minor); list_add_tail(&dev_info->lh, &dcssblk_devices); if (!try_module_get(THIS_MODULE)) { From c769941de8bf6ab744bbc7ec7a88c32955d10646 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 7 Oct 2025 11:05:04 +0200 Subject: [PATCH 12/92] s390/tape: Use scnprintf() instead of sprintf() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use scnprintf() instead of sprintf() for those cases where the destination is an array and the size of the array is known at compile time. This prevents theoretical buffer overflows, but also avoids that people again and again spend time to figure out if the code is actually safe. Reviewed-by: Jan Höppner Reviewed-by: Jan Polensky Signed-off-by: Heiko Carstens --- drivers/s390/char/tape_char.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c index 89778d922d9f..058a3b95f959 100644 --- a/drivers/s390/char/tape_char.c +++ b/drivers/s390/char/tape_char.c @@ -64,7 +64,7 @@ tapechar_setup_device(struct tape_device * device) { char device_name[20]; - sprintf(device_name, "ntibm%i", device->first_minor / 2); + scnprintf(device_name, sizeof(device_name), "ntibm%i", device->first_minor / 2); device->nt = register_tape_dev( &device->cdev->dev, MKDEV(tapechar_major, device->first_minor), From c97689345cd0613f8c8c81c3304331fbd2c5b599 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 7 Oct 2025 11:05:05 +0200 Subject: [PATCH 13/92] s390/con3270: Use scnprintf() instead of sprintf() Use scnprintf() instead of sprintf() for those cases where the destination is an array and the size of the array is known at compile time. This prevents theoretical buffer overflows, but also avoids that people again and again spend time to figure out if the code is actually safe. Reviewed-by: Jan Polensky Signed-off-by: Heiko Carstens --- drivers/s390/char/con3270.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c index a367f95c7c53..5a505972e571 100644 --- a/drivers/s390/char/con3270.c +++ b/drivers/s390/char/con3270.c @@ -1662,7 +1662,7 @@ static void tty3270_escape_sequence(struct tty3270 *tp, u8 ch) else if (tp->esc_par[0] == 6) { /* Cursor report. */ char buf[40]; - sprintf(buf, "\033[%d;%dR", tp->cy + 1, tp->cx + 1); + scnprintf(buf, sizeof(buf), "\033[%d;%dR", tp->cy + 1, tp->cx + 1); kbd_puts_queue(&tp->port, buf); } return; From 39376c77a5d07eb2924104572c1c0582a3ea54ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B6ppner?= Date: Thu, 16 Oct 2025 09:47:11 +0200 Subject: [PATCH 14/92] s390/tape: Remove count parameter from read/write_block functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The count parameter of the read/write_block discipline functions was never used. Remove it. Signed-off-by: Jan Höppner Reviewed-by: Jens Remus Signed-off-by: Heiko Carstens --- drivers/s390/char/tape.h | 4 ++-- drivers/s390/char/tape_char.c | 4 ++-- drivers/s390/char/tape_std.c | 4 ++-- drivers/s390/char/tape_std.h | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h index 0aba30efb483..dc04518b7bec 100644 --- a/drivers/s390/char/tape.h +++ b/drivers/s390/char/tape.h @@ -151,8 +151,8 @@ struct tape_discipline { int (*setup_device)(struct tape_device *); void (*cleanup_device)(struct tape_device *); int (*irq)(struct tape_device *, struct tape_request *, struct irb *); - struct tape_request *(*read_block)(struct tape_device *, size_t); - struct tape_request *(*write_block)(struct tape_device *, size_t); + struct tape_request *(*read_block)(struct tape_device *); + struct tape_request *(*write_block)(struct tape_device *); void (*process_eov)(struct tape_device*); /* ioctl function for additional ioctls. */ int (*ioctl_fn)(struct tape_device *, unsigned int, unsigned long); diff --git a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c index 89778d922d9f..3d557b55bda8 100644 --- a/drivers/s390/char/tape_char.c +++ b/drivers/s390/char/tape_char.c @@ -162,7 +162,7 @@ tapechar_read(struct file *filp, char __user *data, size_t count, loff_t *ppos) DBF_EVENT(6, "TCHAR:nbytes: %lx\n", block_size); /* Let the discipline build the ccw chain. */ - request = device->discipline->read_block(device, block_size); + request = device->discipline->read_block(device); if (IS_ERR(request)) return PTR_ERR(request); /* Execute it. */ @@ -215,7 +215,7 @@ tapechar_write(struct file *filp, const char __user *data, size_t count, loff_t DBF_EVENT(6,"TCHAR:nbytes: %lx\n", block_size); DBF_EVENT(6, "TCHAR:nblocks: %x\n", nblocks); /* Let the discipline build the ccw chain. */ - request = device->discipline->write_block(device, block_size); + request = device->discipline->write_block(device); if (IS_ERR(request)) return PTR_ERR(request); rc = 0; diff --git a/drivers/s390/char/tape_std.c b/drivers/s390/char/tape_std.c index 176ae8e2eb6b..66d4a9b7e710 100644 --- a/drivers/s390/char/tape_std.c +++ b/drivers/s390/char/tape_std.c @@ -641,7 +641,7 @@ tape_std_mtcompression(struct tape_device *device, int mt_count) * Read Block */ struct tape_request * -tape_std_read_block(struct tape_device *device, size_t count) +tape_std_read_block(struct tape_device *device) { struct tape_request *request; @@ -685,7 +685,7 @@ tape_std_read_backward(struct tape_device *device, struct tape_request *request) * Write Block */ struct tape_request * -tape_std_write_block(struct tape_device *device, size_t count) +tape_std_write_block(struct tape_device *device) { struct tape_request *request; diff --git a/drivers/s390/char/tape_std.h b/drivers/s390/char/tape_std.h index dcc63ff587f9..eefeb5484214 100644 --- a/drivers/s390/char/tape_std.h +++ b/drivers/s390/char/tape_std.h @@ -97,10 +97,10 @@ #define SENSE_TAPE_POSITIONING 0x01 /* discipline functions */ -struct tape_request *tape_std_read_block(struct tape_device *, size_t); +struct tape_request *tape_std_read_block(struct tape_device *); void tape_std_read_backward(struct tape_device *device, struct tape_request *request); -struct tape_request *tape_std_write_block(struct tape_device *, size_t); +struct tape_request *tape_std_write_block(struct tape_device *); /* Some non-mtop commands. */ int tape_std_assign(struct tape_device *); From 1b9df1a28f0f625bcd2ce6bba2139a95c3aae703 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B6ppner?= Date: Thu, 16 Oct 2025 09:47:12 +0200 Subject: [PATCH 15/92] s390/tape: Remove 34xx Read Opposite error recovery MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On old native type 3490 tape devices a Read Opposite error recovery procedure on Error Recovery Action Code (ERA) 26 was issued if a Read Forward command failed. This recovery procedure was implemented with the Read Backward command. As a preparation for a subsequent commit, that adds support for bigger block sizes, remove the 34xx ERA 26 related recovery code. The recovery code would need to be adapted to the bigger block sizes, without any possibility to be tested, as modern Virtual Tape Servers (VTS) do neither report ERA 26 on a Read Forward command failure nor support the error recovery procedure anymore. Signed-off-by: Jan Höppner Reviewed-by: Jens Remus Signed-off-by: Heiko Carstens --- drivers/s390/char/tape_34xx.c | 28 ---------------------------- drivers/s390/char/tape_std.c | 20 -------------------- 2 files changed, 48 deletions(-) diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c index 1e4984acb648..9d0fb4b867c4 100644 --- a/drivers/s390/char/tape_34xx.c +++ b/drivers/s390/char/tape_34xx.c @@ -234,31 +234,6 @@ tape_34xx_unsolicited_irq(struct tape_device *device, struct irb *irb) return TAPE_IO_SUCCESS; } -/* - * Read Opposite Error Recovery Function: - * Used, when Read Forward does not work - */ -static int -tape_34xx_erp_read_opposite(struct tape_device *device, - struct tape_request *request) -{ - if (request->op == TO_RFO) { - /* - * We did read forward, but the data could not be read - * *correctly*. We transform the request to a read backward - * and try again. - */ - tape_std_read_backward(device, request); - return tape_34xx_erp_retry(request); - } - - /* - * We tried to read forward and backward, but hat no - * success -> failed. - */ - return tape_34xx_erp_failed(request, -EIO); -} - static int tape_34xx_erp_bug(struct tape_device *device, struct tape_request *request, struct irb *irb, int no) @@ -440,9 +415,6 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request, dev_warn (&device->cdev->dev, "A write error on the " "tape cannot be recovered\n"); return tape_34xx_erp_failed(request, -EIO); - case 0x26: - /* Data Check (read opposite) occurred. */ - return tape_34xx_erp_read_opposite(device, request); case 0x28: /* ID-Mark at tape start couldn't be written */ dev_warn (&device->cdev->dev, "Writing the ID-mark " diff --git a/drivers/s390/char/tape_std.c b/drivers/s390/char/tape_std.c index 66d4a9b7e710..29e40ad6fd19 100644 --- a/drivers/s390/char/tape_std.c +++ b/drivers/s390/char/tape_std.c @@ -662,25 +662,6 @@ tape_std_read_block(struct tape_device *device) return request; } -/* - * Read Block backward transformation function. - */ -void -tape_std_read_backward(struct tape_device *device, struct tape_request *request) -{ - /* - * We have allocated 4 ccws in tape_std_read, so we can now - * transform the request to a read backward, followed by a - * forward space block. - */ - request->op = TO_RBA; - tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte); - tape_ccw_cc_idal(request->cpaddr + 1, READ_BACKWARD, - device->char_data.idal_buf); - tape_ccw_cc(request->cpaddr + 2, FORSPACEBLOCK, 0, NULL); - tape_ccw_end(request->cpaddr + 3, NOP, 0, NULL); - DBF_EVENT(6, "xrop ccwg");} - /* * Write Block */ @@ -741,6 +722,5 @@ EXPORT_SYMBOL(tape_std_mterase); EXPORT_SYMBOL(tape_std_mtunload); EXPORT_SYMBOL(tape_std_mtcompression); EXPORT_SYMBOL(tape_std_read_block); -EXPORT_SYMBOL(tape_std_read_backward); EXPORT_SYMBOL(tape_std_write_block); EXPORT_SYMBOL(tape_std_process_eov); From a984d712773d6573e4b0a05c9e4a77623d8c7dd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B6ppner?= Date: Thu, 16 Oct 2025 09:47:13 +0200 Subject: [PATCH 16/92] s390/tape: Remove 3590 Read Opposite error recovery MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On old native type 3590 tape devices a Read Opposite error recovery procedure on Error Recovery Action Code (ERA) 26 was issued if a Read Forward command failed. This recovery procedure was implemented with the Read Backward command. This is no longer supported. Remove 3590 ERA 26 and Read Backward related recovery code. Signed-off-by: Jan Höppner Reviewed-by: Jens Remus Signed-off-by: Heiko Carstens --- drivers/s390/char/tape_3590.c | 89 ----------------------------------- 1 file changed, 89 deletions(-) diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c index 2a2931d303cb..5b25f5415e4c 100644 --- a/drivers/s390/char/tape_3590.c +++ b/drivers/s390/char/tape_3590.c @@ -550,31 +550,6 @@ tape_3590_mtseek(struct tape_device *device, int count) return tape_do_io_free(device, request); } -/* - * Read Opposite Error Recovery Function: - * Used, when Read Forward does not work - */ -static void -tape_3590_read_opposite(struct tape_device *device, - struct tape_request *request) -{ - struct tape_3590_disc_data *data; - - /* - * We have allocated 4 ccws in tape_std_read, so we can now - * transform the request to a read backward, followed by a - * forward space block. - */ - request->op = TO_RBA; - tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte); - data = device->discdata; - tape_ccw_cc_idal(request->cpaddr + 1, data->read_back_op, - device->char_data.idal_buf); - tape_ccw_cc(request->cpaddr + 2, FORSPACEBLOCK, 0, NULL); - tape_ccw_end(request->cpaddr + 3, NOP, 0, NULL); - DBF_EVENT(6, "xrop ccwg\n"); -} - /* * Read Attention Msg * This should be done after an interrupt with attention bit (0x80) @@ -896,60 +871,6 @@ tape_3590_erp_special_interrupt(struct tape_device *device, return tape_3590_erp_basic(device, request, irb, -EIO); } -/* - * RDA: Read Alternate - */ -static int -tape_3590_erp_read_alternate(struct tape_device *device, - struct tape_request *request, struct irb *irb) -{ - struct tape_3590_disc_data *data; - - /* - * The issued Read Backward or Read Previous command is not - * supported by the device - * The recovery action should be to issue another command: - * Read Revious: if Read Backward is not supported - * Read Backward: if Read Previous is not supported - */ - data = device->discdata; - if (data->read_back_op == READ_PREVIOUS) { - DBF_EVENT(2, "(%08x): No support for READ_PREVIOUS command\n", - device->cdev_id); - data->read_back_op = READ_BACKWARD; - } else { - DBF_EVENT(2, "(%08x): No support for READ_BACKWARD command\n", - device->cdev_id); - data->read_back_op = READ_PREVIOUS; - } - tape_3590_read_opposite(device, request); - return tape_3590_erp_retry(device, request, irb); -} - -/* - * Error Recovery read opposite - */ -static int -tape_3590_erp_read_opposite(struct tape_device *device, - struct tape_request *request, struct irb *irb) -{ - switch (request->op) { - case TO_RFO: - /* - * We did read forward, but the data could not be read. - * We will read backward and then skip forward again. - */ - tape_3590_read_opposite(device, request); - return tape_3590_erp_retry(device, request, irb); - case TO_RBA: - /* We tried to read forward and backward, but hat no success */ - return tape_3590_erp_failed(device, request, irb, -EIO); - break; - default: - return tape_3590_erp_failed(device, request, irb, -EIO); - } -} - /* * Print an MIM (Media Information Message) (message code f0) */ @@ -1348,10 +1269,6 @@ tape_3590_unit_check(struct tape_device *device, struct tape_request *request, tape_3590_print_era_msg(device, irb); return tape_3590_erp_read_buf_log(device, request, irb); - case 0x2011: - tape_3590_print_era_msg(device, irb); - return tape_3590_erp_read_alternate(device, request, irb); - case 0x2230: case 0x2231: tape_3590_print_era_msg(device, irb); @@ -1405,12 +1322,6 @@ tape_3590_unit_check(struct tape_device *device, struct tape_request *request, tape_3590_print_era_msg(device, irb); return tape_3590_erp_swap(device, request, irb); } - if (sense->rac == 0x26) { - /* Read Opposite */ - tape_3590_print_era_msg(device, irb); - return tape_3590_erp_read_opposite(device, request, - irb); - } return tape_3590_erp_basic(device, request, irb, -EIO); case 0x5020: case 0x5021: From 83cff1b1245fcabe76889520c8a92158e4f25f7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B6ppner?= Date: Thu, 16 Oct 2025 09:47:14 +0200 Subject: [PATCH 17/92] s390/tape: Remove extra CCW allocation for error recovery MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Read Opposite error recovery code required 2 extra CCWs to be allocated in order to transform the request. As this error recovery code for both 34xx and 3590 was removed the additional allocation isn't required anymore. Reduce it to two. Signed-off-by: Jan Höppner Reviewed-by: Jens Remus Signed-off-by: Heiko Carstens --- drivers/s390/char/tape_std.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/s390/char/tape_std.c b/drivers/s390/char/tape_std.c index 29e40ad6fd19..e46ffc46f323 100644 --- a/drivers/s390/char/tape_std.c +++ b/drivers/s390/char/tape_std.c @@ -645,11 +645,7 @@ tape_std_read_block(struct tape_device *device) { struct tape_request *request; - /* - * We have to alloc 4 ccws in order to be able to transform request - * into a read backward request in error case. - */ - request = tape_alloc_request(4, 0); + request = tape_alloc_request(2, 0); if (IS_ERR(request)) { DBF_EXCEPTION(6, "xrbl fail"); return request; From e039400f75f1a88675132abc57a18d090cf75209 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B6ppner?= Date: Thu, 16 Oct 2025 09:47:15 +0200 Subject: [PATCH 18/92] s390/tape: Fix return value of ccw helper functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In contrast to all other helper functions used to build CCW chains, tape_ccw_cc_idal() and tape_ccw_end_idal() return values using post-increments, which results in returning the same CCW pointer. Though, the intent of the CCW helper functions is to return the _next_ CCW in the chain, which can then be processed. There is currently no actual issue, as tape_ccw_cc_idal() is not used yet and tape_ccw_end_idal() is only used at the end of a chain. Change both functions return statement to ccw + 1 and bring them in line with the other helper functions. Signed-off-by: Jan Höppner Reviewed-by: Jens Remus Signed-off-by: Heiko Carstens --- drivers/s390/char/tape.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h index dc04518b7bec..0596a9758662 100644 --- a/drivers/s390/char/tape.h +++ b/drivers/s390/char/tape.h @@ -352,7 +352,7 @@ tape_ccw_cc_idal(struct ccw1 *ccw, __u8 cmd_code, struct idal_buffer *idal) ccw->cmd_code = cmd_code; ccw->flags = CCW_FLAG_CC; idal_buffer_set_cda(idal, ccw); - return ccw++; + return ccw + 1; } static inline struct ccw1 * @@ -361,7 +361,7 @@ tape_ccw_end_idal(struct ccw1 *ccw, __u8 cmd_code, struct idal_buffer *idal) ccw->cmd_code = cmd_code; ccw->flags = 0; idal_buffer_set_cda(idal, ccw); - return ccw++; + return ccw + 1; } /* Global vars */ From a5e2ca22c18bcda97c7fc99d216ffd742405fb2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B6ppner?= Date: Thu, 16 Oct 2025 09:47:16 +0200 Subject: [PATCH 19/92] s390/tape: Move idal allocation to core functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently tapechar_check_idalbuffer() is part of tape_char.c and is used to ensure the idal buffer is big enough for the requested I/O and reallocates a new one if required. The same is done in tape_std.c when a fixed block size is set using the mtsetblk command. This is essentially duplicate code. The allocation of the buffer that is required for I/O can be considered core functionality. Move the idal buffer allocation to tape_core.c, make it generally available, and reduce code duplication. Signed-off-by: Jan Höppner Reviewed-by: Jens Remus Signed-off-by: Heiko Carstens --- drivers/s390/char/tape.h | 1 + drivers/s390/char/tape_char.c | 31 ++----------------------------- drivers/s390/char/tape_core.c | 28 ++++++++++++++++++++++++++++ drivers/s390/char/tape_std.c | 22 ++++------------------ 4 files changed, 35 insertions(+), 47 deletions(-) diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h index 0596a9758662..349fa95dcedb 100644 --- a/drivers/s390/char/tape.h +++ b/drivers/s390/char/tape.h @@ -234,6 +234,7 @@ struct tape_device { /* Externals from tape_core.c */ extern struct tape_request *tape_alloc_request(int cplength, int datasize); extern void tape_free_request(struct tape_request *); +extern int tape_check_idalbuffer(struct tape_device *device, size_t size); extern int tape_do_io(struct tape_device *, struct tape_request *); extern int tape_do_io_async(struct tape_device *, struct tape_request *); extern int tape_do_io_interruptible(struct tape_device *, struct tape_request *); diff --git a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c index 3d557b55bda8..e229585cfb9e 100644 --- a/drivers/s390/char/tape_char.c +++ b/drivers/s390/char/tape_char.c @@ -93,33 +93,6 @@ tapechar_cleanup_device(struct tape_device *device) device->nt = NULL; } -static int -tapechar_check_idalbuffer(struct tape_device *device, size_t block_size) -{ - struct idal_buffer *new; - - if (device->char_data.idal_buf != NULL && - device->char_data.idal_buf->size == block_size) - return 0; - - if (block_size > MAX_BLOCKSIZE) { - DBF_EVENT(3, "Invalid blocksize (%zd > %d)\n", - block_size, MAX_BLOCKSIZE); - return -EINVAL; - } - - /* The current idal buffer is not correct. Allocate a new one. */ - new = idal_buffer_alloc(block_size, 0); - if (IS_ERR(new)) - return -ENOMEM; - - if (device->char_data.idal_buf != NULL) - idal_buffer_free(device->char_data.idal_buf); - - device->char_data.idal_buf = new; - - return 0; -} /* * Tape device read function @@ -156,7 +129,7 @@ tapechar_read(struct file *filp, char __user *data, size_t count, loff_t *ppos) block_size = count; } - rc = tapechar_check_idalbuffer(device, block_size); + rc = tape_check_idalbuffer(device, block_size); if (rc) return rc; @@ -208,7 +181,7 @@ tapechar_write(struct file *filp, const char __user *data, size_t count, loff_t nblocks = 1; } - rc = tapechar_check_idalbuffer(device, block_size); + rc = tape_check_idalbuffer(device, block_size); if (rc) return rc; diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c index 6ec812280221..30ace31a3bba 100644 --- a/drivers/s390/char/tape_core.c +++ b/drivers/s390/char/tape_core.c @@ -726,6 +726,34 @@ tape_free_request (struct tape_request * request) kfree(request); } +int +tape_check_idalbuffer(struct tape_device *device, size_t size) +{ + struct idal_buffer *new; + + if (device->char_data.idal_buf != NULL && + device->char_data.idal_buf->size == size) + return 0; + + if (size > MAX_BLOCKSIZE) { + DBF_EVENT(3, "Invalid blocksize (%zd > %d)\n", + size, MAX_BLOCKSIZE); + return -EINVAL; + } + + /* The current idal buffer is not correct. Allocate a new one. */ + new = idal_buffer_alloc(size, 0); + if (IS_ERR(new)) + return -ENOMEM; + + if (device->char_data.idal_buf != NULL) + idal_buffer_free(device->char_data.idal_buf); + + device->char_data.idal_buf = new; + + return 0; +} + static int __tape_start_io(struct tape_device *device, struct tape_request *request) { diff --git a/drivers/s390/char/tape_std.c b/drivers/s390/char/tape_std.c index e46ffc46f323..29abbc23f908 100644 --- a/drivers/s390/char/tape_std.c +++ b/drivers/s390/char/tape_std.c @@ -212,7 +212,7 @@ tape_std_mtload(struct tape_device *device, int count) int tape_std_mtsetblk(struct tape_device *device, int count) { - struct idal_buffer *new; + int rc; DBF_LH(6, "tape_std_mtsetblk(%d)\n", count); if (count <= 0) { @@ -224,26 +224,12 @@ tape_std_mtsetblk(struct tape_device *device, int count) device->char_data.block_size = 0; return 0; } - if (device->char_data.idal_buf != NULL && - device->char_data.idal_buf->size == count) - /* We already have a idal buffer of that size. */ - return 0; - if (count > MAX_BLOCKSIZE) { - DBF_EVENT(3, "Invalid block size (%d > %d) given.\n", - count, MAX_BLOCKSIZE); - return -EINVAL; - } + rc = tape_check_idalbuffer(device, count); + if (rc) + return rc; - /* Allocate a new idal buffer. */ - new = idal_buffer_alloc(count, 0); - if (IS_ERR(new)) - return -ENOMEM; - if (device->char_data.idal_buf != NULL) - idal_buffer_free(device->char_data.idal_buf); - device->char_data.idal_buf = new; device->char_data.block_size = count; - DBF_LH(6, "new blocksize is %d\n", device->char_data.block_size); return 0; From 574817d6c0866e80e8f09b8537476685631fc992 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B6ppner?= Date: Thu, 16 Oct 2025 09:47:17 +0200 Subject: [PATCH 20/92] s390/tape: Introduce idal buffer array MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The tape device driver uses a single idal_buffer for I/O. While the buffer itself can be arbitrary big, the limit for data transfer for a single Channel-Command Word is at 65535 bytes (64K-1) since the count field specifying the amount of data designated by the CCW is a 16-bit unsigned value. Provide functionality that allocates an array of multiple IDAL buffer with the limitation mentioned above in mind. A call to idal_buffer_array_alloc() allocates an array with a certain amount of IDAL buffers which is determined based on the total size of @size. Each individual buffer is limited to a size of CCW_MAX_BYTE_COUNT (65535 bytes). Add helper functions that determine the size (# of elements) and the total data size covered by the array as well. Current users of the single IDAL buffer are adapted to use the new functions with one buffer to allocate. The single IDAL buffer is removed from the tape_char_data struct. Signed-off-by: Jan Höppner Reviewed-by: Jens Remus Signed-off-by: Heiko Carstens --- arch/s390/include/asm/cio.h | 2 + arch/s390/include/asm/idals.h | 76 +++++++++++++++++++++++++++++++++++ drivers/s390/char/tape.h | 2 +- drivers/s390/char/tape_char.c | 10 ++--- drivers/s390/char/tape_core.c | 16 ++++---- drivers/s390/char/tape_std.c | 4 +- 6 files changed, 94 insertions(+), 16 deletions(-) diff --git a/arch/s390/include/asm/cio.h b/arch/s390/include/asm/cio.h index b6b619f340a5..0a82ae2300b6 100644 --- a/arch/s390/include/asm/cio.h +++ b/arch/s390/include/asm/cio.h @@ -18,6 +18,8 @@ #include +#define CCW_MAX_BYTE_COUNT 65535 + /** * struct ccw1 - channel command word * @cmd_code: command code diff --git a/arch/s390/include/asm/idals.h b/arch/s390/include/asm/idals.h index ac68c657b28c..e5000ee6cdc6 100644 --- a/arch/s390/include/asm/idals.h +++ b/arch/s390/include/asm/idals.h @@ -180,6 +180,82 @@ static inline void idal_buffer_free(struct idal_buffer *ib) kfree(ib); } +/* + * Allocate an array of IDAL buffers to cover a total data size of @size. The + * resulting array is null-terminated. + * + * The amount of individual IDAL buffers is determined based on @size. + * Each IDAL buffer can have a maximum size of @CCW_MAX_BYTE_COUNT. + */ +static inline struct idal_buffer **idal_buffer_array_alloc(size_t size, int page_order) +{ + struct idal_buffer **ibs; + size_t ib_size; /* Size of a single idal buffer */ + int count; /* Amount of individual idal buffers */ + int i; + + count = (size + CCW_MAX_BYTE_COUNT - 1) / CCW_MAX_BYTE_COUNT; + ibs = kmalloc_array(count + 1, sizeof(*ibs), GFP_KERNEL); + for (i = 0; i < count; i++) { + /* Determine size for the current idal buffer */ + ib_size = min(size, CCW_MAX_BYTE_COUNT); + size -= ib_size; + ibs[i] = idal_buffer_alloc(ib_size, page_order); + if (IS_ERR(ibs[i])) { + while (i--) + idal_buffer_free(ibs[i]); + kfree(ibs); + ibs = NULL; + return ERR_PTR(-ENOMEM); + } + } + ibs[i] = NULL; + return ibs; +} + +/* + * Free array of IDAL buffers + */ +static inline void idal_buffer_array_free(struct idal_buffer ***ibs) +{ + struct idal_buffer **p; + + if (!ibs || !*ibs) + return; + for (p = *ibs; *p; p++) + idal_buffer_free(*p); + kfree(*ibs); + *ibs = NULL; +} + +/* + * Determine size of IDAL buffer array + */ +static inline int idal_buffer_array_size(struct idal_buffer **ibs) +{ + int size = 0; + + while (ibs && *ibs) { + size++; + ibs++; + } + return size; +} + +/* + * Determine total data size covered by IDAL buffer array + */ +static inline size_t idal_buffer_array_datasize(struct idal_buffer **ibs) +{ + size_t size = 0; + + while (ibs && *ibs) { + size += (*ibs)->size; + ibs++; + } + return size; +} + /* * Test if a idal list is really needed. */ diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h index 349fa95dcedb..6e97b26d4e70 100644 --- a/drivers/s390/char/tape.h +++ b/drivers/s390/char/tape.h @@ -172,7 +172,7 @@ struct tape_discipline { /* Char Frontend Data */ struct tape_char_data { - struct idal_buffer *idal_buf; /* idal buffer for user char data */ + struct idal_buffer **ibs; /* idal buffer array for user char data */ int block_size; /* of size block_size. */ }; diff --git a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c index e229585cfb9e..bcc49e9eabb8 100644 --- a/drivers/s390/char/tape_char.c +++ b/drivers/s390/char/tape_char.c @@ -144,7 +144,7 @@ tapechar_read(struct file *filp, char __user *data, size_t count, loff_t *ppos) rc = block_size - request->rescnt; DBF_EVENT(6, "TCHAR:rbytes: %x\n", rc); /* Copy data from idal buffer to user space. */ - if (idal_buffer_to_user(device->char_data.idal_buf, + if (idal_buffer_to_user(*device->char_data.ibs, data, rc) != 0) rc = -EFAULT; } @@ -195,7 +195,7 @@ tapechar_write(struct file *filp, const char __user *data, size_t count, loff_t written = 0; for (i = 0; i < nblocks; i++) { /* Copy data from user space to idal buffer. */ - if (idal_buffer_from_user(device->char_data.idal_buf, + if (idal_buffer_from_user(*device->char_data.ibs, data, block_size)) { rc = -EFAULT; break; @@ -297,10 +297,8 @@ tapechar_release(struct inode *inode, struct file *filp) } } - if (device->char_data.idal_buf != NULL) { - idal_buffer_free(device->char_data.idal_buf); - device->char_data.idal_buf = NULL; - } + if (device->char_data.ibs) + idal_buffer_array_free(&device->char_data.ibs); tape_release(device); filp->private_data = NULL; tape_put_device(device); diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c index 30ace31a3bba..304c6eae139c 100644 --- a/drivers/s390/char/tape_core.c +++ b/drivers/s390/char/tape_core.c @@ -729,10 +729,11 @@ tape_free_request (struct tape_request * request) int tape_check_idalbuffer(struct tape_device *device, size_t size) { - struct idal_buffer *new; + struct idal_buffer **new; + size_t old_size = 0; - if (device->char_data.idal_buf != NULL && - device->char_data.idal_buf->size == size) + old_size = idal_buffer_array_datasize(device->char_data.ibs); + if (old_size == size) return 0; if (size > MAX_BLOCKSIZE) { @@ -742,14 +743,15 @@ tape_check_idalbuffer(struct tape_device *device, size_t size) } /* The current idal buffer is not correct. Allocate a new one. */ - new = idal_buffer_alloc(size, 0); + new = idal_buffer_array_alloc(size, 0); if (IS_ERR(new)) return -ENOMEM; - if (device->char_data.idal_buf != NULL) - idal_buffer_free(device->char_data.idal_buf); + /* Free old idal buffer array */ + if (device->char_data.ibs) + idal_buffer_array_free(&device->char_data.ibs); - device->char_data.idal_buf = new; + device->char_data.ibs = new; return 0; } diff --git a/drivers/s390/char/tape_std.c b/drivers/s390/char/tape_std.c index 29abbc23f908..5f3646f78bfa 100644 --- a/drivers/s390/char/tape_std.c +++ b/drivers/s390/char/tape_std.c @@ -639,7 +639,7 @@ tape_std_read_block(struct tape_device *device) request->op = TO_RFO; tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte); tape_ccw_end_idal(request->cpaddr + 1, READ_FORWARD, - device->char_data.idal_buf); + *device->char_data.ibs); DBF_EVENT(6, "xrbl ccwg\n"); return request; } @@ -660,7 +660,7 @@ tape_std_write_block(struct tape_device *device) request->op = TO_WRI; tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte); tape_ccw_end_idal(request->cpaddr + 1, WRITE_CMD, - device->char_data.idal_buf); + *device->char_data.ibs); DBF_EVENT(6, "xwbl ccwg\n"); return request; } From 319d3d66537e615e0729ae734099fe01581bc09d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B6ppner?= Date: Thu, 16 Oct 2025 09:47:18 +0200 Subject: [PATCH 21/92] s390/tape: Add support for bigger block sizes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The tape device type 3590/3592 and emulated 3490 VTS can handle a block size of up to 256K bytes. Currently the tape device driver is limited to a block size of 65535 bytes (64K-1). This limitation stems from the maximum of 65535 bytes of data that can be transferred with one Channel-Command Word (CCW). To work around this limitation data chaining is used which uses several CCW to transfer an entire 256K block of data. A single CCW holds a maximum of 65535 bytes of data. Set MAX_BLOCKSIZE to 262144 (= 256K) to allow for data transfers with larger block sizes. The read_block() and write_block() discipline functions calculate the number of CCWs required based on the IDAL buffer array size that was created for a given block size. If there is more than one CCW required for the data transfer, the new helper function tape_ccw_dc_idal() is used to build the data chain accordingly. The Interruption-Repsonse Block (irb) is added to the tape_request struct so that the tapechar_read/write() functions can analyze what data was read or written accordingly. Signed-off-by: Jan Höppner Reviewed-by: Jens Remus Signed-off-by: Heiko Carstens --- drivers/s390/char/tape.h | 10 +++++ drivers/s390/char/tape_char.c | 70 ++++++++++++++++++++++++----------- drivers/s390/char/tape_core.c | 5 ++- drivers/s390/char/tape_std.c | 30 +++++++++++---- drivers/s390/char/tape_std.h | 5 +-- 5 files changed, 86 insertions(+), 34 deletions(-) diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h index 6e97b26d4e70..3953b31b0c55 100644 --- a/drivers/s390/char/tape.h +++ b/drivers/s390/char/tape.h @@ -130,6 +130,7 @@ struct tape_request { int retries; /* retry counter for error recovery. */ int rescnt; /* residual count from devstat. */ struct timer_list timer; /* timer for std_assign_timeout(). */ + struct irb irb; /* device status */ /* Callback for delivering final status. */ void (*callback)(struct tape_request *, void *); @@ -347,6 +348,15 @@ tape_ccw_repeat(struct ccw1 *ccw, __u8 cmd_code, int count) return ccw; } +static inline struct ccw1 * +tape_ccw_dc_idal(struct ccw1 *ccw, __u8 cmd_code, struct idal_buffer *idal) +{ + ccw->cmd_code = cmd_code; + ccw->flags = CCW_FLAG_DC; + idal_buffer_set_cda(idal, ccw); + return ccw + 1; +} + static inline struct ccw1 * tape_ccw_cc_idal(struct ccw1 *ccw, __u8 cmd_code, struct idal_buffer *idal) { diff --git a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c index bcc49e9eabb8..96e6c8a5735e 100644 --- a/drivers/s390/char/tape_char.c +++ b/drivers/s390/char/tape_char.c @@ -100,9 +100,12 @@ tapechar_cleanup_device(struct tape_device *device) static ssize_t tapechar_read(struct file *filp, char __user *data, size_t count, loff_t *ppos) { - struct tape_device *device; struct tape_request *request; + struct ccw1 *ccw, *last_ccw; + struct tape_device *device; + struct idal_buffer **ibs; size_t block_size; + size_t read = 0; int rc; DBF_EVENT(6, "TCHAR:read\n"); @@ -141,12 +144,25 @@ tapechar_read(struct file *filp, char __user *data, size_t count, loff_t *ppos) /* Execute it. */ rc = tape_do_io(device, request); if (rc == 0) { - rc = block_size - request->rescnt; DBF_EVENT(6, "TCHAR:rbytes: %x\n", rc); - /* Copy data from idal buffer to user space. */ - if (idal_buffer_to_user(*device->char_data.ibs, - data, rc) != 0) - rc = -EFAULT; + /* Channel Program Address (cpa) points to last CCW + 8 */ + last_ccw = dma32_to_virt(request->irb.scsw.cmd.cpa); + ccw = request->cpaddr; + ibs = device->char_data.ibs; + while (++ccw < last_ccw) { + /* Copy data from idal buffer to user space. */ + if (idal_buffer_to_user(*ibs++, data, ccw->count) != 0) { + rc = -EFAULT; + break; + } + read += ccw->count; + data += ccw->count; + } + if (&last_ccw[-1] == &request->cpaddr[1] && + request->rescnt == last_ccw[-1].count) + rc = 0; + else + rc = read - request->rescnt; } tape_free_request(request); return rc; @@ -158,10 +174,12 @@ tapechar_read(struct file *filp, char __user *data, size_t count, loff_t *ppos) static ssize_t tapechar_write(struct file *filp, const char __user *data, size_t count, loff_t *ppos) { - struct tape_device *device; struct tape_request *request; + struct ccw1 *ccw, *last_ccw; + struct tape_device *device; + struct idal_buffer **ibs; + size_t written = 0; size_t block_size; - size_t written; int nblocks; int i, rc; @@ -185,31 +203,41 @@ tapechar_write(struct file *filp, const char __user *data, size_t count, loff_t if (rc) return rc; - DBF_EVENT(6,"TCHAR:nbytes: %lx\n", block_size); + DBF_EVENT(6, "TCHAR:nbytes: %lx\n", block_size); DBF_EVENT(6, "TCHAR:nblocks: %x\n", nblocks); /* Let the discipline build the ccw chain. */ request = device->discipline->write_block(device); if (IS_ERR(request)) return PTR_ERR(request); - rc = 0; - written = 0; + for (i = 0; i < nblocks; i++) { - /* Copy data from user space to idal buffer. */ - if (idal_buffer_from_user(*device->char_data.ibs, - data, block_size)) { - rc = -EFAULT; - break; + size_t wbytes = 0; /* Used to trace written data in dbf */ + + ibs = device->char_data.ibs; + while (ibs && *ibs) { + if (idal_buffer_from_user(*ibs, data, (*ibs)->size)) { + rc = -EFAULT; + goto out; + } + data += (*ibs)->size; + ibs++; } rc = tape_do_io(device, request); if (rc) - break; - DBF_EVENT(6, "TCHAR:wbytes: %lx\n", - block_size - request->rescnt); - written += block_size - request->rescnt; + goto out; + + /* Channel Program Address (cpa) points to last CCW + 8 */ + last_ccw = dma32_to_virt(request->irb.scsw.cmd.cpa); + ccw = request->cpaddr; + while (++ccw < last_ccw) + wbytes += ccw->count; + DBF_EVENT(6, "TCHAR:wbytes: %lx\n", wbytes - request->rescnt); + written += wbytes - request->rescnt; if (request->rescnt != 0) break; - data += block_size; } + +out: tape_free_request(request); if (rc == -ENOSPC) { /* diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c index 304c6eae139c..ab1a2dc7d711 100644 --- a/drivers/s390/char/tape_core.c +++ b/drivers/s390/char/tape_core.c @@ -1129,9 +1129,10 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb) } /* May be an unsolicited irq */ - if(request != NULL) + if (request != NULL) { request->rescnt = irb->scsw.cmd.count; - else if ((irb->scsw.cmd.dstat == 0x85 || irb->scsw.cmd.dstat == 0x80) && + memcpy(&request->irb, irb, sizeof(*irb)); + } else if ((irb->scsw.cmd.dstat == 0x85 || irb->scsw.cmd.dstat == 0x80) && !list_empty(&device->req_queue)) { /* Not Ready to Ready after long busy ? */ struct tape_request *req; diff --git a/drivers/s390/char/tape_std.c b/drivers/s390/char/tape_std.c index 5f3646f78bfa..4e1c52313fbc 100644 --- a/drivers/s390/char/tape_std.c +++ b/drivers/s390/char/tape_std.c @@ -630,16 +630,23 @@ struct tape_request * tape_std_read_block(struct tape_device *device) { struct tape_request *request; + struct idal_buffer **ibs; + struct ccw1 *ccw; + size_t count; - request = tape_alloc_request(2, 0); + ibs = device->char_data.ibs; + count = idal_buffer_array_size(ibs); + request = tape_alloc_request(count + 1 /* MODE_SET_DB */, 0); if (IS_ERR(request)) { DBF_EXCEPTION(6, "xrbl fail"); return request; } request->op = TO_RFO; - tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte); - tape_ccw_end_idal(request->cpaddr + 1, READ_FORWARD, - *device->char_data.ibs); + ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte); + while (count-- > 1) + ccw = tape_ccw_dc_idal(ccw, READ_FORWARD, *ibs++); + tape_ccw_end_idal(ccw, READ_FORWARD, *ibs); + DBF_EVENT(6, "xrbl ccwg\n"); return request; } @@ -651,16 +658,23 @@ struct tape_request * tape_std_write_block(struct tape_device *device) { struct tape_request *request; + struct idal_buffer **ibs; + struct ccw1 *ccw; + size_t count; - request = tape_alloc_request(2, 0); + count = idal_buffer_array_size(device->char_data.ibs); + request = tape_alloc_request(count + 1 /* MODE_SET_DB */, 0); if (IS_ERR(request)) { DBF_EXCEPTION(6, "xwbl fail\n"); return request; } request->op = TO_WRI; - tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte); - tape_ccw_end_idal(request->cpaddr + 1, WRITE_CMD, - *device->char_data.ibs); + ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte); + ibs = device->char_data.ibs; + while (count-- > 1) + ccw = tape_ccw_dc_idal(ccw, WRITE_CMD, *ibs++); + tape_ccw_end_idal(ccw, WRITE_CMD, *ibs); + DBF_EVENT(6, "xwbl ccwg\n"); return request; } diff --git a/drivers/s390/char/tape_std.h b/drivers/s390/char/tape_std.h index eefeb5484214..2cf9f725b3b3 100644 --- a/drivers/s390/char/tape_std.h +++ b/drivers/s390/char/tape_std.h @@ -14,10 +14,9 @@ #include /* - * Biggest block size to handle. Currently 64K because we only build - * channel programs without data chaining. + * Biggest block size of 256K to handle. */ -#define MAX_BLOCKSIZE 65535 +#define MAX_BLOCKSIZE 262144 /* * The CCW commands for the Tape type of command. From 215231deeadd5942ce9fd61ea420c2c2105f6459 Mon Sep 17 00:00:00 2001 From: Josephine Pfeiffer Date: Sat, 18 Oct 2025 19:05:21 +0200 Subject: [PATCH 22/92] s390/ptdump: Use seq_puts() in pt_dump_seq_puts() macro The pt_dump_seq_puts() macro incorrectly uses seq_printf() instead of seq_puts(). This is both a performance issue and conceptually wrong, as the macro name suggests plain string output (puts) but the implementation uses formatted output (printf). The macro is used in dump_pagetables.c:67-68 and 131 to output constant strings. Using seq_printf() adds unnecessary overhead for format string parsing. Signed-off-by: Josephine Pfeiffer Signed-off-by: Heiko Carstens --- arch/s390/mm/dump_pagetables.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/mm/dump_pagetables.c b/arch/s390/mm/dump_pagetables.c index 9af2aae0a515..3692f9d20f0d 100644 --- a/arch/s390/mm/dump_pagetables.c +++ b/arch/s390/mm/dump_pagetables.c @@ -51,7 +51,7 @@ struct pg_state { struct seq_file *__m = (m); \ \ if (__m) \ - seq_printf(__m, fmt); \ + seq_puts(__m, fmt); \ }) static void print_prot(struct seq_file *m, unsigned int pr, int level) From 507cff242a98a9712081197d63e0fdc99d9ed3dd Mon Sep 17 00:00:00 2001 From: Harald Freudenberger Date: Fri, 17 Oct 2025 12:14:13 +0200 Subject: [PATCH 23/92] s390/zcrypt: Rework zcrypt request and reply trace event definition This is a slight rework of the s390_zcrypt_req and s390_zcrypt_rep trace event: - the psmid has been added to the s390_zcrypt_rep - "dev" renamed to "card" - "domain" renamed to "dom" The motivation of these changes is to make these traces more aligned to new upcoming traces for AP bus related trace events. Additionally the psmid is needed to match the reply (and thus indirect the request) to AP bus related trace events where only the psmid is unique identifying AP messages. Signed-off-by: Harald Freudenberger Reviewed-by: Anthony Krowiak Reviewed-by: Holger Dengler Signed-off-by: Heiko Carstens --- arch/s390/include/asm/trace/zcrypt.h | 44 +++++++++++++++------------- drivers/s390/crypto/zcrypt_api.c | 15 ++++++---- 2 files changed, 34 insertions(+), 25 deletions(-) diff --git a/arch/s390/include/asm/trace/zcrypt.h b/arch/s390/include/asm/trace/zcrypt.h index 457ddaa99e19..bfb01e335f31 100644 --- a/arch/s390/include/asm/trace/zcrypt.h +++ b/arch/s390/include/asm/trace/zcrypt.h @@ -2,7 +2,7 @@ /* * Tracepoint definitions for the s390 zcrypt device driver * - * Copyright IBM Corp. 2016 + * Copyright IBM Corp. 2016,2025 * Author(s): Harald Freudenberger * * Currently there are two tracepoint events defined here. @@ -73,14 +73,15 @@ TRACE_EVENT(s390_zcrypt_req, /** * trace_s390_zcrypt_rep - zcrypt reply tracepoint function - * @ptr: Address of the local buffer where the request from userspace - * is stored. Can be used as a unique id to match together - * request and reply. - * @fc: Function code. - * @rc: The bare returncode as returned by the device driver ioctl - * function. - * @dev: The adapter nr where this request was actually processed. - * @dom: Domain id of the device where this request was processed. + * @ptr: Address of the local buffer where the request from userspace + * is stored. Can be used as a unique id to match together + * request and reply. + * @fc: Function code. + * @rc: The bare returncode as returned by the device driver ioctl + * function. + * @card: The adapter nr where this request was actually processed. + * @dom: Domain id of the device where this request was processed. + * @psmid: Unique id identifying this request/reply. * * Called upon recognising the reply from the crypto adapter. This * message may act as the exit timestamp for the request but also @@ -88,26 +89,29 @@ TRACE_EVENT(s390_zcrypt_req, * and the returncode from the device driver. */ TRACE_EVENT(s390_zcrypt_rep, - TP_PROTO(void *ptr, u32 fc, u32 rc, u16 dev, u16 dom), - TP_ARGS(ptr, fc, rc, dev, dom), + TP_PROTO(void *ptr, u32 fc, u32 rc, u16 card, u16 dom, u64 psmid), + TP_ARGS(ptr, fc, rc, card, dom, psmid), TP_STRUCT__entry( __field(void *, ptr) __field(u32, fc) __field(u32, rc) - __field(u16, device) - __field(u16, domain)), + __field(u16, card) + __field(u16, dom) + __field(u64, psmid)), TP_fast_assign( __entry->ptr = ptr; __entry->fc = fc; __entry->rc = rc; - __entry->device = dev; - __entry->domain = dom;), - TP_printk("ptr=%p fc=0x%04x rc=%d dev=0x%02hx domain=0x%04hx", + __entry->card = card; + __entry->dom = dom; + __entry->psmid = psmid;), + TP_printk("ptr=%p fc=0x%04x rc=%d card=%u dom=%u psmid=0x%016lx", __entry->ptr, - (unsigned int) __entry->fc, - (int) __entry->rc, - (unsigned short) __entry->device, - (unsigned short) __entry->domain) + (unsigned int)__entry->fc, + (int)__entry->rc, + (unsigned short)__entry->card, + (unsigned short)__entry->dom, + (unsigned long)__entry->psmid) ); #endif /* _TRACE_S390_ZCRYPT_H */ diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c index 4e6bf1cb3475..2b67b6b02ad5 100644 --- a/drivers/s390/crypto/zcrypt_api.c +++ b/drivers/s390/crypto/zcrypt_api.c @@ -740,7 +740,8 @@ static long zcrypt_rsa_modexpo(struct ap_perms *perms, tr->last_qid = qid; } trace_s390_zcrypt_rep(mex, func_code, rc, - AP_QID_CARD(qid), AP_QID_QUEUE(qid)); + AP_QID_CARD(qid), AP_QID_QUEUE(qid), + ap_msg.psmid); return rc; } @@ -845,7 +846,8 @@ static long zcrypt_rsa_crt(struct ap_perms *perms, tr->last_qid = qid; } trace_s390_zcrypt_rep(crt, func_code, rc, - AP_QID_CARD(qid), AP_QID_QUEUE(qid)); + AP_QID_CARD(qid), AP_QID_QUEUE(qid), + ap_msg.psmid); return rc; } @@ -980,7 +982,8 @@ static long _zcrypt_send_cprb(u32 xflags, struct ap_perms *perms, tr->last_qid = qid; } trace_s390_zcrypt_rep(xcrb, func_code, rc, - AP_QID_CARD(qid), AP_QID_QUEUE(qid)); + AP_QID_CARD(qid), AP_QID_QUEUE(qid), + ap_msg.psmid); return rc; } @@ -1182,7 +1185,8 @@ static long _zcrypt_send_ep11_cprb(u32 xflags, struct ap_perms *perms, tr->last_qid = qid; } trace_s390_zcrypt_rep(xcrb, func_code, rc, - AP_QID_CARD(qid), AP_QID_QUEUE(qid)); + AP_QID_CARD(qid), AP_QID_QUEUE(qid), + ap_msg.psmid); return rc; } @@ -1274,7 +1278,8 @@ static long zcrypt_rng(char *buffer) out: ap_release_apmsg(&ap_msg); trace_s390_zcrypt_rep(buffer, func_code, rc, - AP_QID_CARD(qid), AP_QID_QUEUE(qid)); + AP_QID_CARD(qid), AP_QID_QUEUE(qid), + ap_msg.psmid); return rc; } From 7f124d78d4347a61dbb87012dd519ffa05bc755d Mon Sep 17 00:00:00 2001 From: Harald Freudenberger Date: Fri, 17 Oct 2025 12:14:14 +0200 Subject: [PATCH 24/92] s390/ap: Extend struct ap_queue_status with some convenience fields Sometimes there is a different view of the AP status word needed. So here is slight rework of the struct ap_queue_status to open up the possibility to have different ways of accessing the AP status bits and fields. The new struct ap_queue_status struct ap_queue_status { union { unsigned int value : 32; struct { unsigned int status_bits : 8; unsigned int rc : 8; unsigned int : 16; }; struct { unsigned int queue_empty : 1; unsigned int replies_waiting : 1; unsigned int queue_full : 1; unsigned int : 3; unsigned int async : 1; unsigned int irq_enabled : 1; unsigned int response_code : 8; unsigned int : 16; }; }; }; comprises the old struct ap_queue_status but extends it to have this also accessible as an unsigned int required for example for a simple print or trace of the whole value. Note that this rework is fully backward compatible to the existing code exploiting the struct ap_queue_status. Signed-off-by: Harald Freudenberger Reviewed-by: Anthony Krowiak Reviewed-by: Holger Dengler Signed-off-by: Heiko Carstens --- arch/s390/include/asm/ap.h | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/arch/s390/include/asm/ap.h b/arch/s390/include/asm/ap.h index 56817990c73d..b24459f692fa 100644 --- a/arch/s390/include/asm/ap.h +++ b/arch/s390/include/asm/ap.h @@ -38,16 +38,30 @@ typedef unsigned int ap_qid_t; * The ap queue status word is returned by all three AP functions * (PQAP, NQAP and DQAP). There's a set of flags in the first * byte, followed by a 1 byte response code. + * + * For convenience the 'value' field is a 32 bit access of the + * whole status and the 'status_bits' and 'rc' fields comprise + * the leftmost 8 status bits and the response_code. */ struct ap_queue_status { - unsigned int queue_empty : 1; - unsigned int replies_waiting : 1; - unsigned int queue_full : 1; - unsigned int : 3; - unsigned int async : 1; - unsigned int irq_enabled : 1; - unsigned int response_code : 8; - unsigned int : 16; + union { + unsigned int value : 32; + struct { + unsigned int status_bits : 8; + unsigned int rc : 8; + unsigned int : 16; + }; + struct { + unsigned int queue_empty : 1; + unsigned int replies_waiting : 1; + unsigned int queue_full : 1; + unsigned int : 3; + unsigned int async : 1; + unsigned int irq_enabled : 1; + unsigned int response_code : 8; + unsigned int : 16; + }; + }; }; /* From 9c11918040d6aa19c407ead4dc86b65e664f401f Mon Sep 17 00:00:00 2001 From: Harald Freudenberger Date: Fri, 17 Oct 2025 12:14:15 +0200 Subject: [PATCH 25/92] s390/ap: Introduce new AP nqap and dqap trace events Introduce two new AP bus related tracepoint events: - There is a tracepoint s390_ap_nqap event immediately after a request has been pushed into the AP firmware queue with the NQAP AP command. - The other tracepoint s390_ap_dqap event fires immediately after a reply has been pulled out of the AP firmware queue via DQAP AP command. Both events are triggered unconditional and may need filtering. Filtering can be done based on the status value which is part of the nqap and dqap trace. So for example a echo "!(status & 0x00ff0000)" >.../s390_ap_dqap/filter filters out all trace events which have a response_code != 0 leaving just the successful nqap and dqap invocations. The idea of these two trace events focuses on performance to measure the runtime of a crypto request/reply as close as possible at the firmware level. In combination with the two zcrypt tracepoints (see the zcrypt.h trace event definition file) this gives measurement data about the runtime of a request/reply within the zcrpyt and AP bus layer. However, with having the status of these AP commands in hand also other usage may be possible. Signed-off-by: Harald Freudenberger Reviewed-by: Holger Dengler Signed-off-by: Heiko Carstens --- arch/s390/include/asm/trace/ap.h | 87 ++++++++++++++++++++++++++++++++ drivers/s390/crypto/ap_queue.c | 19 ++++++- 2 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 arch/s390/include/asm/trace/ap.h diff --git a/arch/s390/include/asm/trace/ap.h b/arch/s390/include/asm/trace/ap.h new file mode 100644 index 000000000000..5c2e6c664b4d --- /dev/null +++ b/arch/s390/include/asm/trace/ap.h @@ -0,0 +1,87 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Tracepoint definitions for s390 ap bus related trace events + * + * There are two AP bus related tracepoint events defined here: + * There is a tracepoint s390_ap_nqap event immediately after a request + * has been pushed into the AP firmware queue with the NQAP AP command. + * The other tracepoint s390_ap_dqap event fires immediately after a + * reply has been pulled out of the AP firmware queue via DQAP AP command. + * The idea of these two trace events focuses on performance to measure + * the runtime of a crypto request/reply as close as possible at the + * firmware level. In combination with the two zcrypt tracepoints (see the + * zcrypt.h trace event definition file) this gives measurement data about + * the runtime of a request/reply within the zcrpyt and AP bus layer. + */ + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM s390 + +#if !defined(_TRACE_S390_AP_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_S390_AP_H + +#include + +DECLARE_EVENT_CLASS(s390_ap_nqapdqap_template, + TP_PROTO(u16 card, u16 dom, u32 status, u64 psmid), + TP_ARGS(card, dom, status, psmid), + TP_STRUCT__entry( + __field(u16, card) + __field(u16, dom) + __field(u32, status) + __field(u64, psmid)), + TP_fast_assign( + __entry->card = card; + __entry->dom = dom; + __entry->status = status; + __entry->psmid = psmid;), + TP_printk("card=%u dom=%u status=0x%08x psmid=0x%016lx", + (unsigned short)__entry->card, + (unsigned short)__entry->dom, + (unsigned int)__entry->status, + (unsigned long)__entry->psmid) +); + +/** + * trace_s390_ap_nqap - ap msg nqap tracepoint function + * @card: Crypto card number addressed. + * @dom: Domain within the crypto card addressed. + * @status: AP queue status (GR1 on return of nqap). + * @psmid: Unique id identifying this request/reply. + * + * Called immediately after a request has been enqueued into + * the AP firmware queue with the NQAP command. + */ +DEFINE_EVENT(s390_ap_nqapdqap_template, + s390_ap_nqap, + TP_PROTO(u16 card, u16 dom, u32 status, u64 psmid), + TP_ARGS(card, dom, status, psmid) +); + +/** + * trace_s390_ap_dqap - ap msg dqap tracepoint function + * @card: Crypto card number addressed. + * @dom: Domain within the crypto card addressed. + * @status: AP queue status (GR1 on return of dqap). + * @psmid: Unique id identifying this request/reply. + * + * Called immediately after a reply has been dequeued from + * the AP firmware queue with the DQAP command. + */ +DEFINE_EVENT(s390_ap_nqapdqap_template, + s390_ap_dqap, + TP_PROTO(u16 card, u16 dom, u32 status, u64 psmid), + TP_ARGS(card, dom, status, psmid) +); + +#endif /* _TRACE_S390_AP_H */ + +/* This part must be outside protection */ + +#undef TRACE_INCLUDE_PATH +#undef TRACE_INCLUDE_FILE + +#define TRACE_INCLUDE_PATH asm/trace +#define TRACE_INCLUDE_FILE ap + +#include diff --git a/drivers/s390/crypto/ap_queue.c b/drivers/s390/crypto/ap_queue.c index 8977866fab1b..579e421d134c 100644 --- a/drivers/s390/crypto/ap_queue.c +++ b/drivers/s390/crypto/ap_queue.c @@ -14,9 +14,15 @@ #include #include +#define CREATE_TRACE_POINTS +#include + #include "ap_bus.h" #include "ap_debug.h" +EXPORT_TRACEPOINT_SYMBOL(s390_ap_nqap); +EXPORT_TRACEPOINT_SYMBOL(s390_ap_dqap); + static void __ap_flush_queue(struct ap_queue *aq); /* @@ -98,9 +104,17 @@ static inline struct ap_queue_status __ap_send(ap_qid_t qid, unsigned long psmid, void *msg, size_t msglen, int special) { + struct ap_queue_status status; + if (special) qid |= 0x400000UL; - return ap_nqap(qid, psmid, msg, msglen); + + status = ap_nqap(qid, psmid, msg, msglen); + + trace_s390_ap_nqap(AP_QID_CARD(qid), AP_QID_QUEUE(qid), + status.value, psmid); + + return status; } /* State machine definitions and helpers */ @@ -140,6 +154,9 @@ static struct ap_queue_status ap_sm_recv(struct ap_queue *aq) parts++; } while (status.response_code == 0xFF && resgr0 != 0); + trace_s390_ap_dqap(AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid), + status.value, aq->reply->psmid); + switch (status.response_code) { case AP_RESPONSE_NORMAL: print_hex_dump_debug("aprpl: ", DUMP_PREFIX_ADDRESS, 16, 1, From 564ebcae6a0b4a69de79cd40c04ccd1d572e6ecf Mon Sep 17 00:00:00 2001 From: Gerd Bayer Date: Tue, 21 Oct 2025 10:57:16 +0200 Subject: [PATCH 26/92] s390/pci: Highlight failure to enable PCI function Emit an error log when a PCI function cannot be enabled for use, despite being reported as configured to the system. This brings to attention situations where functions might go missing without notice. Going unnoticed is less likely when functions are added to the system through hotplug, but will produce the same error log. Reviewed-by: Niklas Schnelle Reviewed-by: Alexandra Winter Signed-off-by: Gerd Bayer Signed-off-by: Heiko Carstens --- arch/s390/pci/pci_bus.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/s390/pci/pci_bus.c b/arch/s390/pci/pci_bus.c index 45a1c36c5a54..be8c697fea0c 100644 --- a/arch/s390/pci/pci_bus.c +++ b/arch/s390/pci/pci_bus.c @@ -45,8 +45,10 @@ static int zpci_bus_prepare_device(struct zpci_dev *zdev) if (!zdev_enabled(zdev)) { rc = zpci_enable_device(zdev); - if (rc) + if (rc) { + pr_err("Enabling PCI function %08x failed\n", zdev->fid); return rc; + } } if (!zdev->has_resources) { From 07a75d08cfa1b883a6e1256666e5f0617ee99231 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 20 Oct 2025 16:17:54 +0200 Subject: [PATCH 27/92] s390/smp: Fix fallback CPU detection In case SCLP CPU detection does not work a fallback mechanism using SIGP is in place. Since a cleanup this does not work correctly anymore: new CPUs are only considered if their type matches the boot CPU. Before the cleanup the information if a CPU type should be considered was also part of a structure generated by the fallback mechanism and indicated that a CPU type should not be considered when adding CPUs. Since the rework a global SCLP state is used instead. If the global SCLP state indicates that the CPU type should be considered and the fallback mechanism is used, there may be a mismatch with CPU types if CPUs are added. This can lead to a system with only a single CPU even tough there are many more CPUs. Address this by simply copying the boot cpu type into the generated data structure from the fallback mechanism. Reported-by: Alexander Egorenkov Fixes: d08d94306e90 ("s390/smp: cleanup core vs. cpu in the SCLP interface") Reviewed-by: Mete Durlu Signed-off-by: Heiko Carstens --- arch/s390/kernel/smp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index da84c0dc6b7e..70df4ca5d443 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -697,6 +697,7 @@ static void __ref smp_get_core_info(struct sclp_core_info *info, int early) continue; info->core[info->configured].core_id = address >> smp_cpu_mt_shift; + info->core[info->configured].type = boot_core_type; info->configured++; } info->combined = info->configured; From 51d921a613b1e89a47c2c262bbef1d7b0b032ac7 Mon Sep 17 00:00:00 2001 From: Harald Freudenberger Date: Fri, 17 Oct 2025 16:51:52 +0200 Subject: [PATCH 28/92] s390/ap: Expose ap_bindings_complete_count counter via sysfs The AP bus udev event BINDINGS=complete is sent out when the first time all devices detected by the AP bus scan have been bound to device drivers. This is the ideal time to for example change the AP bus masks apmask and aqmask to re-establish a persistent change on the decision about which cards/domains should be available for the host and which should go into the pool for kvm guests. However, if exactly this initial udev event is sent out early in the boot process a udev rule may not have been established yet and thus this event will never be recognized. To have some indication about if the AP bus binding complete has already happened, the internal ap_bindings_complete_count counter is exposed via sysfs with this patch. Suggested-by: Matthew Rosato Signed-off-by: Harald Freudenberger Tested-by: Matthew Rosato Signed-off-by: Heiko Carstens --- drivers/s390/crypto/ap_bus.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 65f1a127cc3f..c8589ac744e4 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -1650,6 +1650,15 @@ static ssize_t bindings_show(const struct bus_type *bus, char *buf) static BUS_ATTR_RO(bindings); +static ssize_t bindings_complete_count_show(const struct bus_type *bus, + char *buf) +{ + return sysfs_emit(buf, "%llu\n", + atomic64_read(&ap_bindings_complete_count)); +} + +static BUS_ATTR_RO(bindings_complete_count); + static ssize_t features_show(const struct bus_type *bus, char *buf) { int n = 0; @@ -1690,6 +1699,7 @@ static struct attribute *ap_bus_attrs[] = { &bus_attr_aqmask.attr, &bus_attr_scans.attr, &bus_attr_bindings.attr, + &bus_attr_bindings_complete_count.attr, &bus_attr_features.attr, NULL, }; From f25d952ab63f5742c343c332879d88fd49c589c3 Mon Sep 17 00:00:00 2001 From: Jens Remus Date: Thu, 23 Oct 2025 11:23:58 +0200 Subject: [PATCH 29/92] s390/ptrace: Explicitly include The psw_bits() macro makes use of typecheck() without that typecheck.h is included. Add the missing include to avoid potential future compile problems. [hca@linux.ibm.com: change commit message] Signed-off-by: Jens Remus Signed-off-by: Heiko Carstens --- arch/s390/include/asm/ptrace.h | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h index dfa770b15fad..8fae167c1bd6 100644 --- a/arch/s390/include/asm/ptrace.h +++ b/arch/s390/include/asm/ptrace.h @@ -8,6 +8,7 @@ #define _S390_PTRACE_H #include +#include #include #include #include From 020d5dc57874e58d3ebae398f3fe258f029e3d06 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 24 Oct 2025 12:24:33 +0200 Subject: [PATCH 30/92] s390/ap: Don't leak debug feature files if AP instructions are not available If no AP instructions are available the AP bus module leaks registered debug feature files. Change function call order to fix this. Fixes: cccd85bfb7bf ("s390/zcrypt: Rework debug feature invocations.") Reviewed-by: Harald Freudenberger Signed-off-by: Heiko Carstens --- drivers/s390/crypto/ap_bus.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index c8589ac744e4..82f4ac97fe97 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -2494,15 +2494,15 @@ static int __init ap_module_init(void) { int rc; - rc = ap_debug_init(); - if (rc) - return rc; - if (!ap_instructions_available()) { pr_warn("The hardware system does not support AP instructions\n"); return -ENODEV; } + rc = ap_debug_init(); + if (rc) + return rc; + /* init ap_queue hashtable */ hash_init(ap_queues); From 73c4b5d728265a6b019c3aba6d7ea2329ca4785a Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 3 Nov 2025 14:39:26 +0100 Subject: [PATCH 31/92] s390: Add Dat-Enhancement facility 1 to architecture level set Add the Dat-Enhancement facility 1 to the list of facilities which are required to start the kernel. The facility provides the CSPG and IDTE instructions. In particular the CSPG instruction can be used to replace a valid page table entry with a different page table entry, which also differs in the page frame real address. Without the CSPG instruction it is possible to use the CSP instruction to change valid page table entries, however it only allows to change the lower or higher 32 bits of such entries, which means it cannot be used to change the page frame real address of valid page table entries. Given that there is code around (e.g. HugeTLB vmemmap optimization) which requires to change valid page table entries of the kernel mapping, without the detour over an invalid page table entry, make the CSPG instruction unconditionally available. The Dat-Enhancement facility 1 is available since z990, which is older than the currently supported minimum architecture (z10). Therefore adding this to the architecture level set shouldn't cause any problems. Reviewed-by: Alexander Gordeev Reviewed-by: Claudio Imbrenda Signed-off-by: Heiko Carstens --- arch/s390/tools/gen_facilities.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/s390/tools/gen_facilities.c b/arch/s390/tools/gen_facilities.c index d5c68ade71ab..2d28a569f793 100644 --- a/arch/s390/tools/gen_facilities.c +++ b/arch/s390/tools/gen_facilities.c @@ -29,6 +29,7 @@ static struct facility_def facility_defs[] = { .bits = (int[]){ 0, /* N3 instructions */ 1, /* z/Arch mode installed */ + 3, /* dat-enhancement 1 */ 18, /* long displacement facility */ 21, /* extended-immediate facility */ 25, /* store clock fast */ From 220d8e10d69a30db7d9cbd0d3483a739768ed16c Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 3 Nov 2025 14:39:27 +0100 Subject: [PATCH 32/92] s390/mm: Remove cpu_has_idte() Remove cpu_has_idte(). The IDTE instruction is part of the Dat-Enhancement facility 1, which is always available. Therefore remove the helper and now superfluous code. Acked-by: Alexander Gordeev Reviewed-by: Claudio Imbrenda Signed-off-by: Heiko Carstens --- arch/s390/include/asm/cpufeature.h | 1 - arch/s390/include/asm/tlbflush.h | 7 ++----- arch/s390/mm/gmap.c | 15 ++++----------- arch/s390/mm/pageattr.c | 4 +--- arch/s390/mm/pgtable.c | 14 ++------------ 5 files changed, 9 insertions(+), 32 deletions(-) diff --git a/arch/s390/include/asm/cpufeature.h b/arch/s390/include/asm/cpufeature.h index 6c6a99660e78..d6fb999c8c6d 100644 --- a/arch/s390/include/asm/cpufeature.h +++ b/arch/s390/include/asm/cpufeature.h @@ -27,7 +27,6 @@ int cpu_have_feature(unsigned int nr); #define cpu_has_edat1() test_facility(8) #define cpu_has_edat2() test_facility(78) #define cpu_has_gs() test_facility(133) -#define cpu_has_idte() test_facility(3) #define cpu_has_nx() test_facility(130) #define cpu_has_rdp() test_facility(194) #define cpu_has_seq_insn() test_facility(85) diff --git a/arch/s390/include/asm/tlbflush.h b/arch/s390/include/asm/tlbflush.h index 75491baa2197..c7f04f9e99b3 100644 --- a/arch/s390/include/asm/tlbflush.h +++ b/arch/s390/include/asm/tlbflush.h @@ -54,7 +54,7 @@ static inline void __tlb_flush_mm(struct mm_struct *mm) cpumask_copy(mm_cpumask(mm), &mm->context.cpu_attach_mask); barrier(); gmap_asce = READ_ONCE(mm->context.gmap_asce); - if (cpu_has_idte() && gmap_asce != -1UL) { + if (gmap_asce != -1UL) { if (gmap_asce) __tlb_flush_idte(gmap_asce); __tlb_flush_idte(mm->context.asce); @@ -68,10 +68,7 @@ static inline void __tlb_flush_mm(struct mm_struct *mm) static inline void __tlb_flush_kernel(void) { - if (cpu_has_idte()) - __tlb_flush_idte(init_mm.context.asce); - else - __tlb_flush_global(); + __tlb_flush_idte(init_mm.context.asce); } static inline void __tlb_flush_mm_lazy(struct mm_struct * mm) diff --git a/arch/s390/mm/gmap.c b/arch/s390/mm/gmap.c index 8ff6bba107e8..f9174be33023 100644 --- a/arch/s390/mm/gmap.c +++ b/arch/s390/mm/gmap.c @@ -138,10 +138,7 @@ EXPORT_SYMBOL_GPL(gmap_create); static void gmap_flush_tlb(struct gmap *gmap) { - if (cpu_has_idte()) - __tlb_flush_idte(gmap->asce); - else - __tlb_flush_global(); + __tlb_flush_idte(gmap->asce); } static void gmap_radix_tree_free(struct radix_tree_root *root) @@ -1988,10 +1985,8 @@ static void gmap_pmdp_xchg(struct gmap *gmap, pmd_t *pmdp, pmd_t new, if (machine_has_tlb_guest()) __pmdp_idte(gaddr, (pmd_t *)pmdp, IDTE_GUEST_ASCE, gmap->asce, IDTE_GLOBAL); - else if (cpu_has_idte()) - __pmdp_idte(gaddr, (pmd_t *)pmdp, 0, 0, IDTE_GLOBAL); else - __pmdp_csp(pmdp); + __pmdp_idte(gaddr, (pmd_t *)pmdp, 0, 0, IDTE_GLOBAL); set_pmd(pmdp, new); } @@ -2066,7 +2061,7 @@ void gmap_pmdp_idte_local(struct mm_struct *mm, unsigned long vmaddr) if (machine_has_tlb_guest()) __pmdp_idte(gaddr, pmdp, IDTE_GUEST_ASCE, gmap->asce, IDTE_LOCAL); - else if (cpu_has_idte()) + else __pmdp_idte(gaddr, pmdp, 0, 0, IDTE_LOCAL); *pmdp = __pmd(_SEGMENT_ENTRY_EMPTY); } @@ -2099,10 +2094,8 @@ void gmap_pmdp_idte_global(struct mm_struct *mm, unsigned long vmaddr) if (machine_has_tlb_guest()) __pmdp_idte(gaddr, pmdp, IDTE_GUEST_ASCE, gmap->asce, IDTE_GLOBAL); - else if (cpu_has_idte()) - __pmdp_idte(gaddr, pmdp, 0, 0, IDTE_GLOBAL); else - __pmdp_csp(pmdp); + __pmdp_idte(gaddr, pmdp, 0, 0, IDTE_GLOBAL); *pmdp = __pmd(_SEGMENT_ENTRY_EMPTY); } spin_unlock(&gmap->guest_table_lock); diff --git a/arch/s390/mm/pageattr.c b/arch/s390/mm/pageattr.c index 348e759840e7..3042647c9dbf 100644 --- a/arch/s390/mm/pageattr.c +++ b/arch/s390/mm/pageattr.c @@ -78,10 +78,8 @@ static void pgt_set(unsigned long *old, unsigned long new, unsigned long addr, } table = (unsigned long *)((unsigned long)old & mask); crdte(*old, new, table, dtt, addr, get_lowcore()->kernel_asce.val); - } else if (cpu_has_idte()) { - cspg(old, *old, new); } else { - csp((unsigned int *)old + 1, *old, new); + cspg(old, *old, new); } } diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 0fde20bbc50b..36305a357cb8 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -360,14 +360,10 @@ static inline void pmdp_idte_global(struct mm_struct *mm, mm->context.asce, IDTE_GLOBAL); if (mm_has_pgste(mm) && mm->context.allow_gmap_hpage_1m) gmap_pmdp_idte_global(mm, addr); - } else if (cpu_has_idte()) { + } else { __pmdp_idte(addr, pmdp, 0, 0, IDTE_GLOBAL); if (mm_has_pgste(mm) && mm->context.allow_gmap_hpage_1m) gmap_pmdp_idte_global(mm, addr); - } else { - __pmdp_csp(pmdp); - if (mm_has_pgste(mm) && mm->context.allow_gmap_hpage_1m) - gmap_pmdp_csp(mm, addr); } } @@ -487,14 +483,8 @@ static inline void pudp_idte_global(struct mm_struct *mm, if (machine_has_tlb_guest()) __pudp_idte(addr, pudp, IDTE_NODAT | IDTE_GUEST_ASCE, mm->context.asce, IDTE_GLOBAL); - else if (cpu_has_idte()) - __pudp_idte(addr, pudp, 0, 0, IDTE_GLOBAL); else - /* - * Invalid bit position is the same for pmd and pud, so we can - * reuse _pmd_csp() here - */ - __pmdp_csp((pmd_t *) pudp); + __pudp_idte(addr, pudp, 0, 0, IDTE_GLOBAL); } static inline pud_t pudp_flush_direct(struct mm_struct *mm, From 68807a894f0c1cb294a568d8e53c1a77ceaf0c6f Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 3 Nov 2025 14:39:28 +0100 Subject: [PATCH 33/92] s390/mm: Replace the CSP instruction with CSPG The CSPG instruction is part of the Dat-Enhancement facility 1, which is always available. Given that it can be used everywhere where also the CSP instruction can be used, replace CSP with CSPG everywhere. This allows to remove the csp() inline assembly. Also remove the unused gmap_pmdp_csp() function. Acked-by: Alexander Gordeev Reviewed-by: Claudio Imbrenda Signed-off-by: Heiko Carstens --- arch/s390/include/asm/pgtable.h | 19 +++---------------- arch/s390/include/asm/tlbflush.h | 4 ++-- arch/s390/mm/gmap.c | 13 +------------ 3 files changed, 6 insertions(+), 30 deletions(-) diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index b7100c6a4054..bb915cbffc7b 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -648,18 +648,6 @@ static inline int mm_uses_skeys(struct mm_struct *mm) return 0; } -static inline void csp(unsigned int *ptr, unsigned int old, unsigned int new) -{ - union register_pair r1 = { .even = old, .odd = new, }; - unsigned long address = (unsigned long)ptr | 1; - - asm volatile( - " csp %[r1],%[address]" - : [r1] "+&d" (r1.pair), "+m" (*ptr) - : [address] "d" (address) - : "cc"); -} - /** * cspg() - Compare and Swap and Purge (CSPG) * @ptr: Pointer to the value to be exchanged @@ -1402,7 +1390,6 @@ int set_pgste_bits(struct mm_struct *mm, unsigned long addr, int get_pgste(struct mm_struct *mm, unsigned long hva, unsigned long *pgstep); int pgste_perform_essa(struct mm_struct *mm, unsigned long hva, int orc, unsigned long *oldpte, unsigned long *oldpgste); -void gmap_pmdp_csp(struct mm_struct *mm, unsigned long vmaddr); void gmap_pmdp_invalidate(struct mm_struct *mm, unsigned long vmaddr); void gmap_pmdp_idte_local(struct mm_struct *mm, unsigned long vmaddr); void gmap_pmdp_idte_global(struct mm_struct *mm, unsigned long vmaddr); @@ -1692,10 +1679,10 @@ static inline pmd_t mk_pmd_phys(unsigned long physpage, pgprot_t pgprot) #endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_HUGETLB_PAGE */ -static inline void __pmdp_csp(pmd_t *pmdp) +static inline void __pmdp_cspg(pmd_t *pmdp) { - csp((unsigned int *)pmdp + 1, pmd_val(*pmdp), - pmd_val(*pmdp) | _SEGMENT_ENTRY_INVALID); + cspg((unsigned long *)pmdp, pmd_val(*pmdp), + pmd_val(*pmdp) | _SEGMENT_ENTRY_INVALID); } #define IDTE_GLOBAL 0 diff --git a/arch/s390/include/asm/tlbflush.h b/arch/s390/include/asm/tlbflush.h index c7f04f9e99b3..be8ca0d854d3 100644 --- a/arch/s390/include/asm/tlbflush.h +++ b/arch/s390/include/asm/tlbflush.h @@ -35,9 +35,9 @@ static inline void __tlb_flush_idte(unsigned long asce) */ static inline void __tlb_flush_global(void) { - unsigned int dummy = 0; + unsigned long dummy = 0; - csp(&dummy, 0, 0); + cspg(&dummy, 0, 0); } /* diff --git a/arch/s390/mm/gmap.c b/arch/s390/mm/gmap.c index f9174be33023..603d9e5febb5 100644 --- a/arch/s390/mm/gmap.c +++ b/arch/s390/mm/gmap.c @@ -2007,7 +2007,7 @@ static void gmap_pmdp_clear(struct mm_struct *mm, unsigned long vmaddr, _SEGMENT_ENTRY_GMAP_UC | _SEGMENT_ENTRY)); if (purge) - __pmdp_csp(pmdp); + __pmdp_cspg(pmdp); set_pmd(pmdp, __pmd(_SEGMENT_ENTRY_EMPTY)); } spin_unlock(&gmap->guest_table_lock); @@ -2027,17 +2027,6 @@ void gmap_pmdp_invalidate(struct mm_struct *mm, unsigned long vmaddr) } EXPORT_SYMBOL_GPL(gmap_pmdp_invalidate); -/** - * gmap_pmdp_csp - csp all affected guest pmd entries - * @mm: pointer to the process mm_struct - * @vmaddr: virtual address in the process address space - */ -void gmap_pmdp_csp(struct mm_struct *mm, unsigned long vmaddr) -{ - gmap_pmdp_clear(mm, vmaddr, 1); -} -EXPORT_SYMBOL_GPL(gmap_pmdp_csp); - /** * gmap_pmdp_idte_local - invalidate and clear a guest pmd entry * @mm: pointer to the process mm_struct From 858063c1aec837a7a500db9bd13145a17b0b7641 Mon Sep 17 00:00:00 2001 From: Bo Liu Date: Wed, 29 Oct 2025 15:19:51 +0800 Subject: [PATCH 34/92] s390: Fix double word in comments Remove the repeated word "the" in comments. Signed-off-by: Bo Liu Signed-off-by: Heiko Carstens --- arch/s390/kernel/perf_cpum_sf.c | 2 +- arch/s390/kernel/sthyi.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/s390/kernel/perf_cpum_sf.c b/arch/s390/kernel/perf_cpum_sf.c index f432869f8921..bf816b134fb1 100644 --- a/arch/s390/kernel/perf_cpum_sf.c +++ b/arch/s390/kernel/perf_cpum_sf.c @@ -1093,7 +1093,7 @@ static void perf_event_count_update(struct perf_event *event, u64 count) * combined-sampling data entry consists of a basic- and a diagnostic-sampling * data entry. The sampling function is determined by the flags in the perf * event hardware structure. The function always works with a combined-sampling - * data entry but ignores the the diagnostic portion if it is not available. + * data entry but ignores the diagnostic portion if it is not available. * * Note that the implementation focuses on basic-sampling data entries and, if * such an entry is not valid, the entire combined-sampling data entry is diff --git a/arch/s390/kernel/sthyi.c b/arch/s390/kernel/sthyi.c index f4ccdbed4b89..5eae2e25997a 100644 --- a/arch/s390/kernel/sthyi.c +++ b/arch/s390/kernel/sthyi.c @@ -253,7 +253,7 @@ static void fill_diag_mac(struct sthyi_sctns *sctns, sctns->mac.infmval1 |= MAC_CNT_VLD; } -/* Returns a pointer to the the next partition block. */ +/* Returns a pointer to the next partition block. */ static struct diag204_x_part_block *lpar_cpu_inf(struct lpar_cpu_inf *part_inf, bool this_lpar, void *diag224_buf, From f07ebfa5e48c59c41aea247982184fe956cbb756 Mon Sep 17 00:00:00 2001 From: Thorsten Blum Date: Mon, 27 Oct 2025 09:47:25 +0100 Subject: [PATCH 35/92] s390/nmi: Annotate s390_handle_damage() with __noreturn s390_handle_damage() ends by calling the non-returning function disabled_wait() and therefore also never returns. Annotate it with the __noreturn compiler attribute to improve compiler optimizations. Remove the unreachable infinite while loop. Signed-off-by: Thorsten Blum Signed-off-by: Heiko Carstens --- arch/s390/kernel/nmi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/s390/kernel/nmi.c b/arch/s390/kernel/nmi.c index 11f33243a23f..a55abbf65333 100644 --- a/arch/s390/kernel/nmi.c +++ b/arch/s390/kernel/nmi.c @@ -184,7 +184,7 @@ static notrace void nmi_print_info(void) sclp_emergency_printk(message); } -static notrace void s390_handle_damage(void) +static notrace void __noreturn s390_handle_damage(void) { struct lowcore *lc = get_lowcore(); union ctlreg0 cr0, cr0_new; @@ -214,7 +214,6 @@ static notrace void s390_handle_damage(void) lc->mcck_new_psw = psw_save; local_ctl_load(0, &cr0.reg); disabled_wait(); - while (1); } NOKPROBE_SYMBOL(s390_handle_damage); From eb3a9b405b85e872d6f3dac427b7faa01e7e724e Mon Sep 17 00:00:00 2001 From: Thorsten Blum Date: Thu, 30 Oct 2025 14:42:41 +0100 Subject: [PATCH 36/92] s390/smp: Mark pcpu_delegate() and smp_call_ipl_cpu() as __noreturn pcpu_delegate() never returns to its caller. If the target CPU is the current CPU, it calls __pcpu_delegate(), whose delegate function is not supposed to return. In any case, even if __pcpu_delegate() unexpectedly returns, pcpu_delegate() sends SIGP_STOP to the current CPU and waits in an infinite loop. Annotate pcpu_delegate() with the __noreturn attribute to improve compiler optimizations. Also annotate smp_call_ipl_cpu() accordingly since it always calls pcpu_delegate(). [hca: Merge two patches from Thorsten Blum] Signed-off-by: Thorsten Blum Signed-off-by: Heiko Carstens --- arch/s390/include/asm/smp.h | 2 +- arch/s390/kernel/smp.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/s390/include/asm/smp.h b/arch/s390/include/asm/smp.h index 03f4d01664f8..fb2bdbf35da5 100644 --- a/arch/s390/include/asm/smp.h +++ b/arch/s390/include/asm/smp.h @@ -43,7 +43,7 @@ extern int __cpu_up(unsigned int cpu, struct task_struct *tidle); extern void arch_send_call_function_single_ipi(int cpu); extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); -extern void smp_call_ipl_cpu(void (*func)(void *), void *); +extern void __noreturn smp_call_ipl_cpu(void (*func)(void *), void *data); extern void smp_emergency_stop(void); extern int smp_find_processor_id(u16 address); diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 70df4ca5d443..b0da25159f06 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -305,9 +305,9 @@ static void __pcpu_delegate(pcpu_delegate_fn *func, void *data) func(data); /* should not return */ } -static void pcpu_delegate(struct pcpu *pcpu, int cpu, - pcpu_delegate_fn *func, - void *data, unsigned long stack) +static void __noreturn pcpu_delegate(struct pcpu *pcpu, int cpu, + pcpu_delegate_fn *func, + void *data, unsigned long stack) { struct lowcore *lc, *abs_lc; unsigned int source_cpu; @@ -370,7 +370,7 @@ static int pcpu_set_smt(unsigned int mtid) /* * Call function on the ipl CPU. */ -void smp_call_ipl_cpu(void (*func)(void *), void *data) +void __noreturn smp_call_ipl_cpu(void (*func)(void *), void *data) { struct lowcore *lc = lowcore_ptr[0]; From 8840cc45209b3224cb17a44c0ff4f95760baf761 Mon Sep 17 00:00:00 2001 From: Mete Durlu Date: Wed, 5 Nov 2025 12:15:34 +0100 Subject: [PATCH 37/92] s390/hiperdispatch: Decrease steal time threshold Higher steal time thresholds favor low utilization scenarios, which is not the common case for s390. Set steal time threshold to a lower value to prioritize vertical high and medium CPUs sooner and allow high utilization scenarios to benefit from it. Suggested-by: Christian Borntraeger Signed-off-by: Mete Durlu Acked-by: Christian Borntraeger Signed-off-by: Heiko Carstens --- arch/s390/kernel/hiperdispatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/kernel/hiperdispatch.c b/arch/s390/kernel/hiperdispatch.c index 2507bc3f7757..7ad134cc9ad3 100644 --- a/arch/s390/kernel/hiperdispatch.c +++ b/arch/s390/kernel/hiperdispatch.c @@ -65,7 +65,7 @@ #define HD_DELAY_FACTOR (4) #define HD_DELAY_INTERVAL (HZ / 4) -#define HD_STEAL_THRESHOLD 30 +#define HD_STEAL_THRESHOLD 10 #define HD_STEAL_AVG_WEIGHT 16 static cpumask_t hd_vl_coremask; /* Mask containing all vertical low COREs */ From c1287d67c3a91aa19e4d9bbd3ad943cfbfa6bed4 Mon Sep 17 00:00:00 2001 From: Sumanth Korikkar Date: Wed, 5 Nov 2025 13:55:28 +0100 Subject: [PATCH 38/92] s390/sclp_mem: Consider global memory_hotplug.memmap_on_memory setting When the global kernel command line parameter memory_hotplug.memmap_on_memory is set to false, per-memory-block memmap_on_memory setting can still be set to true. However, when configuring memory block, add_memory_resource() would configure it without memmap_on_memory. i.e. Even if the MHP_MEMMAP_ON_MEMORY flag is set, mhp_supports_memmap_on_memory() returns false unless the kernel command line parameter "memory_hotplug.memmap_on_memory" is enabled. When both the flag and the cmdline parameter are set, the memory block can be configured with or without memmap_on_memory support. To ensure consistent behavior, permit configuring per-memory-block memmap_on_memory only when the memory_hotplug.memmap_on_memory kernel command line parameter is enabled. This is similar to commit 73954d379efd ("dax: add a sysfs knob to control memmap_on_memory behavior") Fixes: ff18dcb19aab ("s390/sclp: Add support for dynamic (de)configuration of memory") Signed-off-by: Sumanth Korikkar Reviewed-by: Heiko Carstens Signed-off-by: Heiko Carstens --- drivers/s390/char/sclp_mem.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/s390/char/sclp_mem.c b/drivers/s390/char/sclp_mem.c index 3a7a69615d99..bc515a24b3f2 100644 --- a/drivers/s390/char/sclp_mem.c +++ b/drivers/s390/char/sclp_mem.c @@ -275,6 +275,8 @@ static ssize_t sclp_memmap_on_memory_store(struct kobject *kobj, struct kobj_att rc = kstrtobool(buf, &value); if (rc) return rc; + if (value && !mhp_supports_memmap_on_memory()) + return -EOPNOTSUPP; rc = lock_device_hotplug_sysfs(); if (rc) return rc; From abc524caa1382a56f82d07d0621b7fa80f33e207 Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Wed, 5 Nov 2025 15:38:40 +0100 Subject: [PATCH 39/92] s390/pai_crypto: Rename variable cfm_dbg The global variable cfm_dbg points to the s390dbf debug buffer. Rename it to paidbg to better reflect its purpose. No functional change. Signed-off-by: Thomas Richter Reviewed-by: Jan Polensky Signed-off-by: Heiko Carstens --- arch/s390/kernel/perf_pai_crypto.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/s390/kernel/perf_pai_crypto.c b/arch/s390/kernel/perf_pai_crypto.c index 9b06b8a83342..ff0be76e4441 100644 --- a/arch/s390/kernel/perf_pai_crypto.c +++ b/arch/s390/kernel/perf_pai_crypto.c @@ -19,7 +19,7 @@ #include #include -static debug_info_t *cfm_dbg; +static debug_info_t *paidbg; static unsigned int paicrypt_cnt; /* Size of the mapped counter sets */ /* extracted with QPACI instruction */ @@ -55,7 +55,7 @@ static void paicrypt_root_free(void) free_percpu(paicrypt_root.mapptr); paicrypt_root.mapptr = NULL; } - debug_sprintf_event(cfm_dbg, 5, "%s root.refcount %d\n", __func__, + debug_sprintf_event(paidbg, 5, "%s root.refcount %d\n", __func__, refcount_read(&paicrypt_root.refcnt)); } @@ -98,7 +98,7 @@ static void paicrypt_event_destroy_cpu(struct perf_event *event, int cpu) struct paicrypt_map *cpump = mp->mapptr; mutex_lock(&pai_reserve_mutex); - debug_sprintf_event(cfm_dbg, 5, "%s event %#llx cpu %d users %d " + debug_sprintf_event(paidbg, 5, "%s event %#llx cpu %d users %d " "refcnt %u\n", __func__, event->attr.config, event->cpu, cpump->active_events, refcount_read(&cpump->refcnt)); @@ -822,19 +822,19 @@ static int __init paicrypt_init(void) } /* Setup s390dbf facility */ - cfm_dbg = debug_register(KMSG_COMPONENT, 2, 256, 128); - if (!cfm_dbg) { + paidbg = debug_register(KMSG_COMPONENT, 2, 256, 128); + if (!paidbg) { pr_err("Registration of s390dbf pai_crypto failed\n"); return -ENOMEM; } - debug_register_view(cfm_dbg, &debug_sprintf_view); + debug_register_view(paidbg, &debug_sprintf_view); rc = perf_pmu_register(&paicrypt, "pai_crypto", -1); if (rc) { pr_err("Registering the pai_crypto PMU failed with rc=%i\n", rc); - debug_unregister_view(cfm_dbg, &debug_sprintf_view); - debug_unregister(cfm_dbg); + debug_unregister_view(paidbg, &debug_sprintf_view); + debug_unregister(paidbg); return rc; } return 0; From c124208b74a66713d2743089ae1c55a1661e8cd9 Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Wed, 5 Nov 2025 15:38:41 +0100 Subject: [PATCH 40/92] s390/pai_crypto: Rename member paicrypt_map::page Rename member page in struct paicrypt_map to area. This rename creates consistent naming for both PMU drivers paicrypto and PMU paiext. No functional change. Signed-off-by: Thomas Richter Reviewed-by: Jan Polensky Signed-off-by: Heiko Carstens --- arch/s390/kernel/perf_pai_crypto.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/s390/kernel/perf_pai_crypto.c b/arch/s390/kernel/perf_pai_crypto.c index ff0be76e4441..dd5b32c4dd44 100644 --- a/arch/s390/kernel/perf_pai_crypto.c +++ b/arch/s390/kernel/perf_pai_crypto.c @@ -31,7 +31,7 @@ struct pai_userdata { } __packed; struct paicrypt_map { - unsigned long *page; /* Page for CPU to store counters */ + unsigned long *area; /* Area for CPU to store counters */ struct pai_userdata *save; /* Page to store no-zero counters */ unsigned int active_events; /* # of PAI crypto users */ refcount_t refcnt; /* Reference count mapped buffers */ @@ -83,7 +83,7 @@ static DEFINE_MUTEX(pai_reserve_mutex); /* Free all memory allocated for event counting/sampling setup */ static void paicrypt_free(struct paicrypt_mapptr *mp) { - free_page((unsigned long)mp->mapptr->page); + free_page((unsigned long)mp->mapptr->area); kvfree(mp->mapptr->save); kfree(mp->mapptr); mp->mapptr = NULL; @@ -143,13 +143,13 @@ static u64 paicrypt_getdata(struct perf_event *event, bool kernel) int i; if (event->attr.config != PAI_CRYPTO_BASE) { - return paicrypt_getctr(cpump->page, + return paicrypt_getctr(cpump->area, event->attr.config - PAI_CRYPTO_BASE, kernel); } for (i = 1; i <= paicrypt_cnt; i++) { - u64 val = paicrypt_getctr(cpump->page, i, kernel); + u64 val = paicrypt_getctr(cpump->area, i, kernel); if (!val) continue; @@ -201,11 +201,11 @@ static int paicrypt_alloc_cpu(struct perf_event *event, int cpu) * Only the first counting event has to allocate a page. */ mp->mapptr = cpump; - cpump->page = (unsigned long *)get_zeroed_page(GFP_KERNEL); + cpump->area = (unsigned long *)get_zeroed_page(GFP_KERNEL); cpump->save = kvmalloc_array(paicrypt_cnt + 1, sizeof(struct pai_userdata), GFP_KERNEL); - if (!cpump->page || !cpump->save) { + if (!cpump->area || !cpump->save) { paicrypt_free(mp); goto undo; } @@ -334,7 +334,7 @@ static void paicrypt_start(struct perf_event *event, int flags) sum = paicrypt_getall(event); /* Get current value */ local64_set(&event->hw.prev_count, sum); } else { /* Sampling */ - memcpy((void *)PAI_SAVE_AREA(event), cpump->page, PAGE_SIZE); + memcpy((void *)PAI_SAVE_AREA(event), cpump->area, PAGE_SIZE); /* Enable context switch callback for system-wide sampling */ if (!(event->attach_state & PERF_ATTACH_TASK)) { list_add_tail(PAI_SWLIST(event), &cpump->syswide_list); @@ -352,7 +352,7 @@ static int paicrypt_add(struct perf_event *event, int flags) unsigned long ccd; if (++cpump->active_events == 1) { - ccd = virt_to_phys(cpump->page) | PAI_CRYPTO_KERNEL_OFFSET; + ccd = virt_to_phys(cpump->area) | PAI_CRYPTO_KERNEL_OFFSET; WRITE_ONCE(get_lowcore()->ccd, ccd); local_ctl_set_bit(0, CR0_CRYPTOGRAPHY_COUNTER_BIT); } @@ -465,7 +465,7 @@ static int paicrypt_push_sample(size_t rawsize, struct paicrypt_map *cpump, overflow = perf_event_overflow(event, &data, ®s); perf_event_update_userpage(event); /* Save crypto counter lowcore page after reading event data. */ - memcpy((void *)PAI_SAVE_AREA(event), cpump->page, PAGE_SIZE); + memcpy((void *)PAI_SAVE_AREA(event), cpump->area, PAGE_SIZE); return overflow; } @@ -477,7 +477,7 @@ static void paicrypt_have_sample(struct perf_event *event, if (!event) /* No event active */ return; - rawsize = paicrypt_copy(cpump->save, cpump->page, + rawsize = paicrypt_copy(cpump->save, cpump->area, (unsigned long *)PAI_SAVE_AREA(event), event->attr.exclude_user, event->attr.exclude_kernel); From 2706ea193af5c7d727eda2d24c9c9833e2c47ddb Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Wed, 5 Nov 2025 15:38:42 +0100 Subject: [PATCH 41/92] s390/pai_crypto: Rename structure paicrypt_mapptr to pai_mapptr To support one common PAI PMU device driver which handles both PMUs pai_crypto and pai_ext, use a common naming scheme for structures and variables suitable for both device drivers. Rename structure paicrypt_mapptr to pai_mapptr. No functional change. Signed-off-by: Thomas Richter Reviewed-by: Jan Polensky Signed-off-by: Heiko Carstens --- arch/s390/kernel/perf_pai_crypto.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/arch/s390/kernel/perf_pai_crypto.c b/arch/s390/kernel/perf_pai_crypto.c index dd5b32c4dd44..1c855391ac8e 100644 --- a/arch/s390/kernel/perf_pai_crypto.c +++ b/arch/s390/kernel/perf_pai_crypto.c @@ -39,13 +39,13 @@ struct paicrypt_map { struct list_head syswide_list; /* List system-wide sampling events */ }; -struct paicrypt_mapptr { +struct pai_mapptr { struct paicrypt_map *mapptr; }; static struct paicrypt_root { /* Anchor to per CPU data */ refcount_t refcnt; /* Overall active events */ - struct paicrypt_mapptr __percpu *mapptr; + struct pai_mapptr __percpu *mapptr; } paicrypt_root; /* Free per CPU data when the last event is removed. */ @@ -69,7 +69,7 @@ static int paicrypt_root_alloc(void) { if (!refcount_inc_not_zero(&paicrypt_root.refcnt)) { /* The memory is already zeroed. */ - paicrypt_root.mapptr = alloc_percpu(struct paicrypt_mapptr); + paicrypt_root.mapptr = alloc_percpu(struct pai_mapptr); if (!paicrypt_root.mapptr) return -ENOMEM; refcount_set(&paicrypt_root.refcnt, 1); @@ -81,7 +81,7 @@ static int paicrypt_root_alloc(void) static DEFINE_MUTEX(pai_reserve_mutex); /* Free all memory allocated for event counting/sampling setup */ -static void paicrypt_free(struct paicrypt_mapptr *mp) +static void paicrypt_free(struct pai_mapptr *mp) { free_page((unsigned long)mp->mapptr->area); kvfree(mp->mapptr->save); @@ -94,7 +94,7 @@ static void paicrypt_free(struct paicrypt_mapptr *mp) */ static void paicrypt_event_destroy_cpu(struct perf_event *event, int cpu) { - struct paicrypt_mapptr *mp = per_cpu_ptr(paicrypt_root.mapptr, cpu); + struct pai_mapptr *mp = per_cpu_ptr(paicrypt_root.mapptr, cpu); struct paicrypt_map *cpump = mp->mapptr; mutex_lock(&pai_reserve_mutex); @@ -137,7 +137,7 @@ static u64 paicrypt_getctr(unsigned long *page, int nr, bool kernel) */ static u64 paicrypt_getdata(struct perf_event *event, bool kernel) { - struct paicrypt_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr); + struct pai_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr); struct paicrypt_map *cpump = mp->mapptr; u64 sum = 0; int i; @@ -180,7 +180,7 @@ static u64 paicrypt_getall(struct perf_event *event) static int paicrypt_alloc_cpu(struct perf_event *event, int cpu) { struct paicrypt_map *cpump = NULL; - struct paicrypt_mapptr *mp; + struct pai_mapptr *mp; int rc; mutex_lock(&pai_reserve_mutex); @@ -326,7 +326,7 @@ static void paicrypt_read(struct perf_event *event) static void paicrypt_start(struct perf_event *event, int flags) { - struct paicrypt_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr); + struct pai_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr); struct paicrypt_map *cpump = mp->mapptr; u64 sum; @@ -347,7 +347,7 @@ static void paicrypt_start(struct perf_event *event, int flags) static int paicrypt_add(struct perf_event *event, int flags) { - struct paicrypt_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr); + struct pai_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr); struct paicrypt_map *cpump = mp->mapptr; unsigned long ccd; @@ -365,7 +365,7 @@ static int paicrypt_add(struct perf_event *event, int flags) static void paicrypt_have_sample(struct perf_event *, struct paicrypt_map *); static void paicrypt_stop(struct perf_event *event, int flags) { - struct paicrypt_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr); + struct pai_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr); struct paicrypt_map *cpump = mp->mapptr; if (!event->attr.sample_period) { /* Counting */ @@ -384,7 +384,7 @@ static void paicrypt_stop(struct perf_event *event, int flags) static void paicrypt_del(struct perf_event *event, int flags) { - struct paicrypt_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr); + struct pai_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr); struct paicrypt_map *cpump = mp->mapptr; paicrypt_stop(event, PERF_EF_UPDATE); @@ -488,7 +488,7 @@ static void paicrypt_have_sample(struct perf_event *event, /* Check if there is data to be saved on schedule out of a task. */ static void paicrypt_have_samples(void) { - struct paicrypt_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr); + struct pai_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr); struct paicrypt_map *cpump = mp->mapptr; struct perf_event *event; From a626e0d46acb84acb07534c672b19690d5363315 Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Wed, 5 Nov 2025 15:38:43 +0100 Subject: [PATCH 42/92] s390/pai_crypto: Rename structure paicrypt_map to pai_map To support one common PAI PMU device driver which handles both PMUs pai_crypto and pai_ext, use a common naming scheme for structures and variables suitable for both device drivers. Rename structure paicrypt_map to pai_map. No functional change. Signed-off-by: Thomas Richter Reviewed-by: Jan Polensky Signed-off-by: Heiko Carstens --- arch/s390/kernel/perf_pai_crypto.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/arch/s390/kernel/perf_pai_crypto.c b/arch/s390/kernel/perf_pai_crypto.c index 1c855391ac8e..47b950629766 100644 --- a/arch/s390/kernel/perf_pai_crypto.c +++ b/arch/s390/kernel/perf_pai_crypto.c @@ -30,7 +30,7 @@ struct pai_userdata { u64 value; } __packed; -struct paicrypt_map { +struct pai_map { unsigned long *area; /* Area for CPU to store counters */ struct pai_userdata *save; /* Page to store no-zero counters */ unsigned int active_events; /* # of PAI crypto users */ @@ -40,7 +40,7 @@ struct paicrypt_map { }; struct pai_mapptr { - struct paicrypt_map *mapptr; + struct pai_map *mapptr; }; static struct paicrypt_root { /* Anchor to per CPU data */ @@ -95,7 +95,7 @@ static void paicrypt_free(struct pai_mapptr *mp) static void paicrypt_event_destroy_cpu(struct perf_event *event, int cpu) { struct pai_mapptr *mp = per_cpu_ptr(paicrypt_root.mapptr, cpu); - struct paicrypt_map *cpump = mp->mapptr; + struct pai_map *cpump = mp->mapptr; mutex_lock(&pai_reserve_mutex); debug_sprintf_event(paidbg, 5, "%s event %#llx cpu %d users %d " @@ -138,7 +138,7 @@ static u64 paicrypt_getctr(unsigned long *page, int nr, bool kernel) static u64 paicrypt_getdata(struct perf_event *event, bool kernel) { struct pai_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr); - struct paicrypt_map *cpump = mp->mapptr; + struct pai_map *cpump = mp->mapptr; u64 sum = 0; int i; @@ -179,7 +179,7 @@ static u64 paicrypt_getall(struct perf_event *event) */ static int paicrypt_alloc_cpu(struct perf_event *event, int cpu) { - struct paicrypt_map *cpump = NULL; + struct pai_map *cpump = NULL; struct pai_mapptr *mp; int rc; @@ -327,7 +327,7 @@ static void paicrypt_read(struct perf_event *event) static void paicrypt_start(struct perf_event *event, int flags) { struct pai_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr); - struct paicrypt_map *cpump = mp->mapptr; + struct pai_map *cpump = mp->mapptr; u64 sum; if (!event->attr.sample_period) { /* Counting */ @@ -348,7 +348,7 @@ static void paicrypt_start(struct perf_event *event, int flags) static int paicrypt_add(struct perf_event *event, int flags) { struct pai_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr); - struct paicrypt_map *cpump = mp->mapptr; + struct pai_map *cpump = mp->mapptr; unsigned long ccd; if (++cpump->active_events == 1) { @@ -362,11 +362,11 @@ static int paicrypt_add(struct perf_event *event, int flags) return 0; } -static void paicrypt_have_sample(struct perf_event *, struct paicrypt_map *); +static void paicrypt_have_sample(struct perf_event *, struct pai_map *); static void paicrypt_stop(struct perf_event *event, int flags) { struct pai_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr); - struct paicrypt_map *cpump = mp->mapptr; + struct pai_map *cpump = mp->mapptr; if (!event->attr.sample_period) { /* Counting */ paicrypt_read(event); @@ -385,7 +385,7 @@ static void paicrypt_stop(struct perf_event *event, int flags) static void paicrypt_del(struct perf_event *event, int flags) { struct pai_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr); - struct paicrypt_map *cpump = mp->mapptr; + struct pai_map *cpump = mp->mapptr; paicrypt_stop(event, PERF_EF_UPDATE); if (--cpump->active_events == 0) { @@ -431,7 +431,7 @@ static size_t paicrypt_copy(struct pai_userdata *userdata, unsigned long *page, return outidx * sizeof(*userdata); } -static int paicrypt_push_sample(size_t rawsize, struct paicrypt_map *cpump, +static int paicrypt_push_sample(size_t rawsize, struct pai_map *cpump, struct perf_event *event) { struct perf_sample_data data; @@ -471,7 +471,7 @@ static int paicrypt_push_sample(size_t rawsize, struct paicrypt_map *cpump, /* Check if there is data to be saved on schedule out of a task. */ static void paicrypt_have_sample(struct perf_event *event, - struct paicrypt_map *cpump) + struct pai_map *cpump) { size_t rawsize; @@ -489,7 +489,7 @@ static void paicrypt_have_sample(struct perf_event *event, static void paicrypt_have_samples(void) { struct pai_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr); - struct paicrypt_map *cpump = mp->mapptr; + struct pai_map *cpump = mp->mapptr; struct perf_event *event; list_for_each_entry(event, &cpump->syswide_list, hw.tp_list) From 3f082c2e479b02e553bf1ed0b47f0a315179585c Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Wed, 5 Nov 2025 15:38:44 +0100 Subject: [PATCH 43/92] s390/pai_crypto: Rename structure paicrypt_root To support one common PAI PMU device driver which handles both PMUs pai_crypto and pai_ext, use a common naming scheme for structures and variables suitable for both device drivers. Rename structure paicrypt_root to pai_root. No functional change. Signed-off-by: Thomas Richter Reviewed-by: Jan Polensky Signed-off-by: Heiko Carstens --- arch/s390/kernel/perf_pai_crypto.c | 36 +++++++++++++++--------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/arch/s390/kernel/perf_pai_crypto.c b/arch/s390/kernel/perf_pai_crypto.c index 47b950629766..5807365145c3 100644 --- a/arch/s390/kernel/perf_pai_crypto.c +++ b/arch/s390/kernel/perf_pai_crypto.c @@ -43,20 +43,20 @@ struct pai_mapptr { struct pai_map *mapptr; }; -static struct paicrypt_root { /* Anchor to per CPU data */ +static struct pai_root { /* Anchor to per CPU data */ refcount_t refcnt; /* Overall active events */ struct pai_mapptr __percpu *mapptr; -} paicrypt_root; +} pai_root; /* Free per CPU data when the last event is removed. */ static void paicrypt_root_free(void) { - if (refcount_dec_and_test(&paicrypt_root.refcnt)) { - free_percpu(paicrypt_root.mapptr); - paicrypt_root.mapptr = NULL; + if (refcount_dec_and_test(&pai_root.refcnt)) { + free_percpu(pai_root.mapptr); + pai_root.mapptr = NULL; } debug_sprintf_event(paidbg, 5, "%s root.refcount %d\n", __func__, - refcount_read(&paicrypt_root.refcnt)); + refcount_read(&pai_root.refcnt)); } /* @@ -67,12 +67,12 @@ static void paicrypt_root_free(void) */ static int paicrypt_root_alloc(void) { - if (!refcount_inc_not_zero(&paicrypt_root.refcnt)) { + if (!refcount_inc_not_zero(&pai_root.refcnt)) { /* The memory is already zeroed. */ - paicrypt_root.mapptr = alloc_percpu(struct pai_mapptr); - if (!paicrypt_root.mapptr) + pai_root.mapptr = alloc_percpu(struct pai_mapptr); + if (!pai_root.mapptr) return -ENOMEM; - refcount_set(&paicrypt_root.refcnt, 1); + refcount_set(&pai_root.refcnt, 1); } return 0; } @@ -94,7 +94,7 @@ static void paicrypt_free(struct pai_mapptr *mp) */ static void paicrypt_event_destroy_cpu(struct perf_event *event, int cpu) { - struct pai_mapptr *mp = per_cpu_ptr(paicrypt_root.mapptr, cpu); + struct pai_mapptr *mp = per_cpu_ptr(pai_root.mapptr, cpu); struct pai_map *cpump = mp->mapptr; mutex_lock(&pai_reserve_mutex); @@ -137,7 +137,7 @@ static u64 paicrypt_getctr(unsigned long *page, int nr, bool kernel) */ static u64 paicrypt_getdata(struct perf_event *event, bool kernel) { - struct pai_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr); + struct pai_mapptr *mp = this_cpu_ptr(pai_root.mapptr); struct pai_map *cpump = mp->mapptr; u64 sum = 0; int i; @@ -190,7 +190,7 @@ static int paicrypt_alloc_cpu(struct perf_event *event, int cpu) goto unlock; /* Allocate node for this event */ - mp = per_cpu_ptr(paicrypt_root.mapptr, cpu); + mp = per_cpu_ptr(pai_root.mapptr, cpu); cpump = mp->mapptr; if (!cpump) { /* Paicrypt_map allocated? */ rc = -ENOMEM; @@ -326,7 +326,7 @@ static void paicrypt_read(struct perf_event *event) static void paicrypt_start(struct perf_event *event, int flags) { - struct pai_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr); + struct pai_mapptr *mp = this_cpu_ptr(pai_root.mapptr); struct pai_map *cpump = mp->mapptr; u64 sum; @@ -347,7 +347,7 @@ static void paicrypt_start(struct perf_event *event, int flags) static int paicrypt_add(struct perf_event *event, int flags) { - struct pai_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr); + struct pai_mapptr *mp = this_cpu_ptr(pai_root.mapptr); struct pai_map *cpump = mp->mapptr; unsigned long ccd; @@ -365,7 +365,7 @@ static int paicrypt_add(struct perf_event *event, int flags) static void paicrypt_have_sample(struct perf_event *, struct pai_map *); static void paicrypt_stop(struct perf_event *event, int flags) { - struct pai_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr); + struct pai_mapptr *mp = this_cpu_ptr(pai_root.mapptr); struct pai_map *cpump = mp->mapptr; if (!event->attr.sample_period) { /* Counting */ @@ -384,7 +384,7 @@ static void paicrypt_stop(struct perf_event *event, int flags) static void paicrypt_del(struct perf_event *event, int flags) { - struct pai_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr); + struct pai_mapptr *mp = this_cpu_ptr(pai_root.mapptr); struct pai_map *cpump = mp->mapptr; paicrypt_stop(event, PERF_EF_UPDATE); @@ -488,7 +488,7 @@ static void paicrypt_have_sample(struct perf_event *event, /* Check if there is data to be saved on schedule out of a task. */ static void paicrypt_have_samples(void) { - struct pai_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr); + struct pai_mapptr *mp = this_cpu_ptr(pai_root.mapptr); struct pai_map *cpump = mp->mapptr; struct perf_event *event; From 387c7b5f04eff53f5bd7990b9909f7cc3a4e2e8c Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Wed, 5 Nov 2025 15:38:45 +0100 Subject: [PATCH 44/92] s390/pai_crypto: Rename paicrypt_root_alloc() and paicrypt_root_free() To support one common PAI PMU device driver which handles both PMUs pai_crypto and pai_ext, use a common naming scheme for structures and variables suitable for both device drivers. Rename functions paicrypt_root_alloc() and paicrypt_root_free() to pai_root_alloc() and pai_root_free(). No functional change. Signed-off-by: Thomas Richter Reviewed-by: Jan Polensky Signed-off-by: Heiko Carstens --- arch/s390/kernel/perf_pai_crypto.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/s390/kernel/perf_pai_crypto.c b/arch/s390/kernel/perf_pai_crypto.c index 5807365145c3..12f99028d5b8 100644 --- a/arch/s390/kernel/perf_pai_crypto.c +++ b/arch/s390/kernel/perf_pai_crypto.c @@ -49,7 +49,7 @@ static struct pai_root { /* Anchor to per CPU data */ } pai_root; /* Free per CPU data when the last event is removed. */ -static void paicrypt_root_free(void) +static void pai_root_free(void) { if (refcount_dec_and_test(&pai_root.refcnt)) { free_percpu(pai_root.mapptr); @@ -65,7 +65,7 @@ static void paicrypt_root_free(void) * CPUs possible, which might be larger than the number of CPUs currently * online. */ -static int paicrypt_root_alloc(void) +static int pai_root_alloc(void) { if (!refcount_inc_not_zero(&pai_root.refcnt)) { /* The memory is already zeroed. */ @@ -104,7 +104,7 @@ static void paicrypt_event_destroy_cpu(struct perf_event *event, int cpu) refcount_read(&cpump->refcnt)); if (refcount_dec_and_test(&cpump->refcnt)) paicrypt_free(mp); - paicrypt_root_free(); + pai_root_free(); mutex_unlock(&pai_reserve_mutex); } @@ -185,7 +185,7 @@ static int paicrypt_alloc_cpu(struct perf_event *event, int cpu) mutex_lock(&pai_reserve_mutex); /* Allocate root node */ - rc = paicrypt_root_alloc(); + rc = pai_root_alloc(); if (rc) goto unlock; @@ -222,7 +222,7 @@ static int paicrypt_alloc_cpu(struct perf_event *event, int cpu) * the event in not created, its destroy() function is never * invoked. Adjust the reference counter for the anchor. */ - paicrypt_root_free(); + pai_root_free(); } unlock: mutex_unlock(&pai_reserve_mutex); From a3f8423622ef34cca050816c49be4291f9f41b1d Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Wed, 5 Nov 2025 15:38:46 +0100 Subject: [PATCH 45/92] s390/pai_crypto: Add PAI crypto characteristics table for parameters Create and add a PMU characteristics table to store the parameters of the PAI crypto PMU. This table contains PMU details such as - number of available counters - name of these counters to export to /sysfs - Size of the memory mapped counter area - base number of first counter - etc Also define a PMU specific initialization function to be called when a PAI PMU feature is supported. At device driver initialization test these features and if available use instruction qpaci to retrieve the number of available counters. Also export these counter names to /sysfs and register this PMU. Signed-off-by: Thomas Richter Reviewed-by: Jan Polensky Signed-off-by: Heiko Carstens --- arch/s390/kernel/perf_pai_crypto.c | 198 +++++++++++++++++++++-------- 1 file changed, 143 insertions(+), 55 deletions(-) diff --git a/arch/s390/kernel/perf_pai_crypto.c b/arch/s390/kernel/perf_pai_crypto.c index 12f99028d5b8..36a99cdc3d37 100644 --- a/arch/s390/kernel/perf_pai_crypto.c +++ b/arch/s390/kernel/perf_pai_crypto.c @@ -25,6 +25,11 @@ static unsigned int paicrypt_cnt; /* Size of the mapped counter sets */ DEFINE_STATIC_KEY_FALSE(pai_key); +enum { + PAI_PMU_CRYPTO, /* Index of PMU pai_crypto */ + PAI_PMU_MAX /* # of PAI PMUs */ +}; + struct pai_userdata { u16 num; u64 value; @@ -48,6 +53,28 @@ static struct pai_root { /* Anchor to per CPU data */ struct pai_mapptr __percpu *mapptr; } pai_root; +/* This table defines the different parameters of the PAI PMUs. During + * initialization the machine dependent values are extracted and saved. + * However most of the values are static and do not change. + * There is one table entry per PAI PMU. + */ +struct pai_pmu { /* Define PAI PMU characteristics */ + const char *pmuname; /* Name of PMU */ + const int facility_nr; /* Facility number to check for support */ + unsigned int num_avail; /* # Counters defined by hardware */ + unsigned int num_named; /* # Counters known by name */ + unsigned long base; /* Counter set base number */ + unsigned long kernel_offset; /* Offset to kernel part in counter page */ + unsigned long area_size; /* Size of counter area */ + const char * const *names; /* List of counter names */ + struct pmu *pmu; /* Ptr to supporting PMU */ + int (*init)(struct pai_pmu *p); /* PMU support init function */ + void (*exit)(struct pai_pmu *p); /* PMU support exit function */ + struct attribute_group *event_group; /* Ptr to attribute of events */ +}; + +static struct pai_pmu pai_pmu[]; /* Forward declaration */ + /* Free per CPU data when the last event is removed. */ static void pai_root_free(void) { @@ -738,12 +765,12 @@ static const char * const paicrypt_ctrnames[] = { [172] = "PCKMO_ENCRYPT_AES_XTS_256", }; -static void __init attr_event_free(struct attribute **attrs, int num) +static void __init attr_event_free(struct attribute **attrs) { struct perf_pmu_events_attr *pa; - int i; + unsigned int i; - for (i = 0; i < num; i++) { + for (i = 0; attrs[i]; i++) { struct device_attribute *dap; dap = container_of(attrs[i], struct device_attribute, attr); @@ -753,89 +780,150 @@ static void __init attr_event_free(struct attribute **attrs, int num) kfree(attrs); } -static int __init attr_event_init_one(struct attribute **attrs, int num) +static struct attribute * __init attr_event_init_one(int num, + unsigned long base, + const char *name) { struct perf_pmu_events_attr *pa; - /* Index larger than array_size, no counter name available */ - if (num >= ARRAY_SIZE(paicrypt_ctrnames)) { - attrs[num] = NULL; - return 0; - } - pa = kzalloc(sizeof(*pa), GFP_KERNEL); if (!pa) - return -ENOMEM; + return NULL; sysfs_attr_init(&pa->attr.attr); - pa->id = PAI_CRYPTO_BASE + num; - pa->attr.attr.name = paicrypt_ctrnames[num]; + pa->id = base + num; + pa->attr.attr.name = name; pa->attr.attr.mode = 0444; pa->attr.show = cpumf_events_sysfs_show; pa->attr.store = NULL; - attrs[num] = &pa->attr.attr; - return 0; + return &pa->attr.attr; } -/* Create PMU sysfs event attributes on the fly. */ -static int __init attr_event_init(void) +static struct attribute ** __init attr_event_init(struct pai_pmu *p) { + unsigned int min_attr = min_t(unsigned int, p->num_named, p->num_avail); struct attribute **attrs; - int ret, i; + unsigned int i; - attrs = kmalloc_array(paicrypt_cnt + 2, sizeof(*attrs), GFP_KERNEL); + attrs = kmalloc_array(min_attr + 1, sizeof(*attrs), GFP_KERNEL | __GFP_ZERO); if (!attrs) - return -ENOMEM; - for (i = 0; i <= paicrypt_cnt; i++) { - ret = attr_event_init_one(attrs, i); - if (ret) { - attr_event_free(attrs, i); - return ret; + goto out; + for (i = 0; i < min_attr; i++) { + attrs[i] = attr_event_init_one(i, p->base, p->names[i]); + if (!attrs[i]) { + attr_event_free(attrs); + attrs = NULL; + goto out; } } attrs[i] = NULL; - paicrypt_events_group.attrs = attrs; - return 0; +out: + return attrs; +} + +static void __init pai_pmu_exit(struct pai_pmu *p) +{ + attr_event_free(p->event_group->attrs); + p->event_group->attrs = NULL; +} + +/* Add a PMU. Install its events and register the PMU device driver + * call back functions. + */ +static int __init pai_pmu_init(struct pai_pmu *p) +{ + int rc = -ENOMEM; + + + /* Export known PAI events */ + p->event_group->attrs = attr_event_init(p); + if (!p->event_group->attrs) { + pr_err("Creation of PMU %s /sysfs failed\n", p->pmuname); + goto out; + } + + rc = perf_pmu_register(p->pmu, p->pmuname, -1); + if (rc) { + pai_pmu_exit(p); + pr_err("Registering PMU %s failed with rc=%i\n", p->pmuname, + rc); + } +out: + return rc; +} + +/* PAI PMU characteristics table */ +static struct pai_pmu pai_pmu[] __refdata = { + [PAI_PMU_CRYPTO] = { + .pmuname = "pai_crypto", + .facility_nr = 196, + .num_named = ARRAY_SIZE(paicrypt_ctrnames), + .names = paicrypt_ctrnames, + .base = PAI_CRYPTO_BASE, + .kernel_offset = PAI_CRYPTO_KERNEL_OFFSET, + .area_size = PAGE_SIZE, + .init = pai_pmu_init, + .exit = pai_pmu_exit, + .pmu = &paicrypt, + .event_group = &paicrypt_events_group + } +}; + +/* + * Check if the PMU (via facility) is supported by machine. Try all of the + * supported PAI PMUs. + * Return number of successfully installed PMUs. + */ +static int __init paipmu_setup(void) +{ + struct qpaci_info_block ib; + int install_ok = 0, rc; + struct pai_pmu *p; + size_t i; + + for (i = 0; i < ARRAY_SIZE(pai_pmu); ++i) { + p = &pai_pmu[i]; + + if (!test_facility(p->facility_nr)) + continue; + + qpaci(&ib); + switch (i) { + case PAI_PMU_CRYPTO: + p->num_avail = ib.num_cc; + paicrypt_cnt = ib.num_cc; + if (p->num_avail >= PAI_CRYPTO_MAXCTR) { + pr_err("Too many PMU %s counters %d\n", + p->pmuname, p->num_avail); + continue; + } + break; + } + p->num_avail += 1; /* Add xxx_ALL event */ + if (p->init) { + rc = p->init(p); + if (!rc) + ++install_ok; + } + } + return install_ok; } static int __init paicrypt_init(void) { - struct qpaci_info_block ib; - int rc; - - if (!test_facility(196)) - return 0; - - qpaci(&ib); - paicrypt_cnt = ib.num_cc; - if (paicrypt_cnt == 0) - return 0; - if (paicrypt_cnt >= PAI_CRYPTO_MAXCTR) { - pr_err("Too many PMU pai_crypto counters %d\n", paicrypt_cnt); - return -E2BIG; - } - - rc = attr_event_init(); /* Export known PAI crypto events */ - if (rc) { - pr_err("Creation of PMU pai_crypto /sysfs failed\n"); - return rc; - } - /* Setup s390dbf facility */ - paidbg = debug_register(KMSG_COMPONENT, 2, 256, 128); + paidbg = debug_register(KMSG_COMPONENT, 32, 256, 128); if (!paidbg) { - pr_err("Registration of s390dbf pai_crypto failed\n"); + pr_err("Registration of s390dbf " KMSG_COMPONENT " failed\n"); return -ENOMEM; } debug_register_view(paidbg, &debug_sprintf_view); - rc = perf_pmu_register(&paicrypt, "pai_crypto", -1); - if (rc) { - pr_err("Registering the pai_crypto PMU failed with rc=%i\n", - rc); + if (!paipmu_setup()) { + /* No PMU registration, no need for debug buffer */ debug_unregister_view(paidbg, &debug_sprintf_view); debug_unregister(paidbg); - return rc; + return -ENODEV; } return 0; } From 413957980ac86d04afa6a634eaab1182dcd8c6c3 Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Wed, 5 Nov 2025 15:38:47 +0100 Subject: [PATCH 46/92] s390/pai_crypto: Introduce generic event init using pai_pmu[] To support one common PAI PMU device driver which handles both PMUs pai_crypto and pai_ext, use a common naming scheme for structures and variables suitable for both device drivers. Rework PAI crypto event initialization. Add a common function for event initialization. It uses the PAI characteristics stored in the pai_pmu table instead of hardcoded values. Enlarge pai_event_valid() to check all event validation aspects. Signed-off-by: Thomas Richter Reviewed-by: Jan Polensky Signed-off-by: Heiko Carstens --- arch/s390/include/asm/pai.h | 1 + arch/s390/kernel/perf_pai_crypto.c | 63 +++++++++++++++++++++--------- 2 files changed, 45 insertions(+), 19 deletions(-) diff --git a/arch/s390/include/asm/pai.h b/arch/s390/include/asm/pai.h index ebeabd0aaa51..534d0320e2aa 100644 --- a/arch/s390/include/asm/pai.h +++ b/arch/s390/include/asm/pai.h @@ -77,6 +77,7 @@ static __always_inline void pai_kernel_exit(struct pt_regs *regs) #define PAI_SAVE_AREA(x) ((x)->hw.event_base) #define PAI_CPU_MASK(x) ((x)->hw.addr_filters) +#define PAI_PMU_IDX(x) ((x)->hw.last_tag) #define PAI_SWLIST(x) (&(x)->hw.tp_list) #endif diff --git a/arch/s390/kernel/perf_pai_crypto.c b/arch/s390/kernel/perf_pai_crypto.c index 36a99cdc3d37..163053cb61a6 100644 --- a/arch/s390/kernel/perf_pai_crypto.c +++ b/arch/s390/kernel/perf_pai_crypto.c @@ -204,11 +204,11 @@ static u64 paicrypt_getall(struct perf_event *event) * * Allocate the memory for the event. */ -static int paicrypt_alloc_cpu(struct perf_event *event, int cpu) +static int pai_alloc_cpu(struct perf_event *event, int cpu) { + int rc, idx = PAI_PMU_IDX(event); struct pai_map *cpump = NULL; struct pai_mapptr *mp; - int rc; mutex_lock(&pai_reserve_mutex); /* Allocate root node */ @@ -229,7 +229,7 @@ static int paicrypt_alloc_cpu(struct perf_event *event, int cpu) */ mp->mapptr = cpump; cpump->area = (unsigned long *)get_zeroed_page(GFP_KERNEL); - cpump->save = kvmalloc_array(paicrypt_cnt + 1, + cpump->save = kvmalloc_array(pai_pmu[idx].num_avail + 1, sizeof(struct pai_userdata), GFP_KERNEL); if (!cpump->area || !cpump->save) { @@ -253,10 +253,11 @@ static int paicrypt_alloc_cpu(struct perf_event *event, int cpu) } unlock: mutex_unlock(&pai_reserve_mutex); + /* If rc is non-zero, no increment of counter/sampler was done. */ return rc; } -static int paicrypt_alloc(struct perf_event *event) +static int pai_alloc(struct perf_event *event) { struct cpumask *maskptr; int cpu, rc = -ENOMEM; @@ -266,7 +267,7 @@ static int paicrypt_alloc(struct perf_event *event) goto out; for_each_online_cpu(cpu) { - rc = paicrypt_alloc_cpu(event, cpu); + rc = pai_alloc_cpu(event, cpu); if (rc) { for_each_cpu(cpu, maskptr) paicrypt_event_destroy_cpu(event, cpu); @@ -288,22 +289,38 @@ static int paicrypt_alloc(struct perf_event *event) return rc; } -/* Might be called on different CPU than the one the event is intended for. */ -static int paicrypt_event_init(struct perf_event *event) +/* Validate event number and return error if event is not supported. + * On successful return, PAI_PMU_IDX(event) is set to the index of + * the supporting paing_support[] array element. + */ +static int pai_event_valid(struct perf_event *event, int idx) { struct perf_event_attr *a = &event->attr; - int rc = 0; + struct pai_pmu *pp = &pai_pmu[idx]; /* PAI crypto PMU registered as PERF_TYPE_RAW, check event type */ if (a->type != PERF_TYPE_RAW && event->pmu->type != a->type) return -ENOENT; - /* PAI crypto event must be in valid range, try others if not */ - if (a->config < PAI_CRYPTO_BASE || - a->config > PAI_CRYPTO_BASE + paicrypt_cnt) - return -ENOENT; - /* Allow only CRYPTO_ALL for sampling */ - if (a->sample_period && a->config != PAI_CRYPTO_BASE) + /* Allow only CRYPTO_ALL/NNPA_ALL for sampling */ + if (a->sample_period && a->config != pp->base) return -EINVAL; + /* PAI crypto event must be in valid range, try others if not */ + if (a->config < pp->base || a->config > pp->base + pp->num_avail) + return -ENOENT; + PAI_PMU_IDX(event) = idx; + return 0; +} + +/* Might be called on different CPU than the one the event is intended for. */ +static int pai_event_init(struct perf_event *event, int idx) +{ + struct perf_event_attr *a = &event->attr; + int rc; + + /* PAI event must be valid and in supported range */ + rc = pai_event_valid(event, idx); + if (rc) + goto out; /* Get a page to store last counter values for sampling */ if (a->sample_period) { PAI_SAVE_AREA(event) = get_zeroed_page(GFP_KERNEL); @@ -314,14 +331,13 @@ static int paicrypt_event_init(struct perf_event *event) } if (event->cpu >= 0) - rc = paicrypt_alloc_cpu(event, event->cpu); + rc = pai_alloc_cpu(event, event->cpu); else - rc = paicrypt_alloc(event); + rc = pai_alloc(event); if (rc) { free_page(PAI_SAVE_AREA(event)); goto out; } - event->destroy = paicrypt_event_destroy; if (a->sample_period) { a->sample_period = 1; @@ -333,12 +349,21 @@ static int paicrypt_event_init(struct perf_event *event) /* Turn off inheritance */ a->inherit = 0; } - - static_branch_inc(&pai_key); out: return rc; } +static int paicrypt_event_init(struct perf_event *event) +{ + int rc = pai_event_init(event, PAI_PMU_CRYPTO); + + if (!rc) { + event->destroy = paicrypt_event_destroy; + static_branch_inc(&pai_key); + } + return rc; +} + static void paicrypt_read(struct perf_event *event) { u64 prev, new, delta; From 65b9831bd3ced5acb0d4a0fad66f7585a3ad3db8 Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Wed, 5 Nov 2025 15:38:48 +0100 Subject: [PATCH 47/92] s390/pai_crypto: Rename some function for common usage. To support one common PAI PMU device driver which handles both PMUs pai_crypto and pai_ext, use a common naming scheme for structures and variables suitable for both device drivers. Rename functions - paicrypt_free() -> pai_free() - paicrypt_destroy_event() -> pai_destroy_event() - paicrypt_destroy_event_cpu() -> pai_destroy_event_cpu() to reflect their future common usage. No functional change. Signed-off-by: Thomas Richter Reviewed-by: Jan Polensky Signed-off-by: Heiko Carstens --- arch/s390/kernel/perf_pai_crypto.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/s390/kernel/perf_pai_crypto.c b/arch/s390/kernel/perf_pai_crypto.c index 163053cb61a6..4b4c22bf6171 100644 --- a/arch/s390/kernel/perf_pai_crypto.c +++ b/arch/s390/kernel/perf_pai_crypto.c @@ -108,7 +108,7 @@ static int pai_root_alloc(void) static DEFINE_MUTEX(pai_reserve_mutex); /* Free all memory allocated for event counting/sampling setup */ -static void paicrypt_free(struct pai_mapptr *mp) +static void pai_free(struct pai_mapptr *mp) { free_page((unsigned long)mp->mapptr->area); kvfree(mp->mapptr->save); @@ -119,7 +119,7 @@ static void paicrypt_free(struct pai_mapptr *mp) /* Adjust usage counters and remove allocated memory when all users are * gone. */ -static void paicrypt_event_destroy_cpu(struct perf_event *event, int cpu) +static void pai_event_destroy_cpu(struct perf_event *event, int cpu) { struct pai_mapptr *mp = per_cpu_ptr(pai_root.mapptr, cpu); struct pai_map *cpump = mp->mapptr; @@ -130,12 +130,12 @@ static void paicrypt_event_destroy_cpu(struct perf_event *event, int cpu) event->cpu, cpump->active_events, refcount_read(&cpump->refcnt)); if (refcount_dec_and_test(&cpump->refcnt)) - paicrypt_free(mp); + pai_free(mp); pai_root_free(); mutex_unlock(&pai_reserve_mutex); } -static void paicrypt_event_destroy(struct perf_event *event) +static void pai_event_destroy(struct perf_event *event) { int cpu; @@ -145,10 +145,10 @@ static void paicrypt_event_destroy(struct perf_event *event) struct cpumask *mask = PAI_CPU_MASK(event); for_each_cpu(cpu, mask) - paicrypt_event_destroy_cpu(event, cpu); + pai_event_destroy_cpu(event, cpu); kfree(mask); } else { - paicrypt_event_destroy_cpu(event, event->cpu); + pai_event_destroy_cpu(event, event->cpu); } } @@ -233,7 +233,7 @@ static int pai_alloc_cpu(struct perf_event *event, int cpu) sizeof(struct pai_userdata), GFP_KERNEL); if (!cpump->area || !cpump->save) { - paicrypt_free(mp); + pai_free(mp); goto undo; } INIT_LIST_HEAD(&cpump->syswide_list); @@ -270,7 +270,7 @@ static int pai_alloc(struct perf_event *event) rc = pai_alloc_cpu(event, cpu); if (rc) { for_each_cpu(cpu, maskptr) - paicrypt_event_destroy_cpu(event, cpu); + pai_event_destroy_cpu(event, cpu); kfree(maskptr); goto out; } @@ -280,7 +280,7 @@ static int pai_alloc(struct perf_event *event) /* * On error all cpumask are freed and all events have been destroyed. * Save of which CPUs data structures have been allocated for. - * Release them in paicrypt_event_destroy call back function + * Release them in pai_event_destroy call back function * for this event. */ PAI_CPU_MASK(event) = maskptr; @@ -358,7 +358,7 @@ static int paicrypt_event_init(struct perf_event *event) int rc = pai_event_init(event, PAI_PMU_CRYPTO); if (!rc) { - event->destroy = paicrypt_event_destroy; + event->destroy = pai_event_destroy; static_branch_inc(&pai_key); } return rc; From 42cd0c82422775e34528b9d0df438e51150a4db9 Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Wed, 5 Nov 2025 15:38:49 +0100 Subject: [PATCH 48/92] s390/pai_crypto: Rename paicrypt_getdata() to pai_getdata() To support one common PAI PMU device driver which handles both PMUs pai_crypto and pai_ext, use a common naming scheme for structures and variables suitable for both device drivers. Rename paicrypt_getdata() to pai_getdata(). Use the PAI PMU characteristics in the pai_pmu table to determine the number of counters to be extracted. Signed-off-by: Thomas Richter Reviewed-by: Jan Polensky Signed-off-by: Heiko Carstens --- arch/s390/kernel/perf_pai_crypto.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/arch/s390/kernel/perf_pai_crypto.c b/arch/s390/kernel/perf_pai_crypto.c index 4b4c22bf6171..8b3f6c624e81 100644 --- a/arch/s390/kernel/perf_pai_crypto.c +++ b/arch/s390/kernel/perf_pai_crypto.c @@ -159,23 +159,25 @@ static u64 paicrypt_getctr(unsigned long *page, int nr, bool kernel) return page[nr]; } -/* Read the counter values. Return value from location in CMP. For event - * CRYPTO_ALL sum up all events. +/* Read the counter values. Return value from location in CMP. For base + * event xxx_ALL sum up all events. Returns counter value. */ -static u64 paicrypt_getdata(struct perf_event *event, bool kernel) +static u64 pai_getdata(struct perf_event *event, bool kernel) { struct pai_mapptr *mp = this_cpu_ptr(pai_root.mapptr); struct pai_map *cpump = mp->mapptr; + int idx = PAI_PMU_IDX(event); + struct pai_pmu *pp = &pai_pmu[idx]; + unsigned int i; u64 sum = 0; - int i; - if (event->attr.config != PAI_CRYPTO_BASE) { + if (event->attr.config != pp->base) { return paicrypt_getctr(cpump->area, - event->attr.config - PAI_CRYPTO_BASE, + event->attr.config - pp->base, kernel); } - for (i = 1; i <= paicrypt_cnt; i++) { + for (i = 1; i <= pp->num_avail; i++) { u64 val = paicrypt_getctr(cpump->area, i, kernel); if (!val) @@ -190,9 +192,9 @@ static u64 paicrypt_getall(struct perf_event *event) u64 sum = 0; if (!event->attr.exclude_kernel) - sum += paicrypt_getdata(event, true); + sum += pai_getdata(event, true); if (!event->attr.exclude_user) - sum += paicrypt_getdata(event, false); + sum += pai_getdata(event, false); return sum; } From 360e180d8b5d448429079d2c541c1968f3b82790 Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Wed, 5 Nov 2025 15:38:50 +0100 Subject: [PATCH 49/92] s390/pai_crypto: Rename paicrypt_getctr() to pai_getctr() To support one common PAI PMU device driver which handles both PMUs pai_crypto and pai_ext, use a common naming scheme for structures and variables suitable for both device drivers. Rename paicrypt_getctr() to pai_getctr() to reflect is common purpose. pai_getctr() now uses pai_pmu table to extract PAI PMU characteristics such as kernel_offset inside the counter area page. Also rename paicrypt_have_sample() to pai_have_sample(). Signed-off-by: Thomas Richter Reviewed-by: Jan Polensky Signed-off-by: Heiko Carstens --- arch/s390/kernel/perf_pai_crypto.c | 40 ++++++++++++++++-------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/arch/s390/kernel/perf_pai_crypto.c b/arch/s390/kernel/perf_pai_crypto.c index 8b3f6c624e81..33af05b91874 100644 --- a/arch/s390/kernel/perf_pai_crypto.c +++ b/arch/s390/kernel/perf_pai_crypto.c @@ -152,10 +152,10 @@ static void pai_event_destroy(struct perf_event *event) } } -static u64 paicrypt_getctr(unsigned long *page, int nr, bool kernel) +static u64 pai_getctr(unsigned long *page, int nr, unsigned long offset) { - if (kernel) - nr += PAI_CRYPTO_MAXCTR; + if (offset) + nr += offset / sizeof(*page); return page[nr]; } @@ -172,13 +172,14 @@ static u64 pai_getdata(struct perf_event *event, bool kernel) u64 sum = 0; if (event->attr.config != pp->base) { - return paicrypt_getctr(cpump->area, + return pai_getctr(cpump->area, event->attr.config - pp->base, - kernel); + kernel ? pp->kernel_offset : 0); } for (i = 1; i <= pp->num_avail; i++) { - u64 val = paicrypt_getctr(cpump->area, i, kernel); + u64 val = pai_getctr(cpump->area, i, + kernel ? pp->kernel_offset : 0); if (!val) continue; @@ -416,7 +417,7 @@ static int paicrypt_add(struct perf_event *event, int flags) return 0; } -static void paicrypt_have_sample(struct perf_event *, struct pai_map *); +static void pai_have_sample(struct perf_event *, struct pai_map *); static void paicrypt_stop(struct perf_event *event, int flags) { struct pai_mapptr *mp = this_cpu_ptr(pai_root.mapptr); @@ -429,7 +430,7 @@ static void paicrypt_stop(struct perf_event *event, int flags) perf_sched_cb_dec(event->pmu); list_del(PAI_SWLIST(event)); } else { - paicrypt_have_sample(event, cpump); + pai_have_sample(event, cpump); cpump->event = NULL; } } @@ -456,21 +457,21 @@ static void paicrypt_del(struct perf_event *event, int flags) * 8 bytes: Value of counter */ static size_t paicrypt_copy(struct pai_userdata *userdata, unsigned long *page, - unsigned long *page_old, bool exclude_user, - bool exclude_kernel) + struct pai_pmu *pp, unsigned long *page_old, + bool exclude_user, bool exclude_kernel) { int i, outidx = 0; - for (i = 1; i <= paicrypt_cnt; i++) { + for (i = 1; i <= pp->num_avail; i++) { u64 val = 0, val_old = 0; if (!exclude_kernel) { - val += paicrypt_getctr(page, i, true); - val_old += paicrypt_getctr(page_old, i, true); + val += pai_getctr(page, i, pp->kernel_offset); + val_old += pai_getctr(page_old, i, pp->kernel_offset); } if (!exclude_user) { - val += paicrypt_getctr(page, i, false); - val_old += paicrypt_getctr(page_old, i, false); + val += pai_getctr(page, i, 0); + val_old += pai_getctr(page_old, i, 0); } if (val >= val_old) val -= val_old; @@ -524,14 +525,15 @@ static int paicrypt_push_sample(size_t rawsize, struct pai_map *cpump, } /* Check if there is data to be saved on schedule out of a task. */ -static void paicrypt_have_sample(struct perf_event *event, - struct pai_map *cpump) +static void pai_have_sample(struct perf_event *event, struct pai_map *cpump) { + struct pai_pmu *pp; size_t rawsize; if (!event) /* No event active */ return; - rawsize = paicrypt_copy(cpump->save, cpump->area, + pp = &pai_pmu[PAI_PMU_IDX(event)]; + rawsize = paicrypt_copy(cpump->save, cpump->area, pp, (unsigned long *)PAI_SAVE_AREA(event), event->attr.exclude_user, event->attr.exclude_kernel); @@ -547,7 +549,7 @@ static void paicrypt_have_samples(void) struct perf_event *event; list_for_each_entry(event, &cpump->syswide_list, hw.tp_list) - paicrypt_have_sample(event, cpump); + pai_have_sample(event, cpump); } /* Called on schedule-in and schedule-out. No access to event structure, From 0f1c0d754ac9c27cfb21e2e10c95261b1459e212 Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Wed, 5 Nov 2025 15:38:51 +0100 Subject: [PATCH 50/92] s390/pai_crypto: Rename paicrypt_have_samples() to pai_have_samples() To support one common PAI PMU device driver which handles both PMUs pai_crypto and pai_ext, use a common naming scheme for structures and variables suitable for both device drivers. Rename paicrypt_have_samples() to pai_have_samples() to reflect its common usage. No functional change. Signed-off-by: Thomas Richter Reviewed-by: Jan Polensky Signed-off-by: Heiko Carstens --- arch/s390/kernel/perf_pai_crypto.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/s390/kernel/perf_pai_crypto.c b/arch/s390/kernel/perf_pai_crypto.c index 33af05b91874..f7d846262a5b 100644 --- a/arch/s390/kernel/perf_pai_crypto.c +++ b/arch/s390/kernel/perf_pai_crypto.c @@ -542,7 +542,7 @@ static void pai_have_sample(struct perf_event *event, struct pai_map *cpump) } /* Check if there is data to be saved on schedule out of a task. */ -static void paicrypt_have_samples(void) +static void pai_have_samples(void) { struct pai_mapptr *mp = this_cpu_ptr(pai_root.mapptr); struct pai_map *cpump = mp->mapptr; @@ -562,7 +562,7 @@ static void paicrypt_sched_task(struct perf_event_pmu_context *pmu_ctx, * results on schedule_out and if page was dirty, save old values. */ if (!sched_in) - paicrypt_have_samples(); + pai_have_samples(); } /* Attribute definitions for paicrypt interface. As with other CPU From 74466e87e7fae1e5d746037a3d0484fd0afb03b2 Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Wed, 5 Nov 2025 15:38:52 +0100 Subject: [PATCH 51/92] s390/pai_crypto: Unify sample push logic and update context handling Unify naming and logic for PAI PMU drivers to support both PMUs pai_crypto and pai_ext. Rename paicrypt_push_sample() to pai_push_sample() to reflect its common usage. Add detailed comments about invocation context and scheduler callbacks. Use struct pai_pmu to determine area_size instead of PAGE_SIZE for counter backup. Remove obsolete variable paicrypt_cnt. Signed-off-by: Thomas Richter Reviewed-by: Jan Polensky Signed-off-by: Heiko Carstens --- arch/s390/kernel/perf_pai_crypto.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/arch/s390/kernel/perf_pai_crypto.c b/arch/s390/kernel/perf_pai_crypto.c index f7d846262a5b..59b18f86b8ae 100644 --- a/arch/s390/kernel/perf_pai_crypto.c +++ b/arch/s390/kernel/perf_pai_crypto.c @@ -20,8 +20,6 @@ #include static debug_info_t *paidbg; -static unsigned int paicrypt_cnt; /* Size of the mapped counter sets */ - /* extracted with QPACI instruction */ DEFINE_STATIC_KEY_FALSE(pai_key); @@ -486,9 +484,25 @@ static size_t paicrypt_copy(struct pai_userdata *userdata, unsigned long *page, return outidx * sizeof(*userdata); } -static int paicrypt_push_sample(size_t rawsize, struct pai_map *cpump, - struct perf_event *event) +/* Write sample when one or more counters values are nonzero. + * + * Note: The function paicrypt_sched_task() and pai_push_sample() are not + * invoked after function paicrypt_del() has been called because of function + * perf_sched_cb_dec(). Both functions are only + * called when sampling is active. Function perf_sched_cb_inc() + * has been invoked to install function paicrypt_sched_task() as call back + * to run at context switch time. + * + * This causes function perf_event_context_sched_out() and + * perf_event_context_sched_in() to check whether the PMU has installed an + * sched_task() callback. That callback is not active after paicrypt_del() + * returns and has deleted the event on that CPU. + */ +static int pai_push_sample(size_t rawsize, struct pai_map *cpump, + struct perf_event *event) { + int idx = PAI_PMU_IDX(event); + struct pai_pmu *pp = &pai_pmu[idx]; struct perf_sample_data data; struct perf_raw_record raw; struct pt_regs regs; @@ -520,7 +534,7 @@ static int paicrypt_push_sample(size_t rawsize, struct pai_map *cpump, overflow = perf_event_overflow(event, &data, ®s); perf_event_update_userpage(event); /* Save crypto counter lowcore page after reading event data. */ - memcpy((void *)PAI_SAVE_AREA(event), cpump->area, PAGE_SIZE); + memcpy((void *)PAI_SAVE_AREA(event), cpump->area, pp->area_size); return overflow; } @@ -538,7 +552,7 @@ static void pai_have_sample(struct perf_event *event, struct pai_map *cpump) event->attr.exclude_user, event->attr.exclude_kernel); if (rawsize) /* No incremented counters */ - paicrypt_push_sample(rawsize, cpump, event); + pai_push_sample(rawsize, cpump, event); } /* Check if there is data to be saved on schedule out of a task. */ @@ -920,7 +934,6 @@ static int __init paipmu_setup(void) switch (i) { case PAI_PMU_CRYPTO: p->num_avail = ib.num_cc; - paicrypt_cnt = ib.num_cc; if (p->num_avail >= PAI_CRYPTO_MAXCTR) { pr_err("Too many PMU %s counters %d\n", p->pmuname, p->num_avail); From 8f6116fd4940ad60adbfaca3525567b087054b5b Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Wed, 5 Nov 2025 15:38:53 +0100 Subject: [PATCH 52/92] s390/pai_crypto: Add common pai_read() function To support one common PAI PMU device driver which handles both PMUs pai_crypto and pai_ext, use a common naming scheme for structures and variables suitable for both device drivers. Add a common usable function pai_read() to read counter values. The function expects a PAI PMU specific read function as second parameter. Signed-off-by: Thomas Richter Reviewed-by: Jan Polensky Signed-off-by: Heiko Carstens --- arch/s390/kernel/perf_pai_crypto.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/arch/s390/kernel/perf_pai_crypto.c b/arch/s390/kernel/perf_pai_crypto.c index 59b18f86b8ae..4eb1a09c36bd 100644 --- a/arch/s390/kernel/perf_pai_crypto.c +++ b/arch/s390/kernel/perf_pai_crypto.c @@ -365,18 +365,23 @@ static int paicrypt_event_init(struct perf_event *event) return rc; } -static void paicrypt_read(struct perf_event *event) +static void pai_read(struct perf_event *event, + u64 (*fct)(struct perf_event *event)) { u64 prev, new, delta; prev = local64_read(&event->hw.prev_count); - new = paicrypt_getall(event); + new = fct(event); local64_set(&event->hw.prev_count, new); - delta = (prev <= new) ? new - prev - : (-1ULL - prev) + new + 1; /* overflow */ + delta = (prev <= new) ? new - prev : (-1ULL - prev) + new + 1; local64_add(delta, &event->count); } +static void paicrypt_read(struct perf_event *event) +{ + pai_read(event, paicrypt_getall); +} + static void paicrypt_start(struct perf_event *event, int flags) { struct pai_mapptr *mp = this_cpu_ptr(pai_root.mapptr); From 6fe66b21570f138017ee493b72cd4f724c8f1df1 Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Wed, 5 Nov 2025 15:38:54 +0100 Subject: [PATCH 53/92] s390/pai_crypto: Add common pai_start() function To support one common PAI PMU device driver which handles both PMUs pai_crypto and pai_ext, use a common naming scheme for structures and variables suitable for both device drivers. Add a common usable function pai_start() to the event on a CPU. The function expects a PAI PMU specific read function as second parameter to read out the start value for an event. Signed-off-by: Thomas Richter Reviewed-by: Jan Polensky Signed-off-by: Heiko Carstens --- arch/s390/kernel/perf_pai_crypto.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/arch/s390/kernel/perf_pai_crypto.c b/arch/s390/kernel/perf_pai_crypto.c index 4eb1a09c36bd..e7f225764126 100644 --- a/arch/s390/kernel/perf_pai_crypto.c +++ b/arch/s390/kernel/perf_pai_crypto.c @@ -382,17 +382,20 @@ static void paicrypt_read(struct perf_event *event) pai_read(event, paicrypt_getall); } -static void paicrypt_start(struct perf_event *event, int flags) +static void pai_start(struct perf_event *event, int flags, + u64 (*fct)(struct perf_event *event)) { + int idx = PAI_PMU_IDX(event); + struct pai_pmu *pp = &pai_pmu[idx]; struct pai_mapptr *mp = this_cpu_ptr(pai_root.mapptr); struct pai_map *cpump = mp->mapptr; u64 sum; if (!event->attr.sample_period) { /* Counting */ - sum = paicrypt_getall(event); /* Get current value */ + sum = fct(event); /* Get current value */ local64_set(&event->hw.prev_count, sum); } else { /* Sampling */ - memcpy((void *)PAI_SAVE_AREA(event), cpump->area, PAGE_SIZE); + memcpy((void *)PAI_SAVE_AREA(event), cpump->area, pp->area_size); /* Enable context switch callback for system-wide sampling */ if (!(event->attach_state & PERF_ATTACH_TASK)) { list_add_tail(PAI_SWLIST(event), &cpump->syswide_list); @@ -403,6 +406,11 @@ static void paicrypt_start(struct perf_event *event, int flags) } } +static void paicrypt_start(struct perf_event *event, int flags) +{ + pai_start(event, flags, paicrypt_getall); +} + static int paicrypt_add(struct perf_event *event, int flags) { struct pai_mapptr *mp = this_cpu_ptr(pai_root.mapptr); From a65a4d7e806402e394b1ef0323aafec23903888b Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Wed, 5 Nov 2025 15:38:55 +0100 Subject: [PATCH 54/92] s390/pai_crypto: Add common pai_add() function To support one common PAI PMU device driver which handles both PMUs pai_crypto and pai_ext, use a common naming scheme for structures and variables suitable for both device drivers. Add a common usable function pai_add() for the event on a CPU. Call this common pai_add() from paicrypt_add(). Signed-off-by: Thomas Richter Reviewed-by: Jan Polensky Signed-off-by: Heiko Carstens --- arch/s390/kernel/perf_pai_crypto.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/arch/s390/kernel/perf_pai_crypto.c b/arch/s390/kernel/perf_pai_crypto.c index e7f225764126..73a55ddedc80 100644 --- a/arch/s390/kernel/perf_pai_crypto.c +++ b/arch/s390/kernel/perf_pai_crypto.c @@ -411,10 +411,11 @@ static void paicrypt_start(struct perf_event *event, int flags) pai_start(event, flags, paicrypt_getall); } -static int paicrypt_add(struct perf_event *event, int flags) +static int pai_add(struct perf_event *event, int flags) { struct pai_mapptr *mp = this_cpu_ptr(pai_root.mapptr); struct pai_map *cpump = mp->mapptr; + int idx = PAI_PMU_IDX(event); unsigned long ccd; if (++cpump->active_events == 1) { @@ -423,11 +424,16 @@ static int paicrypt_add(struct perf_event *event, int flags) local_ctl_set_bit(0, CR0_CRYPTOGRAPHY_COUNTER_BIT); } if (flags & PERF_EF_START) - paicrypt_start(event, PERF_EF_RELOAD); + pai_pmu[idx].pmu->start(event, PERF_EF_RELOAD); event->hw.state = 0; return 0; } +static int paicrypt_add(struct perf_event *event, int flags) +{ + return pai_add(event, flags); +} + static void pai_have_sample(struct perf_event *, struct pai_map *); static void paicrypt_stop(struct perf_event *event, int flags) { From ac03223f0723cf7ee11171be963f19958a91f7b3 Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Wed, 5 Nov 2025 15:38:56 +0100 Subject: [PATCH 55/92] s390/pai_crypto: Add common pai_stop() function To support one common PAI PMU device driver which handles both PMUs pai_crypto and pai_ext, use a common naming scheme for structures and variables suitable for both device drivers. Add a common usable function pai_stop() for the event on a CPU. Call this common pai_stop() from paicrypt_del(). Signed-off-by: Thomas Richter Reviewed-by: Jan Polensky Signed-off-by: Heiko Carstens --- arch/s390/kernel/perf_pai_crypto.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/arch/s390/kernel/perf_pai_crypto.c b/arch/s390/kernel/perf_pai_crypto.c index 73a55ddedc80..5d4b9ffe3cb1 100644 --- a/arch/s390/kernel/perf_pai_crypto.c +++ b/arch/s390/kernel/perf_pai_crypto.c @@ -435,13 +435,14 @@ static int paicrypt_add(struct perf_event *event, int flags) } static void pai_have_sample(struct perf_event *, struct pai_map *); -static void paicrypt_stop(struct perf_event *event, int flags) +static void pai_stop(struct perf_event *event, int flags) { struct pai_mapptr *mp = this_cpu_ptr(pai_root.mapptr); struct pai_map *cpump = mp->mapptr; + int idx = PAI_PMU_IDX(event); if (!event->attr.sample_period) { /* Counting */ - paicrypt_read(event); + pai_pmu[idx].pmu->read(event); } else { /* Sampling */ if (!(event->attach_state & PERF_ATTACH_TASK)) { perf_sched_cb_dec(event->pmu); @@ -454,6 +455,11 @@ static void paicrypt_stop(struct perf_event *event, int flags) event->hw.state = PERF_HES_STOPPED; } +static void paicrypt_stop(struct perf_event *event, int flags) +{ + pai_stop(event, flags); +} + static void paicrypt_del(struct perf_event *event, int flags) { struct pai_mapptr *mp = this_cpu_ptr(pai_root.mapptr); From 42e6a0f6d2f0e9ac96d0d6045624a1fa44ab6871 Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Wed, 5 Nov 2025 15:38:57 +0100 Subject: [PATCH 56/92] s390/pai_crypto: Add common pai_del() function To support one common PAI PMU device driver which handles both PMUs pai_crypto and pai_ext, use a common naming scheme for structures and variables suitable for both device drivers. Add a common usable function pai_stop() for the event on a CPU. Signed-off-by: Thomas Richter Reviewed-by: Jan Polensky Signed-off-by: Heiko Carstens --- arch/s390/kernel/perf_pai_crypto.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/arch/s390/kernel/perf_pai_crypto.c b/arch/s390/kernel/perf_pai_crypto.c index 5d4b9ffe3cb1..a014f4a1b443 100644 --- a/arch/s390/kernel/perf_pai_crypto.c +++ b/arch/s390/kernel/perf_pai_crypto.c @@ -460,18 +460,24 @@ static void paicrypt_stop(struct perf_event *event, int flags) pai_stop(event, flags); } -static void paicrypt_del(struct perf_event *event, int flags) +static void pai_del(struct perf_event *event, int flags) { struct pai_mapptr *mp = this_cpu_ptr(pai_root.mapptr); struct pai_map *cpump = mp->mapptr; + int idx = PAI_PMU_IDX(event); - paicrypt_stop(event, PERF_EF_UPDATE); + pai_pmu[idx].pmu->stop(event, PERF_EF_UPDATE); if (--cpump->active_events == 0) { local_ctl_clear_bit(0, CR0_CRYPTOGRAPHY_COUNTER_BIT); WRITE_ONCE(get_lowcore()->ccd, 0); } } +static void paicrypt_del(struct perf_event *event, int flags) +{ + pai_del(event, flags); +} + /* Create raw data and save it in buffer. Calculate the delta for each * counter between this invocation and the last invocation. * Returns number of bytes copied. From f12473541356f5765e4130a7b5af77862a872a51 Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Wed, 5 Nov 2025 15:38:58 +0100 Subject: [PATCH 57/92] s390/pai_crypto: Rename paicrypt_copy() to pai_copy() To support one common PAI PMU device driver which handles both PMUs pai_crypto and pai_ext, use a common naming scheme for structures and variables suitable for both device drivers. Rename paicrypt_copy() to pai_copy() to indicate its common usage. No functional change. Signed-off-by: Thomas Richter Reviewed-by: Jan Polensky Signed-off-by: Heiko Carstens --- arch/s390/kernel/perf_pai_crypto.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/s390/kernel/perf_pai_crypto.c b/arch/s390/kernel/perf_pai_crypto.c index a014f4a1b443..870b84b0ce5f 100644 --- a/arch/s390/kernel/perf_pai_crypto.c +++ b/arch/s390/kernel/perf_pai_crypto.c @@ -485,9 +485,9 @@ static void paicrypt_del(struct perf_event *event, int flags) * 2 bytes: Number of counter * 8 bytes: Value of counter */ -static size_t paicrypt_copy(struct pai_userdata *userdata, unsigned long *page, - struct pai_pmu *pp, unsigned long *page_old, - bool exclude_user, bool exclude_kernel) +static size_t pai_copy(struct pai_userdata *userdata, unsigned long *page, + struct pai_pmu *pp, unsigned long *page_old, + bool exclude_user, bool exclude_kernel) { int i, outidx = 0; @@ -578,10 +578,10 @@ static void pai_have_sample(struct perf_event *event, struct pai_map *cpump) if (!event) /* No event active */ return; pp = &pai_pmu[PAI_PMU_IDX(event)]; - rawsize = paicrypt_copy(cpump->save, cpump->area, pp, - (unsigned long *)PAI_SAVE_AREA(event), - event->attr.exclude_user, - event->attr.exclude_kernel); + rawsize = pai_copy(cpump->save, cpump->area, pp, + (unsigned long *)PAI_SAVE_AREA(event), + event->attr.exclude_user, + event->attr.exclude_kernel); if (rawsize) /* No incremented counters */ pai_push_sample(rawsize, cpump, event); } From 35a27bad075d594ebaabc62f94b665fa2a135433 Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Wed, 5 Nov 2025 15:38:59 +0100 Subject: [PATCH 58/92] s390/pai_crypto: Make pai_root per-PMU and unify naming Prepare the common PAI PMU driver to handle multiple PMUs. Convert pai_root into an array indexed by PAI_PMU_IDX(event) so that per-CPU state becomes per-PMU. Adjust all call sites accordingly. Rename KMSG_COMPONENT and the s390dbf buffer from "pai_crypto" to "pai" for consistent naming. No functional change intended beyond log identifiers. Signed-off-by: Thomas Richter Reviewed-by: Jan Polensky Signed-off-by: Heiko Carstens --- arch/s390/kernel/perf_pai_crypto.c | 71 +++++++++++++++--------------- 1 file changed, 36 insertions(+), 35 deletions(-) diff --git a/arch/s390/kernel/perf_pai_crypto.c b/arch/s390/kernel/perf_pai_crypto.c index 870b84b0ce5f..94551b3d09f3 100644 --- a/arch/s390/kernel/perf_pai_crypto.c +++ b/arch/s390/kernel/perf_pai_crypto.c @@ -2,10 +2,10 @@ /* * Performance event support - Processor Activity Instrumentation Facility * - * Copyright IBM Corp. 2022 + * Copyright IBM Corp. 2026 * Author(s): Thomas Richter */ -#define KMSG_COMPONENT "pai_crypto" +#define KMSG_COMPONENT "pai" #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt #include @@ -49,7 +49,7 @@ struct pai_mapptr { static struct pai_root { /* Anchor to per CPU data */ refcount_t refcnt; /* Overall active events */ struct pai_mapptr __percpu *mapptr; -} pai_root; +} pai_root[PAI_PMU_MAX]; /* This table defines the different parameters of the PAI PMUs. During * initialization the machine dependent values are extracted and saved. @@ -74,14 +74,14 @@ struct pai_pmu { /* Define PAI PMU characteristics */ static struct pai_pmu pai_pmu[]; /* Forward declaration */ /* Free per CPU data when the last event is removed. */ -static void pai_root_free(void) +static void pai_root_free(int idx) { - if (refcount_dec_and_test(&pai_root.refcnt)) { - free_percpu(pai_root.mapptr); - pai_root.mapptr = NULL; + if (refcount_dec_and_test(&pai_root[idx].refcnt)) { + free_percpu(pai_root[idx].mapptr); + pai_root[idx].mapptr = NULL; } - debug_sprintf_event(paidbg, 5, "%s root.refcount %d\n", __func__, - refcount_read(&pai_root.refcnt)); + debug_sprintf_event(paidbg, 5, "%s root[%d].refcount %d\n", __func__, + idx, refcount_read(&pai_root[idx].refcnt)); } /* @@ -90,14 +90,14 @@ static void pai_root_free(void) * CPUs possible, which might be larger than the number of CPUs currently * online. */ -static int pai_root_alloc(void) +static int pai_root_alloc(int idx) { - if (!refcount_inc_not_zero(&pai_root.refcnt)) { + if (!refcount_inc_not_zero(&pai_root[idx].refcnt)) { /* The memory is already zeroed. */ - pai_root.mapptr = alloc_percpu(struct pai_mapptr); - if (!pai_root.mapptr) + pai_root[idx].mapptr = alloc_percpu(struct pai_mapptr); + if (!pai_root[idx].mapptr) return -ENOMEM; - refcount_set(&pai_root.refcnt, 1); + refcount_set(&pai_root[idx].refcnt, 1); } return 0; } @@ -119,17 +119,18 @@ static void pai_free(struct pai_mapptr *mp) */ static void pai_event_destroy_cpu(struct perf_event *event, int cpu) { - struct pai_mapptr *mp = per_cpu_ptr(pai_root.mapptr, cpu); + int idx = PAI_PMU_IDX(event); + struct pai_mapptr *mp = per_cpu_ptr(pai_root[idx].mapptr, cpu); struct pai_map *cpump = mp->mapptr; mutex_lock(&pai_reserve_mutex); - debug_sprintf_event(paidbg, 5, "%s event %#llx cpu %d users %d " - "refcnt %u\n", __func__, event->attr.config, + debug_sprintf_event(paidbg, 5, "%s event %#llx idx %d cpu %d users %d " + "refcnt %u\n", __func__, event->attr.config, idx, event->cpu, cpump->active_events, refcount_read(&cpump->refcnt)); if (refcount_dec_and_test(&cpump->refcnt)) pai_free(mp); - pai_root_free(); + pai_root_free(idx); mutex_unlock(&pai_reserve_mutex); } @@ -162,10 +163,10 @@ static u64 pai_getctr(unsigned long *page, int nr, unsigned long offset) */ static u64 pai_getdata(struct perf_event *event, bool kernel) { - struct pai_mapptr *mp = this_cpu_ptr(pai_root.mapptr); - struct pai_map *cpump = mp->mapptr; int idx = PAI_PMU_IDX(event); + struct pai_mapptr *mp = this_cpu_ptr(pai_root[idx].mapptr); struct pai_pmu *pp = &pai_pmu[idx]; + struct pai_map *cpump = mp->mapptr; unsigned int i; u64 sum = 0; @@ -213,12 +214,12 @@ static int pai_alloc_cpu(struct perf_event *event, int cpu) mutex_lock(&pai_reserve_mutex); /* Allocate root node */ - rc = pai_root_alloc(); + rc = pai_root_alloc(idx); if (rc) goto unlock; /* Allocate node for this event */ - mp = per_cpu_ptr(pai_root.mapptr, cpu); + mp = per_cpu_ptr(pai_root[idx].mapptr, cpu); cpump = mp->mapptr; if (!cpump) { /* Paicrypt_map allocated? */ rc = -ENOMEM; @@ -250,7 +251,7 @@ static int pai_alloc_cpu(struct perf_event *event, int cpu) * the event in not created, its destroy() function is never * invoked. Adjust the reference counter for the anchor. */ - pai_root_free(); + pai_root_free(idx); } unlock: mutex_unlock(&pai_reserve_mutex); @@ -387,7 +388,7 @@ static void pai_start(struct perf_event *event, int flags, { int idx = PAI_PMU_IDX(event); struct pai_pmu *pp = &pai_pmu[idx]; - struct pai_mapptr *mp = this_cpu_ptr(pai_root.mapptr); + struct pai_mapptr *mp = this_cpu_ptr(pai_root[idx].mapptr); struct pai_map *cpump = mp->mapptr; u64 sum; @@ -413,9 +414,9 @@ static void paicrypt_start(struct perf_event *event, int flags) static int pai_add(struct perf_event *event, int flags) { - struct pai_mapptr *mp = this_cpu_ptr(pai_root.mapptr); - struct pai_map *cpump = mp->mapptr; int idx = PAI_PMU_IDX(event); + struct pai_mapptr *mp = this_cpu_ptr(pai_root[idx].mapptr); + struct pai_map *cpump = mp->mapptr; unsigned long ccd; if (++cpump->active_events == 1) { @@ -437,9 +438,9 @@ static int paicrypt_add(struct perf_event *event, int flags) static void pai_have_sample(struct perf_event *, struct pai_map *); static void pai_stop(struct perf_event *event, int flags) { - struct pai_mapptr *mp = this_cpu_ptr(pai_root.mapptr); - struct pai_map *cpump = mp->mapptr; int idx = PAI_PMU_IDX(event); + struct pai_mapptr *mp = this_cpu_ptr(pai_root[idx].mapptr); + struct pai_map *cpump = mp->mapptr; if (!event->attr.sample_period) { /* Counting */ pai_pmu[idx].pmu->read(event); @@ -462,9 +463,9 @@ static void paicrypt_stop(struct perf_event *event, int flags) static void pai_del(struct perf_event *event, int flags) { - struct pai_mapptr *mp = this_cpu_ptr(pai_root.mapptr); - struct pai_map *cpump = mp->mapptr; int idx = PAI_PMU_IDX(event); + struct pai_mapptr *mp = this_cpu_ptr(pai_root[idx].mapptr); + struct pai_map *cpump = mp->mapptr; pai_pmu[idx].pmu->stop(event, PERF_EF_UPDATE); if (--cpump->active_events == 0) { @@ -587,9 +588,9 @@ static void pai_have_sample(struct perf_event *event, struct pai_map *cpump) } /* Check if there is data to be saved on schedule out of a task. */ -static void pai_have_samples(void) +static void pai_have_samples(int idx) { - struct pai_mapptr *mp = this_cpu_ptr(pai_root.mapptr); + struct pai_mapptr *mp = this_cpu_ptr(pai_root[idx].mapptr); struct pai_map *cpump = mp->mapptr; struct perf_event *event; @@ -607,7 +608,7 @@ static void paicrypt_sched_task(struct perf_event_pmu_context *pmu_ctx, * results on schedule_out and if page was dirty, save old values. */ if (!sched_in) - pai_have_samples(); + pai_have_samples(PAI_PMU_CRYPTO); } /* Attribute definitions for paicrypt interface. As with other CPU @@ -982,7 +983,7 @@ static int __init paipmu_setup(void) return install_ok; } -static int __init paicrypt_init(void) +static int __init pai_init(void) { /* Setup s390dbf facility */ paidbg = debug_register(KMSG_COMPONENT, 32, 256, 128); @@ -1001,4 +1002,4 @@ static int __init paicrypt_init(void) return 0; } -device_initcall(paicrypt_init); +device_initcall(pai_init); From 3abb6b16758045b44d5fdf50915befa6744eaaca Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Wed, 5 Nov 2025 15:39:00 +0100 Subject: [PATCH 59/92] s390/pai_crypto: Introduce PAI crypto specific event delete function Introduce PAI crypto specific event delete function to handle additional actions to be done at event removal. Signed-off-by: Thomas Richter Reviewed-by: Jan Polensky Signed-off-by: Heiko Carstens --- arch/s390/kernel/perf_pai_crypto.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/s390/kernel/perf_pai_crypto.c b/arch/s390/kernel/perf_pai_crypto.c index 94551b3d09f3..f2d7f8bc0319 100644 --- a/arch/s390/kernel/perf_pai_crypto.c +++ b/arch/s390/kernel/perf_pai_crypto.c @@ -138,7 +138,6 @@ static void pai_event_destroy(struct perf_event *event) { int cpu; - static_branch_dec(&pai_key); free_page(PAI_SAVE_AREA(event)); if (event->cpu == -1) { struct cpumask *mask = PAI_CPU_MASK(event); @@ -151,6 +150,12 @@ static void pai_event_destroy(struct perf_event *event) } } +static void paicrypt_event_destroy(struct perf_event *event) +{ + static_branch_dec(&pai_key); + pai_event_destroy(event); +} + static u64 pai_getctr(unsigned long *page, int nr, unsigned long offset) { if (offset) @@ -360,7 +365,7 @@ static int paicrypt_event_init(struct perf_event *event) int rc = pai_event_init(event, PAI_PMU_CRYPTO); if (!rc) { - event->destroy = pai_event_destroy; + event->destroy = paicrypt_event_destroy; static_branch_inc(&pai_key); } return rc; From 8b65b0ba3541c738af671377872270af6ee6a8ac Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Wed, 5 Nov 2025 15:39:01 +0100 Subject: [PATCH 60/92] s390/pai_crypto: Merge pai_ext PMU into pai_crypto Combine PAI cryptography and PAI extension (NNPA) PMUs in one driver. Remove file perf_pai_ext.c and registration of PMU "pai_ext" from perf_pai_crypto.c. Includes: - Shared alloc/free and sched_task handling - NNPA events with exclude_kernel enforced, exclude_user rejected - Setup CR0 bits for both PMUs Signed-off-by: Thomas Richter Reviewed-by: Jan Polensky Signed-off-by: Heiko Carstens --- arch/s390/kernel/Makefile | 2 +- arch/s390/kernel/perf_pai_crypto.c | 237 ++++++++- arch/s390/kernel/perf_pai_ext.c | 756 ----------------------------- 3 files changed, 230 insertions(+), 765 deletions(-) delete mode 100644 arch/s390/kernel/perf_pai_ext.c diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index eb06ff888314..558f7c5bfe32 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile @@ -79,7 +79,7 @@ obj-$(CONFIG_IMA_SECURE_AND_OR_TRUSTED_BOOT) += ima_arch.o obj-$(CONFIG_PERF_EVENTS) += perf_event.o obj-$(CONFIG_PERF_EVENTS) += perf_cpum_cf.o perf_cpum_sf.o obj-$(CONFIG_PERF_EVENTS) += perf_cpum_cf_events.o perf_regs.o -obj-$(CONFIG_PERF_EVENTS) += perf_pai_crypto.o perf_pai_ext.o +obj-$(CONFIG_PERF_EVENTS) += perf_pai_crypto.o obj-$(CONFIG_TRACEPOINTS) += trace.o diff --git a/arch/s390/kernel/perf_pai_crypto.c b/arch/s390/kernel/perf_pai_crypto.c index f2d7f8bc0319..1fac41a0aa09 100644 --- a/arch/s390/kernel/perf_pai_crypto.c +++ b/arch/s390/kernel/perf_pai_crypto.c @@ -25,14 +25,32 @@ DEFINE_STATIC_KEY_FALSE(pai_key); enum { PAI_PMU_CRYPTO, /* Index of PMU pai_crypto */ + PAI_PMU_EXT, /* Index of PMU pai_ext */ PAI_PMU_MAX /* # of PAI PMUs */ }; +enum { + PAIE1_CB_SZ = 0x200, /* Size of PAIE1 control block */ + PAIE1_CTRBLOCK_SZ = 0x400 /* Size of PAIE1 counter blocks */ +}; + struct pai_userdata { u16 num; u64 value; } __packed; +/* Create the PAI extension 1 control block area. + * The PAI extension control block 1 is pointed to by lowcore + * address 0x1508 for each CPU. This control block is 512 bytes in size + * and requires a 512 byte boundary alignment. + */ +struct paiext_cb { /* PAI extension 1 control block */ + u64 header; /* Not used */ + u64 reserved1; + u64 acc; /* Addr to analytics counter control block */ + u8 reserved2[488]; +} __packed; + struct pai_map { unsigned long *area; /* Area for CPU to store counters */ struct pai_userdata *save; /* Page to store no-zero counters */ @@ -40,6 +58,8 @@ struct pai_map { refcount_t refcnt; /* Reference count mapped buffers */ struct perf_event *event; /* Perf event for sampling */ struct list_head syswide_list; /* List system-wide sampling events */ + struct paiext_cb *paiext_cb; /* PAI extension control block area */ + bool fullpage; /* True: counter area is a full page */ }; struct pai_mapptr { @@ -108,7 +128,11 @@ static DEFINE_MUTEX(pai_reserve_mutex); /* Free all memory allocated for event counting/sampling setup */ static void pai_free(struct pai_mapptr *mp) { - free_page((unsigned long)mp->mapptr->area); + if (mp->mapptr->fullpage) + free_page((unsigned long)mp->mapptr->area); + else + kfree(mp->mapptr->area); + kfree(mp->mapptr->paiext_cb); kvfree(mp->mapptr->save); kfree(mp->mapptr); mp->mapptr = NULL; @@ -215,6 +239,7 @@ static int pai_alloc_cpu(struct perf_event *event, int cpu) { int rc, idx = PAI_PMU_IDX(event); struct pai_map *cpump = NULL; + bool need_paiext_cb = false; struct pai_mapptr *mp; mutex_lock(&pai_reserve_mutex); @@ -235,11 +260,33 @@ static int pai_alloc_cpu(struct perf_event *event, int cpu) * Only the first counting event has to allocate a page. */ mp->mapptr = cpump; - cpump->area = (unsigned long *)get_zeroed_page(GFP_KERNEL); + if (idx == PAI_PMU_CRYPTO) { + cpump->area = (unsigned long *)get_zeroed_page(GFP_KERNEL); + /* free_page() can handle 0x0 address */ + cpump->fullpage = true; + } else { /* PAI_PMU_EXT */ + /* + * Allocate memory for counter area and counter extraction. + * These are + * - a 512 byte block and requires 512 byte boundary + * alignment. + * - a 1KB byte block and requires 1KB boundary + * alignment. + * Only the first counting event has to allocate the area. + * + * Note: This works with commit 59bb47985c1d by default. + * Backporting this to kernels without this commit might + * needs adjustment. + */ + cpump->area = kzalloc(pai_pmu[idx].area_size, GFP_KERNEL); + cpump->paiext_cb = kzalloc(PAIE1_CB_SZ, GFP_KERNEL); + need_paiext_cb = true; + } cpump->save = kvmalloc_array(pai_pmu[idx].num_avail + 1, sizeof(struct pai_userdata), GFP_KERNEL); - if (!cpump->area || !cpump->save) { + if (!cpump->area || !cpump->save || + (need_paiext_cb && !cpump->paiext_cb)) { pai_free(mp); goto undo; } @@ -314,6 +361,8 @@ static int pai_event_valid(struct perf_event *event, int idx) /* PAI crypto event must be in valid range, try others if not */ if (a->config < pp->base || a->config > pp->base + pp->num_avail) return -ENOENT; + if (idx == PAI_PMU_EXT && a->exclude_user) + return -EINVAL; PAI_PMU_IDX(event) = idx; return 0; } @@ -422,12 +471,21 @@ static int pai_add(struct perf_event *event, int flags) int idx = PAI_PMU_IDX(event); struct pai_mapptr *mp = this_cpu_ptr(pai_root[idx].mapptr); struct pai_map *cpump = mp->mapptr; + struct paiext_cb *pcb = cpump->paiext_cb; unsigned long ccd; if (++cpump->active_events == 1) { - ccd = virt_to_phys(cpump->area) | PAI_CRYPTO_KERNEL_OFFSET; - WRITE_ONCE(get_lowcore()->ccd, ccd); - local_ctl_set_bit(0, CR0_CRYPTOGRAPHY_COUNTER_BIT); + if (!pcb) { /* PAI crypto */ + ccd = virt_to_phys(cpump->area) | PAI_CRYPTO_KERNEL_OFFSET; + WRITE_ONCE(get_lowcore()->ccd, ccd); + local_ctl_set_bit(0, CR0_CRYPTOGRAPHY_COUNTER_BIT); + } else { /* PAI extension 1 */ + ccd = virt_to_phys(pcb); + WRITE_ONCE(get_lowcore()->aicd, ccd); + pcb->acc = virt_to_phys(cpump->area) | 0x1; + /* Enable CPU instruction lookup for PAIE1 control block */ + local_ctl_set_bit(0, CR0_PAI_EXTENSION_BIT); + } } if (flags & PERF_EF_START) pai_pmu[idx].pmu->start(event, PERF_EF_RELOAD); @@ -471,11 +529,19 @@ static void pai_del(struct perf_event *event, int flags) int idx = PAI_PMU_IDX(event); struct pai_mapptr *mp = this_cpu_ptr(pai_root[idx].mapptr); struct pai_map *cpump = mp->mapptr; + struct paiext_cb *pcb = cpump->paiext_cb; pai_pmu[idx].pmu->stop(event, PERF_EF_UPDATE); if (--cpump->active_events == 0) { - local_ctl_clear_bit(0, CR0_CRYPTOGRAPHY_COUNTER_BIT); - WRITE_ONCE(get_lowcore()->ccd, 0); + if (!pcb) { /* PAI crypto */ + local_ctl_clear_bit(0, CR0_CRYPTOGRAPHY_COUNTER_BIT); + WRITE_ONCE(get_lowcore()->ccd, 0); + } else { /* PAI extension 1 */ + /* Disable CPU instruction lookup for PAIE1 control block */ + local_ctl_clear_bit(0, CR0_PAI_EXTENSION_BIT); + pcb->acc = 0; + WRITE_ONCE(get_lowcore()->aicd, 0); + } } } @@ -616,6 +682,70 @@ static void paicrypt_sched_task(struct perf_event_pmu_context *pmu_ctx, pai_have_samples(PAI_PMU_CRYPTO); } +/* ============================= paiext ====================================*/ + +static void paiext_event_destroy(struct perf_event *event) +{ + pai_event_destroy(event); +} + +/* Might be called on different CPU than the one the event is intended for. */ +static int paiext_event_init(struct perf_event *event) +{ + int rc = pai_event_init(event, PAI_PMU_EXT); + + if (!rc) { + event->attr.exclude_kernel = true; /* No kernel space part */ + event->destroy = paiext_event_destroy; + /* Offset of NNPA in paiext_cb */ + event->hw.config_base = offsetof(struct paiext_cb, acc); + } + return rc; +} + +static u64 paiext_getall(struct perf_event *event) +{ + return pai_getdata(event, false); +} + +static void paiext_read(struct perf_event *event) +{ + pai_read(event, paiext_getall); +} + +static void paiext_start(struct perf_event *event, int flags) +{ + pai_start(event, flags, paiext_getall); +} + +static int paiext_add(struct perf_event *event, int flags) +{ + return pai_add(event, flags); +} + +static void paiext_stop(struct perf_event *event, int flags) +{ + pai_stop(event, flags); +} + +static void paiext_del(struct perf_event *event, int flags) +{ + pai_del(event, flags); +} + +/* Called on schedule-in and schedule-out. No access to event structure, + * but for sampling only event NNPA_ALL is allowed. + */ +static void paiext_sched_task(struct perf_event_pmu_context *pmu_ctx, + struct task_struct *task, bool sched_in) +{ + /* We started with a clean page on event installation. So read out + * results on schedule_out and if page was dirty, save old values. + */ + if (!sched_in) + pai_have_samples(PAI_PMU_EXT); +} + /* Attribute definitions for paicrypt interface. As with other CPU * Measurement Facilities, there is one attribute per mapped counter. * The number of mapped counters may vary per machine generation. Use @@ -845,6 +975,81 @@ static const char * const paicrypt_ctrnames[] = { [172] = "PCKMO_ENCRYPT_AES_XTS_256", }; +static struct attribute *paiext_format_attr[] = { + &format_attr_event.attr, + NULL, +}; + +static struct attribute_group paiext_events_group = { + .name = "events", + .attrs = NULL, /* Filled in attr_event_init() */ +}; + +static struct attribute_group paiext_format_group = { + .name = "format", + .attrs = paiext_format_attr, +}; + +static const struct attribute_group *paiext_attr_groups[] = { + &paiext_events_group, + &paiext_format_group, + NULL, +}; + +/* Performance monitoring unit for mapped counters */ +static struct pmu paiext = { + .task_ctx_nr = perf_hw_context, + .event_init = paiext_event_init, + .add = paiext_add, + .del = paiext_del, + .start = paiext_start, + .stop = paiext_stop, + .read = paiext_read, + .sched_task = paiext_sched_task, + .attr_groups = paiext_attr_groups, +}; + +/* List of symbolic PAI extension 1 NNPA counter names. */ +static const char * const paiext_ctrnames[] = { + [0] = "NNPA_ALL", + [1] = "NNPA_ADD", + [2] = "NNPA_SUB", + [3] = "NNPA_MUL", + [4] = "NNPA_DIV", + [5] = "NNPA_MIN", + [6] = "NNPA_MAX", + [7] = "NNPA_LOG", + [8] = "NNPA_EXP", + [9] = "NNPA_IBM_RESERVED_9", + [10] = "NNPA_RELU", + [11] = "NNPA_TANH", + [12] = "NNPA_SIGMOID", + [13] = "NNPA_SOFTMAX", + [14] = "NNPA_BATCHNORM", + [15] = "NNPA_MAXPOOL2D", + [16] = "NNPA_AVGPOOL2D", + [17] = "NNPA_LSTMACT", + [18] = "NNPA_GRUACT", + [19] = "NNPA_CONVOLUTION", + [20] = "NNPA_MATMUL_OP", + [21] = "NNPA_MATMUL_OP_BCAST23", + [22] = "NNPA_SMALLBATCH", + [23] = "NNPA_LARGEDIM", + [24] = "NNPA_SMALLTENSOR", + [25] = "NNPA_1MFRAME", + [26] = "NNPA_2GFRAME", + [27] = "NNPA_ACCESSEXCEPT", + [28] = "NNPA_TRANSFORM", + [29] = "NNPA_GELU", + [30] = "NNPA_MOMENTS", + [31] = "NNPA_LAYERNORM", + [32] = "NNPA_MATMUL_OP_BCAST1", + [33] = "NNPA_SQRT", + [34] = "NNPA_INVSQRT", + [35] = "NNPA_NORM", + [36] = "NNPA_REDUCE", +}; + static void __init attr_event_free(struct attribute **attrs) { struct perf_pmu_events_attr *pa; @@ -946,6 +1151,19 @@ static struct pai_pmu pai_pmu[] __refdata = { .exit = pai_pmu_exit, .pmu = &paicrypt, .event_group = &paicrypt_events_group + }, + [PAI_PMU_EXT] = { + .pmuname = "pai_ext", + .facility_nr = 197, + .num_named = ARRAY_SIZE(paiext_ctrnames), + .names = paiext_ctrnames, + .base = PAI_NNPA_BASE, + .kernel_offset = 0, + .area_size = PAIE1_CTRBLOCK_SZ, + .init = pai_pmu_init, + .exit = pai_pmu_exit, + .pmu = &paiext, + .event_group = &paiext_events_group } }; @@ -977,6 +1195,9 @@ static int __init paipmu_setup(void) continue; } break; + case PAI_PMU_EXT: + p->num_avail = ib.num_nnpa; + break; } p->num_avail += 1; /* Add xxx_ALL event */ if (p->init) { diff --git a/arch/s390/kernel/perf_pai_ext.c b/arch/s390/kernel/perf_pai_ext.c deleted file mode 100644 index 7b32935273ce..000000000000 --- a/arch/s390/kernel/perf_pai_ext.c +++ /dev/null @@ -1,756 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Performance event support - Processor Activity Instrumentation Extension - * Facility - * - * Copyright IBM Corp. 2022 - * Author(s): Thomas Richter - */ -#define KMSG_COMPONENT "pai_ext" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define PAIE1_CB_SZ 0x200 /* Size of PAIE1 control block */ -#define PAIE1_CTRBLOCK_SZ 0x400 /* Size of PAIE1 counter blocks */ - -static debug_info_t *paiext_dbg; -static unsigned int paiext_cnt; /* Extracted with QPACI instruction */ - -struct pai_userdata { - u16 num; - u64 value; -} __packed; - -/* Create the PAI extension 1 control block area. - * The PAI extension control block 1 is pointed to by lowcore - * address 0x1508 for each CPU. This control block is 512 bytes in size - * and requires a 512 byte boundary alignment. - */ -struct paiext_cb { /* PAI extension 1 control block */ - u64 header; /* Not used */ - u64 reserved1; - u64 acc; /* Addr to analytics counter control block */ - u8 reserved2[488]; -} __packed; - -struct paiext_map { - unsigned long *area; /* Area for CPU to store counters */ - struct pai_userdata *save; /* Area to store non-zero counters */ - unsigned int active_events; /* # of PAI Extension users */ - refcount_t refcnt; - struct perf_event *event; /* Perf event for sampling */ - struct paiext_cb *paiext_cb; /* PAI extension control block area */ - struct list_head syswide_list; /* List system-wide sampling events */ -}; - -struct paiext_mapptr { - struct paiext_map *mapptr; -}; - -static struct paiext_root { /* Anchor to per CPU data */ - refcount_t refcnt; /* Overall active events */ - struct paiext_mapptr __percpu *mapptr; -} paiext_root; - -/* Free per CPU data when the last event is removed. */ -static void paiext_root_free(void) -{ - if (refcount_dec_and_test(&paiext_root.refcnt)) { - free_percpu(paiext_root.mapptr); - paiext_root.mapptr = NULL; - } - debug_sprintf_event(paiext_dbg, 5, "%s root.refcount %d\n", __func__, - refcount_read(&paiext_root.refcnt)); -} - -/* On initialization of first event also allocate per CPU data dynamically. - * Start with an array of pointers, the array size is the maximum number of - * CPUs possible, which might be larger than the number of CPUs currently - * online. - */ -static int paiext_root_alloc(void) -{ - if (!refcount_inc_not_zero(&paiext_root.refcnt)) { - /* The memory is already zeroed. */ - paiext_root.mapptr = alloc_percpu(struct paiext_mapptr); - if (!paiext_root.mapptr) { - /* Returning without refcnt adjustment is ok. The - * error code is handled by paiext_alloc() which - * decrements refcnt when an event can not be - * created. - */ - return -ENOMEM; - } - refcount_set(&paiext_root.refcnt, 1); - } - return 0; -} - -/* Protects against concurrent increment of sampler and counter member - * increments at the same time and prohibits concurrent execution of - * counting and sampling events. - * Ensures that analytics counter block is deallocated only when the - * sampling and counting on that cpu is zero. - * For details see paiext_alloc(). - */ -static DEFINE_MUTEX(paiext_reserve_mutex); - -/* Free all memory allocated for event counting/sampling setup */ -static void paiext_free(struct paiext_mapptr *mp) -{ - kfree(mp->mapptr->area); - kfree(mp->mapptr->paiext_cb); - kvfree(mp->mapptr->save); - kfree(mp->mapptr); - mp->mapptr = NULL; -} - -/* Release the PMU if event is the last perf event */ -static void paiext_event_destroy_cpu(struct perf_event *event, int cpu) -{ - struct paiext_mapptr *mp = per_cpu_ptr(paiext_root.mapptr, cpu); - struct paiext_map *cpump = mp->mapptr; - - mutex_lock(&paiext_reserve_mutex); - if (refcount_dec_and_test(&cpump->refcnt)) /* Last reference gone */ - paiext_free(mp); - paiext_root_free(); - mutex_unlock(&paiext_reserve_mutex); -} - -static void paiext_event_destroy(struct perf_event *event) -{ - int cpu; - - free_page(PAI_SAVE_AREA(event)); - if (event->cpu == -1) { - struct cpumask *mask = PAI_CPU_MASK(event); - - for_each_cpu(cpu, mask) - paiext_event_destroy_cpu(event, cpu); - kfree(mask); - } else { - paiext_event_destroy_cpu(event, event->cpu); - } - debug_sprintf_event(paiext_dbg, 4, "%s cpu %d\n", __func__, - event->cpu); -} - -/* Used to avoid races in checking concurrent access of counting and - * sampling for pai_extension events. - * - * Only one instance of event pai_ext/NNPA_ALL/ for sampling is - * allowed and when this event is running, no counting event is allowed. - * Several counting events are allowed in parallel, but no sampling event - * is allowed while one (or more) counting events are running. - * - * This function is called in process context and it is safe to block. - * When the event initialization functions fails, no other call back will - * be invoked. - * - * Allocate the memory for the event. - */ -static int paiext_alloc_cpu(struct perf_event *event, int cpu) -{ - struct paiext_mapptr *mp; - struct paiext_map *cpump; - int rc; - - mutex_lock(&paiext_reserve_mutex); - rc = paiext_root_alloc(); - if (rc) - goto unlock; - - mp = per_cpu_ptr(paiext_root.mapptr, cpu); - cpump = mp->mapptr; - if (!cpump) { /* Paiext_map allocated? */ - rc = -ENOMEM; - cpump = kzalloc(sizeof(*cpump), GFP_KERNEL); - if (!cpump) - goto undo; - - /* Allocate memory for counter area and counter extraction. - * These are - * - a 512 byte block and requires 512 byte boundary alignment. - * - a 1KB byte block and requires 1KB boundary alignment. - * Only the first counting event has to allocate the area. - * - * Note: This works with commit 59bb47985c1d by default. - * Backporting this to kernels without this commit might - * need adjustment. - */ - mp->mapptr = cpump; - cpump->area = kzalloc(PAIE1_CTRBLOCK_SZ, GFP_KERNEL); - cpump->paiext_cb = kzalloc(PAIE1_CB_SZ, GFP_KERNEL); - cpump->save = kvmalloc_array(paiext_cnt + 1, - sizeof(struct pai_userdata), - GFP_KERNEL); - if (!cpump->save || !cpump->area || !cpump->paiext_cb) { - paiext_free(mp); - goto undo; - } - INIT_LIST_HEAD(&cpump->syswide_list); - refcount_set(&cpump->refcnt, 1); - rc = 0; - } else { - refcount_inc(&cpump->refcnt); - } - -undo: - if (rc) { - /* Error in allocation of event, decrement anchor. Since - * the event in not created, its destroy() function is never - * invoked. Adjust the reference counter for the anchor. - */ - paiext_root_free(); - } -unlock: - mutex_unlock(&paiext_reserve_mutex); - /* If rc is non-zero, no increment of counter/sampler was done. */ - return rc; -} - -static int paiext_alloc(struct perf_event *event) -{ - struct cpumask *maskptr; - int cpu, rc = -ENOMEM; - - maskptr = kzalloc(sizeof(*maskptr), GFP_KERNEL); - if (!maskptr) - goto out; - - for_each_online_cpu(cpu) { - rc = paiext_alloc_cpu(event, cpu); - if (rc) { - for_each_cpu(cpu, maskptr) - paiext_event_destroy_cpu(event, cpu); - kfree(maskptr); - goto out; - } - cpumask_set_cpu(cpu, maskptr); - } - - /* - * On error all cpumask are freed and all events have been destroyed. - * Save of which CPUs data structures have been allocated for. - * Release them in paicrypt_event_destroy call back function - * for this event. - */ - PAI_CPU_MASK(event) = maskptr; - rc = 0; -out: - return rc; -} - -/* The PAI extension 1 control block supports up to 128 entries. Return - * the index within PAIE1_CB given the event number. Also validate event - * number. - */ -static int paiext_event_valid(struct perf_event *event) -{ - u64 cfg = event->attr.config; - - if (cfg >= PAI_NNPA_BASE && cfg <= PAI_NNPA_BASE + paiext_cnt) { - /* Offset NNPA in paiext_cb */ - event->hw.config_base = offsetof(struct paiext_cb, acc); - return 0; - } - return -ENOENT; -} - -/* Might be called on different CPU than the one the event is intended for. */ -static int paiext_event_init(struct perf_event *event) -{ - struct perf_event_attr *a = &event->attr; - int rc; - - /* PMU pai_ext registered as PERF_TYPE_RAW, check event type */ - if (a->type != PERF_TYPE_RAW && event->pmu->type != a->type) - return -ENOENT; - /* PAI extension event must be valid and in supported range */ - rc = paiext_event_valid(event); - if (rc) - return rc; - /* Allow only event NNPA_ALL for sampling. */ - if (a->sample_period && a->config != PAI_NNPA_BASE) - return -EINVAL; - /* Prohibit exclude_user event selection */ - if (a->exclude_user) - return -EINVAL; - /* Get a page to store last counter values for sampling */ - if (a->sample_period) { - PAI_SAVE_AREA(event) = get_zeroed_page(GFP_KERNEL); - if (!PAI_SAVE_AREA(event)) - return -ENOMEM; - } - - if (event->cpu >= 0) - rc = paiext_alloc_cpu(event, event->cpu); - else - rc = paiext_alloc(event); - if (rc) { - free_page(PAI_SAVE_AREA(event)); - return rc; - } - event->destroy = paiext_event_destroy; - - if (a->sample_period) { - a->sample_period = 1; - a->freq = 0; - /* Register for paicrypt_sched_task() to be called */ - event->attach_state |= PERF_ATTACH_SCHED_CB; - /* Add raw data which are the memory mapped counters */ - a->sample_type |= PERF_SAMPLE_RAW; - /* Turn off inheritance */ - a->inherit = 0; - } - - return 0; -} - -static u64 paiext_getctr(unsigned long *area, int nr) -{ - return area[nr]; -} - -/* Read the counter values. Return value from location in buffer. For event - * NNPA_ALL sum up all events. - */ -static u64 paiext_getdata(struct perf_event *event) -{ - struct paiext_mapptr *mp = this_cpu_ptr(paiext_root.mapptr); - struct paiext_map *cpump = mp->mapptr; - u64 sum = 0; - int i; - - if (event->attr.config != PAI_NNPA_BASE) - return paiext_getctr(cpump->area, - event->attr.config - PAI_NNPA_BASE); - - for (i = 1; i <= paiext_cnt; i++) - sum += paiext_getctr(cpump->area, i); - - return sum; -} - -static u64 paiext_getall(struct perf_event *event) -{ - return paiext_getdata(event); -} - -static void paiext_read(struct perf_event *event) -{ - u64 prev, new, delta; - - prev = local64_read(&event->hw.prev_count); - new = paiext_getall(event); - local64_set(&event->hw.prev_count, new); - delta = new - prev; - local64_add(delta, &event->count); -} - -static void paiext_start(struct perf_event *event, int flags) -{ - struct paiext_mapptr *mp = this_cpu_ptr(paiext_root.mapptr); - struct paiext_map *cpump = mp->mapptr; - u64 sum; - - if (!event->attr.sample_period) { /* Counting */ - sum = paiext_getall(event); /* Get current value */ - local64_set(&event->hw.prev_count, sum); - } else { /* Sampling */ - memcpy((void *)PAI_SAVE_AREA(event), cpump->area, - PAIE1_CTRBLOCK_SZ); - /* Enable context switch callback for system-wide sampling */ - if (!(event->attach_state & PERF_ATTACH_TASK)) { - list_add_tail(PAI_SWLIST(event), &cpump->syswide_list); - perf_sched_cb_inc(event->pmu); - } else { - cpump->event = event; - } - } -} - -static int paiext_add(struct perf_event *event, int flags) -{ - struct paiext_mapptr *mp = this_cpu_ptr(paiext_root.mapptr); - struct paiext_map *cpump = mp->mapptr; - struct paiext_cb *pcb = cpump->paiext_cb; - - if (++cpump->active_events == 1) { - get_lowcore()->aicd = virt_to_phys(cpump->paiext_cb); - pcb->acc = virt_to_phys(cpump->area) | 0x1; - /* Enable CPU instruction lookup for PAIE1 control block */ - local_ctl_set_bit(0, CR0_PAI_EXTENSION_BIT); - } - if (flags & PERF_EF_START) - paiext_start(event, PERF_EF_RELOAD); - event->hw.state = 0; - return 0; -} - -static void paiext_have_sample(struct perf_event *, struct paiext_map *); -static void paiext_stop(struct perf_event *event, int flags) -{ - struct paiext_mapptr *mp = this_cpu_ptr(paiext_root.mapptr); - struct paiext_map *cpump = mp->mapptr; - - if (!event->attr.sample_period) { /* Counting */ - paiext_read(event); - } else { /* Sampling */ - if (!(event->attach_state & PERF_ATTACH_TASK)) { - list_del(PAI_SWLIST(event)); - perf_sched_cb_dec(event->pmu); - } else { - paiext_have_sample(event, cpump); - cpump->event = NULL; - } - } - event->hw.state = PERF_HES_STOPPED; -} - -static void paiext_del(struct perf_event *event, int flags) -{ - struct paiext_mapptr *mp = this_cpu_ptr(paiext_root.mapptr); - struct paiext_map *cpump = mp->mapptr; - struct paiext_cb *pcb = cpump->paiext_cb; - - paiext_stop(event, PERF_EF_UPDATE); - if (--cpump->active_events == 0) { - /* Disable CPU instruction lookup for PAIE1 control block */ - local_ctl_clear_bit(0, CR0_PAI_EXTENSION_BIT); - pcb->acc = 0; - get_lowcore()->aicd = 0; - } -} - -/* Create raw data and save it in buffer. Returns number of bytes copied. - * Saves only positive counter entries of the form - * 2 bytes: Number of counter - * 8 bytes: Value of counter - */ -static size_t paiext_copy(struct pai_userdata *userdata, unsigned long *area, - unsigned long *area_old) -{ - int i, outidx = 0; - - for (i = 1; i <= paiext_cnt; i++) { - u64 val = paiext_getctr(area, i); - u64 val_old = paiext_getctr(area_old, i); - - if (val >= val_old) - val -= val_old; - else - val = (~0ULL - val_old) + val + 1; - if (val) { - userdata[outidx].num = i; - userdata[outidx].value = val; - outidx++; - } - } - return outidx * sizeof(*userdata); -} - -/* Write sample when one or more counters values are nonzero. - * - * Note: The function paiext_sched_task() and paiext_push_sample() are not - * invoked after function paiext_del() has been called because of function - * perf_sched_cb_dec(). - * The function paiext_sched_task() and paiext_push_sample() are only - * called when sampling is active. Function perf_sched_cb_inc() - * has been invoked to install function paiext_sched_task() as call back - * to run at context switch time (see paiext_add()). - * - * This causes function perf_event_context_sched_out() and - * perf_event_context_sched_in() to check whether the PMU has installed an - * sched_task() callback. That callback is not active after paiext_del() - * returns and has deleted the event on that CPU. - */ -static int paiext_push_sample(size_t rawsize, struct paiext_map *cpump, - struct perf_event *event) -{ - struct perf_sample_data data; - struct perf_raw_record raw; - struct pt_regs regs; - int overflow; - - /* Setup perf sample */ - memset(®s, 0, sizeof(regs)); - memset(&raw, 0, sizeof(raw)); - memset(&data, 0, sizeof(data)); - perf_sample_data_init(&data, 0, event->hw.last_period); - if (event->attr.sample_type & PERF_SAMPLE_TID) { - data.tid_entry.pid = task_tgid_nr(current); - data.tid_entry.tid = task_pid_nr(current); - } - if (event->attr.sample_type & PERF_SAMPLE_TIME) - data.time = event->clock(); - if (event->attr.sample_type & (PERF_SAMPLE_ID | PERF_SAMPLE_IDENTIFIER)) - data.id = event->id; - if (event->attr.sample_type & PERF_SAMPLE_CPU) - data.cpu_entry.cpu = smp_processor_id(); - if (event->attr.sample_type & PERF_SAMPLE_RAW) { - raw.frag.size = rawsize; - raw.frag.data = cpump->save; - perf_sample_save_raw_data(&data, event, &raw); - } - - overflow = perf_event_overflow(event, &data, ®s); - perf_event_update_userpage(event); - /* Save NNPA lowcore area after read in event */ - memcpy((void *)PAI_SAVE_AREA(event), cpump->area, - PAIE1_CTRBLOCK_SZ); - return overflow; -} - -/* Check if there is data to be saved on schedule out of a task. */ -static void paiext_have_sample(struct perf_event *event, - struct paiext_map *cpump) -{ - size_t rawsize; - - if (!event) - return; - rawsize = paiext_copy(cpump->save, cpump->area, - (unsigned long *)PAI_SAVE_AREA(event)); - if (rawsize) /* Incremented counters */ - paiext_push_sample(rawsize, cpump, event); -} - -/* Check if there is data to be saved on schedule out of a task. */ -static void paiext_have_samples(void) -{ - struct paiext_mapptr *mp = this_cpu_ptr(paiext_root.mapptr); - struct paiext_map *cpump = mp->mapptr; - struct perf_event *event; - - list_for_each_entry(event, &cpump->syswide_list, hw.tp_list) - paiext_have_sample(event, cpump); -} - -/* Called on schedule-in and schedule-out. No access to event structure, - * but for sampling only event NNPA_ALL is allowed. - */ -static void paiext_sched_task(struct perf_event_pmu_context *pmu_ctx, - struct task_struct *task, bool sched_in) -{ - /* We started with a clean page on event installation. So read out - * results on schedule_out and if page was dirty, save old values. - */ - if (!sched_in) - paiext_have_samples(); -} - -/* Attribute definitions for pai extension1 interface. As with other CPU - * Measurement Facilities, there is one attribute per mapped counter. - * The number of mapped counters may vary per machine generation. Use - * the QUERY PROCESSOR ACTIVITY COUNTER INFORMATION (QPACI) instruction - * to determine the number of mapped counters. The instructions returns - * a positive number, which is the highest number of supported counters. - * All counters less than this number are also supported, there are no - * holes. A returned number of zero means no support for mapped counters. - * - * The identification of the counter is a unique number. The chosen range - * is 0x1800 + offset in mapped kernel page. - * All CPU Measurement Facility counters identifiers must be unique and - * the numbers from 0 to 496 are already used for the CPU Measurement - * Counter facility. Number 0x1000 to 0x103e are used for PAI cryptography - * counters. - * Numbers 0xb0000, 0xbc000 and 0xbd000 are already - * used for the CPU Measurement Sampling facility. - */ -PMU_FORMAT_ATTR(event, "config:0-63"); - -static struct attribute *paiext_format_attr[] = { - &format_attr_event.attr, - NULL, -}; - -static struct attribute_group paiext_events_group = { - .name = "events", - .attrs = NULL, /* Filled in attr_event_init() */ -}; - -static struct attribute_group paiext_format_group = { - .name = "format", - .attrs = paiext_format_attr, -}; - -static const struct attribute_group *paiext_attr_groups[] = { - &paiext_events_group, - &paiext_format_group, - NULL, -}; - -/* Performance monitoring unit for mapped counters */ -static struct pmu paiext = { - .task_ctx_nr = perf_hw_context, - .event_init = paiext_event_init, - .add = paiext_add, - .del = paiext_del, - .start = paiext_start, - .stop = paiext_stop, - .read = paiext_read, - .sched_task = paiext_sched_task, - .attr_groups = paiext_attr_groups, -}; - -/* List of symbolic PAI extension 1 NNPA counter names. */ -static const char * const paiext_ctrnames[] = { - [0] = "NNPA_ALL", - [1] = "NNPA_ADD", - [2] = "NNPA_SUB", - [3] = "NNPA_MUL", - [4] = "NNPA_DIV", - [5] = "NNPA_MIN", - [6] = "NNPA_MAX", - [7] = "NNPA_LOG", - [8] = "NNPA_EXP", - [9] = "NNPA_IBM_RESERVED_9", - [10] = "NNPA_RELU", - [11] = "NNPA_TANH", - [12] = "NNPA_SIGMOID", - [13] = "NNPA_SOFTMAX", - [14] = "NNPA_BATCHNORM", - [15] = "NNPA_MAXPOOL2D", - [16] = "NNPA_AVGPOOL2D", - [17] = "NNPA_LSTMACT", - [18] = "NNPA_GRUACT", - [19] = "NNPA_CONVOLUTION", - [20] = "NNPA_MATMUL_OP", - [21] = "NNPA_MATMUL_OP_BCAST23", - [22] = "NNPA_SMALLBATCH", - [23] = "NNPA_LARGEDIM", - [24] = "NNPA_SMALLTENSOR", - [25] = "NNPA_1MFRAME", - [26] = "NNPA_2GFRAME", - [27] = "NNPA_ACCESSEXCEPT", - [28] = "NNPA_TRANSFORM", - [29] = "NNPA_GELU", - [30] = "NNPA_MOMENTS", - [31] = "NNPA_LAYERNORM", - [32] = "NNPA_MATMUL_OP_BCAST1", - [33] = "NNPA_SQRT", - [34] = "NNPA_INVSQRT", - [35] = "NNPA_NORM", - [36] = "NNPA_REDUCE", -}; - -static void __init attr_event_free(struct attribute **attrs, int num) -{ - struct perf_pmu_events_attr *pa; - struct device_attribute *dap; - int i; - - for (i = 0; i < num; i++) { - dap = container_of(attrs[i], struct device_attribute, attr); - pa = container_of(dap, struct perf_pmu_events_attr, attr); - kfree(pa); - } - kfree(attrs); -} - -static int __init attr_event_init_one(struct attribute **attrs, int num) -{ - struct perf_pmu_events_attr *pa; - - /* Index larger than array_size, no counter name available */ - if (num >= ARRAY_SIZE(paiext_ctrnames)) { - attrs[num] = NULL; - return 0; - } - - pa = kzalloc(sizeof(*pa), GFP_KERNEL); - if (!pa) - return -ENOMEM; - - sysfs_attr_init(&pa->attr.attr); - pa->id = PAI_NNPA_BASE + num; - pa->attr.attr.name = paiext_ctrnames[num]; - pa->attr.attr.mode = 0444; - pa->attr.show = cpumf_events_sysfs_show; - pa->attr.store = NULL; - attrs[num] = &pa->attr.attr; - return 0; -} - -/* Create PMU sysfs event attributes on the fly. */ -static int __init attr_event_init(void) -{ - struct attribute **attrs; - int ret, i; - - attrs = kmalloc_array(paiext_cnt + 2, sizeof(*attrs), GFP_KERNEL); - if (!attrs) - return -ENOMEM; - for (i = 0; i <= paiext_cnt; i++) { - ret = attr_event_init_one(attrs, i); - if (ret) { - attr_event_free(attrs, i); - return ret; - } - } - attrs[i] = NULL; - paiext_events_group.attrs = attrs; - return 0; -} - -static int __init paiext_init(void) -{ - struct qpaci_info_block ib; - int rc = -ENOMEM; - - if (!test_facility(197)) - return 0; - - qpaci(&ib); - paiext_cnt = ib.num_nnpa; - if (paiext_cnt >= PAI_NNPA_MAXCTR) - paiext_cnt = PAI_NNPA_MAXCTR; - if (!paiext_cnt) - return 0; - - rc = attr_event_init(); - if (rc) { - pr_err("Creation of PMU " KMSG_COMPONENT " /sysfs failed\n"); - return rc; - } - - /* Setup s390dbf facility */ - paiext_dbg = debug_register(KMSG_COMPONENT, 2, 256, 128); - if (!paiext_dbg) { - pr_err("Registration of s390dbf " KMSG_COMPONENT " failed\n"); - rc = -ENOMEM; - goto out_init; - } - debug_register_view(paiext_dbg, &debug_sprintf_view); - - rc = perf_pmu_register(&paiext, KMSG_COMPONENT, -1); - if (rc) { - pr_err("Registration of " KMSG_COMPONENT " PMU failed with " - "rc=%i\n", rc); - goto out_pmu; - } - - return 0; - -out_pmu: - debug_unregister_view(paiext_dbg, &debug_sprintf_view); - debug_unregister(paiext_dbg); -out_init: - attr_event_free(paiext_events_group.attrs, - ARRAY_SIZE(paiext_ctrnames) + 1); - return rc; -} - -device_initcall(paiext_init); From 492578d3a2bce24b73f24728bc244add0bdf3fee Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Wed, 5 Nov 2025 15:39:02 +0100 Subject: [PATCH 61/92] s390/pai: Rename perf_pai_crypto.c to perf_pai.c Rename perf_pai_crypto.c to perf_pai.c. The new perf_pai.c contains both PAI device drivers: - pai_crypto for PAI crypto counter set - pai_ext for PAI NNPA counter set The rename reflects this common driver supporting both PMUs. Signed-off-by: Thomas Richter Reviewed-by: Jan Polensky Signed-off-by: Heiko Carstens --- arch/s390/kernel/Makefile | 2 +- arch/s390/kernel/{perf_pai_crypto.c => perf_pai.c} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename arch/s390/kernel/{perf_pai_crypto.c => perf_pai.c} (100%) diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index 558f7c5bfe32..c5791179b4b0 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile @@ -79,7 +79,7 @@ obj-$(CONFIG_IMA_SECURE_AND_OR_TRUSTED_BOOT) += ima_arch.o obj-$(CONFIG_PERF_EVENTS) += perf_event.o obj-$(CONFIG_PERF_EVENTS) += perf_cpum_cf.o perf_cpum_sf.o obj-$(CONFIG_PERF_EVENTS) += perf_cpum_cf_events.o perf_regs.o -obj-$(CONFIG_PERF_EVENTS) += perf_pai_crypto.o +obj-$(CONFIG_PERF_EVENTS) += perf_pai.o obj-$(CONFIG_TRACEPOINTS) += trace.o diff --git a/arch/s390/kernel/perf_pai_crypto.c b/arch/s390/kernel/perf_pai.c similarity index 100% rename from arch/s390/kernel/perf_pai_crypto.c rename to arch/s390/kernel/perf_pai.c From 02310adcc621ca59d09263074de8fe44b30abbe8 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 3 Nov 2025 11:54:20 +0100 Subject: [PATCH 62/92] s390/mm: Remove unused flush_tlb() flush_tlb() exists for historic reasons and was never used. Remove it. Reviewed-by: Alexander Gordeev Signed-off-by: Heiko Carstens --- arch/s390/include/asm/tlbflush.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/s390/include/asm/tlbflush.h b/arch/s390/include/asm/tlbflush.h index be8ca0d854d3..163ccbbe8c47 100644 --- a/arch/s390/include/asm/tlbflush.h +++ b/arch/s390/include/asm/tlbflush.h @@ -83,7 +83,6 @@ static inline void __tlb_flush_mm_lazy(struct mm_struct * mm) /* * TLB flushing: - * flush_tlb() - flushes the current mm struct TLBs * flush_tlb_all() - flushes all processes TLBs * flush_tlb_mm(mm) - flushes the specified mm context TLB's * flush_tlb_page(vma, vmaddr) - flushes one page @@ -99,7 +98,6 @@ static inline void __tlb_flush_mm_lazy(struct mm_struct * mm) * only one user. At the end of the update the flush_tlb_mm and * flush_tlb_range functions need to do the flush. */ -#define flush_tlb() do { } while (0) #define flush_tlb_all() do { } while (0) #define flush_tlb_page(vma, addr) do { } while (0) From 76502abca219fc8579353458a12744587b7a281f Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 3 Nov 2025 16:25:32 +0100 Subject: [PATCH 63/92] s390/mm: Change comment and die() message if teid.b61 is zero The comments in do_protection() give the impression that a TEID, where bit 61 is zero, indicates a low address protection exception. This is not necessarily true, and it depends on the type of Suppression-on-Protection facility of the machine (see Princples of Operation) what this means. Rework the comments and the die() message to reflect this. This may also help to avoid confusion. Reviewed-by: Alexander Gordeev Signed-off-by: Heiko Carstens --- arch/s390/mm/fault.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index e1ad05bfd28a..639c4f610fdd 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -368,20 +368,15 @@ void do_protection_exception(struct pt_regs *regs) if (!(regs->int_code & 0x200)) regs->psw.addr = __rewind_psw(regs->psw, regs->int_code >> 16); /* - * Check for low-address protection. This needs to be treated - * as a special case because the translation exception code - * field is not guaranteed to contain valid data in this case. + * If bit 61 if the TEID is not set, the remainder of the + * TEID is unpredictable. Special handling is required. */ if (unlikely(!teid.b61)) { if (user_mode(regs)) { - /* Low-address protection in user mode: cannot happen */ dump_fault_info(regs); - die(regs, "Low-address protection"); + die(regs, "Unexpected TEID"); } - /* - * Low-address protection in kernel mode means - * NULL pointer write access in kernel mode. - */ + /* Assume low-address protection in kernel mode. */ return handle_fault_error_nolock(regs, 0); } if (unlikely(cpu_has_nx() && teid.b56)) { From b60d126c8ea3444d8c1f29538542d5c03d219e3e Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 3 Nov 2025 16:25:33 +0100 Subject: [PATCH 64/92] s390/mm: Let dump_fault_info() print additional information Let dump_fault_info() print additional information to make debugging easier: Print "FSI" if the access-exception-fetch/store-indication facility is installed. If it is installed the TEID may also indicate if an exception happened because of a fetch or a store operation. Print "SOP", "ESOP-1", or "ESOP-2" depending on the type of the installed Suppression-on-Protection facility. This also gives additional information about the validity and meaning of the TEID bits. The output is changed from something like: Failing address: 0000000000000000 TEID: 0000000000000803 to Failing address: 0000000000000000 TEID: 0000000000000803 ESOP-2 FSI Reviewed-by: Alexander Gordeev Signed-off-by: Heiko Carstens --- arch/s390/mm/fault.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 639c4f610fdd..20804f1f781a 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -133,8 +133,17 @@ static void dump_fault_info(struct pt_regs *regs) union teid teid = { .val = regs->int_parm_long }; unsigned long asce; - pr_alert("Failing address: %016lx TEID: %016lx\n", + pr_alert("Failing address: %016lx TEID: %016lx", get_fault_address(regs), teid.val); + if (test_facility(131)) + pr_cont(" ESOP-2"); + else if (machine_has_esop()) + pr_cont(" ESOP-1"); + else + pr_cont(" SOP"); + if (test_facility(75)) + pr_cont(" FSI"); + pr_cont("\n"); pr_alert("Fault in "); switch (teid.as) { case PSW_BITS_AS_HOME: From d17901e8e8ddef130222c5e087854811d9fdaff4 Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Thu, 6 Nov 2025 14:23:33 +0100 Subject: [PATCH 65/92] s390/pai: Calculate size of reserved PAI extension control block area The PAI extension 1 control block area is 512 bytes in total. It currently contains three address pointer which refer to counter memory blocks followed by a reserved area. Calculate the reserved area instead of hardcoding its size. This makes the code more readable and maintainable. No functional chance. Signed-off-by: Thomas Richter Suggested-by: Jan Polensky Reviewed-by: Jan Polensky Signed-off-by: Heiko Carstens --- arch/s390/kernel/perf_pai.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/kernel/perf_pai.c b/arch/s390/kernel/perf_pai.c index 1fac41a0aa09..c79864628582 100644 --- a/arch/s390/kernel/perf_pai.c +++ b/arch/s390/kernel/perf_pai.c @@ -48,7 +48,7 @@ struct paiext_cb { /* PAI extension 1 control block */ u64 header; /* Not used */ u64 reserved1; u64 acc; /* Addr to analytics counter control block */ - u8 reserved2[488]; + u8 reserved2[PAIE1_CTRBLOCK_SZ - 3 * sizeof(u64)]; } __packed; struct pai_map { From 14e4e4175b64dd9216b522f6ece8af6997d063b2 Mon Sep 17 00:00:00 2001 From: Aleksei Nikiforov Date: Fri, 7 Nov 2025 16:59:16 +0100 Subject: [PATCH 66/92] s390/fpu: Fix false-positive kmsan report in fpu_vstl() A false-positive kmsan report is detected when running ping command. An inline assembly instruction 'vstl' can write varied amount of bytes depending on value of 'index' argument. If 'index' > 0, 'vstl' writes at least 2 bytes. clang generates kmsan write helper call depending on inline assembly constraints. Constraints are evaluated compile-time, but value of 'index' argument is known only at runtime. clang currently generates call to __msan_instrument_asm_store with 1 byte as size. Manually call kmsan function to indicate correct amount of bytes written and fix false-positive report. This change fixes following kmsan reports: [ 36.563119] ===================================================== [ 36.563594] BUG: KMSAN: uninit-value in virtqueue_add+0x35c6/0x7c70 [ 36.563852] virtqueue_add+0x35c6/0x7c70 [ 36.564016] virtqueue_add_outbuf+0xa0/0xb0 [ 36.564266] start_xmit+0x288c/0x4a20 [ 36.564460] dev_hard_start_xmit+0x302/0x900 [ 36.564649] sch_direct_xmit+0x340/0xea0 [ 36.564894] __dev_queue_xmit+0x2e94/0x59b0 [ 36.565058] neigh_resolve_output+0x936/0xb40 [ 36.565278] __neigh_update+0x2f66/0x3a60 [ 36.565499] neigh_update+0x52/0x60 [ 36.565683] arp_process+0x1588/0x2de0 [ 36.565916] NF_HOOK+0x1da/0x240 [ 36.566087] arp_rcv+0x3e4/0x6e0 [ 36.566306] __netif_receive_skb_list_core+0x1374/0x15a0 [ 36.566527] netif_receive_skb_list_internal+0x1116/0x17d0 [ 36.566710] napi_complete_done+0x376/0x740 [ 36.566918] virtnet_poll+0x1bae/0x2910 [ 36.567130] __napi_poll+0xf4/0x830 [ 36.567294] net_rx_action+0x97c/0x1ed0 [ 36.567556] handle_softirqs+0x306/0xe10 [ 36.567731] irq_exit_rcu+0x14c/0x2e0 [ 36.567910] do_io_irq+0xd4/0x120 [ 36.568139] io_int_handler+0xc2/0xe8 [ 36.568299] arch_cpu_idle+0xb0/0xc0 [ 36.568540] arch_cpu_idle+0x76/0xc0 [ 36.568726] default_idle_call+0x40/0x70 [ 36.568953] do_idle+0x1d6/0x390 [ 36.569486] cpu_startup_entry+0x9a/0xb0 [ 36.569745] rest_init+0x1ea/0x290 [ 36.570029] start_kernel+0x95e/0xb90 [ 36.570348] startup_continue+0x2e/0x40 [ 36.570703] [ 36.570798] Uninit was created at: [ 36.571002] kmem_cache_alloc_node_noprof+0x9e8/0x10e0 [ 36.571261] kmalloc_reserve+0x12a/0x470 [ 36.571553] __alloc_skb+0x310/0x860 [ 36.571844] __ip_append_data+0x483e/0x6a30 [ 36.572170] ip_append_data+0x11c/0x1e0 [ 36.572477] raw_sendmsg+0x1c8c/0x2180 [ 36.572818] inet_sendmsg+0xe6/0x190 [ 36.573142] __sys_sendto+0x55e/0x8e0 [ 36.573392] __s390x_sys_socketcall+0x19ae/0x2ba0 [ 36.573571] __do_syscall+0x12e/0x240 [ 36.573823] system_call+0x6e/0x90 [ 36.573976] [ 36.574017] Byte 35 of 98 is uninitialized [ 36.574082] Memory access of size 98 starts at 0000000007aa0012 [ 36.574218] [ 36.574325] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Tainted: G B N 6.17.0-dirty #16 NONE [ 36.574541] Tainted: [B]=BAD_PAGE, [N]=TEST [ 36.574617] Hardware name: IBM 3931 A01 703 (KVM/Linux) [ 36.574755] ===================================================== [ 63.532541] ===================================================== [ 63.533639] BUG: KMSAN: uninit-value in virtqueue_add+0x35c6/0x7c70 [ 63.533989] virtqueue_add+0x35c6/0x7c70 [ 63.534940] virtqueue_add_outbuf+0xa0/0xb0 [ 63.535861] start_xmit+0x288c/0x4a20 [ 63.536708] dev_hard_start_xmit+0x302/0x900 [ 63.537020] sch_direct_xmit+0x340/0xea0 [ 63.537997] __dev_queue_xmit+0x2e94/0x59b0 [ 63.538819] neigh_resolve_output+0x936/0xb40 [ 63.539793] ip_finish_output2+0x1ee2/0x2200 [ 63.540784] __ip_finish_output+0x272/0x7a0 [ 63.541765] ip_finish_output+0x4e/0x5e0 [ 63.542791] ip_output+0x166/0x410 [ 63.543771] ip_push_pending_frames+0x1a2/0x470 [ 63.544753] raw_sendmsg+0x1f06/0x2180 [ 63.545033] inet_sendmsg+0xe6/0x190 [ 63.546006] __sys_sendto+0x55e/0x8e0 [ 63.546859] __s390x_sys_socketcall+0x19ae/0x2ba0 [ 63.547730] __do_syscall+0x12e/0x240 [ 63.548019] system_call+0x6e/0x90 [ 63.548989] [ 63.549779] Uninit was created at: [ 63.550691] kmem_cache_alloc_node_noprof+0x9e8/0x10e0 [ 63.550975] kmalloc_reserve+0x12a/0x470 [ 63.551969] __alloc_skb+0x310/0x860 [ 63.552949] __ip_append_data+0x483e/0x6a30 [ 63.553902] ip_append_data+0x11c/0x1e0 [ 63.554912] raw_sendmsg+0x1c8c/0x2180 [ 63.556719] inet_sendmsg+0xe6/0x190 [ 63.557534] __sys_sendto+0x55e/0x8e0 [ 63.557875] __s390x_sys_socketcall+0x19ae/0x2ba0 [ 63.558869] __do_syscall+0x12e/0x240 [ 63.559832] system_call+0x6e/0x90 [ 63.560780] [ 63.560972] Byte 35 of 98 is uninitialized [ 63.561741] Memory access of size 98 starts at 0000000005704312 [ 63.561950] [ 63.562824] CPU: 3 UID: 0 PID: 192 Comm: ping Tainted: G B N 6.17.0-dirty #16 NONE [ 63.563868] Tainted: [B]=BAD_PAGE, [N]=TEST [ 63.564751] Hardware name: IBM 3931 A01 703 (KVM/Linux) [ 63.564986] ===================================================== Fixes: dcd3e1de9d17 ("s390/checksum: provide csum_partial_copy_nocheck()") Signed-off-by: Aleksei Nikiforov Signed-off-by: Heiko Carstens --- arch/s390/include/asm/fpu-insn.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/s390/include/asm/fpu-insn.h b/arch/s390/include/asm/fpu-insn.h index e99f8bca8e08..96727f3bd0dc 100644 --- a/arch/s390/include/asm/fpu-insn.h +++ b/arch/s390/include/asm/fpu-insn.h @@ -12,6 +12,7 @@ #ifndef __ASSEMBLER__ #include +#include #include asm(".include \"asm/fpu-insn-asm.h\"\n"); @@ -393,6 +394,7 @@ static __always_inline void fpu_vstl(u8 v1, u32 index, const void *vxr) : [vxr] "=Q" (*(u8 *)vxr) : [index] "d" (index), [v1] "I" (v1) : "memory"); + kmsan_unpoison_memory(vxr, size); } #else /* CONFIG_CC_HAS_ASM_AOR_FORMAT_FLAGS */ @@ -409,6 +411,7 @@ static __always_inline void fpu_vstl(u8 v1, u32 index, const void *vxr) : [vxr] "=R" (*(u8 *)vxr) : [index] "d" (index), [v1] "I" (v1) : "memory", "1"); + kmsan_unpoison_memory(vxr, size); } #endif /* CONFIG_CC_HAS_ASM_AOR_FORMAT_FLAGS */ From 37450e0994f717d8f621b1dfc1c713f9c66cf59c Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 4 Nov 2025 11:48:55 +0100 Subject: [PATCH 67/92] s390/processor: Add __forward_psw() helper Similar to __rewind_psw() add the counter part __forward_psw(). This helps to make code more readable if a PSW address has to be forwarded, since it is more natural to write addr = __forward_psw(psw, ilen); instead of addr = __rewind_psw(psw, -ilen); This renames also the ilc parameter of __rewind_psw() to ilen, since the parameter reflects an instruction length, and not an instruction length code. Also change the type of ilen from unsigned long to long so it reflects that lengths can be negative or positive. Reviewed-by: Alexander Gordeev Signed-off-by: Heiko Carstens --- arch/s390/include/asm/processor.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index 93e1034485d7..ead1ebc9c61e 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h @@ -379,14 +379,19 @@ static inline void local_mcck_enable(void) /* * Rewind PSW instruction address by specified number of bytes. */ -static inline unsigned long __rewind_psw(psw_t psw, unsigned long ilc) +static inline unsigned long __rewind_psw(psw_t psw, long ilen) { unsigned long mask; mask = (psw.mask & PSW_MASK_EA) ? -1UL : (psw.mask & PSW_MASK_BA) ? (1UL << 31) - 1 : (1UL << 24) - 1; - return (psw.addr - ilc) & mask; + return (psw.addr - ilen) & mask; +} + +static inline unsigned long __forward_psw(psw_t psw, long ilen) +{ + return __rewind_psw(psw, -ilen); } /* From a603a0039965ee66d7e521bacf8161d3109bfd75 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 4 Nov 2025 11:48:56 +0100 Subject: [PATCH 68/92] s390/uprobes: Use __forward_psw() instead of private implementation With adjust_psw_addr() the uprobes code contains more or less a private __forward_psw() implementation. Switch it to use __forward_psw(), and remove adjust_psw_addr(). Reviewed-by: Alexander Gordeev Signed-off-by: Heiko Carstens --- arch/s390/kernel/uprobes.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/arch/s390/kernel/uprobes.c b/arch/s390/kernel/uprobes.c index 5b0633ea8d93..a91b4fd01bf4 100644 --- a/arch/s390/kernel/uprobes.c +++ b/arch/s390/kernel/uprobes.c @@ -161,11 +161,6 @@ bool arch_uretprobe_is_alive(struct return_instance *ret, enum rp_check ctx, /* Instruction Emulation */ -static void adjust_psw_addr(psw_t *psw, unsigned long len) -{ - psw->addr = __rewind_psw(*psw, -len); -} - #define EMU_ILLEGAL_OP 1 #define EMU_SPECIFICATION 2 #define EMU_ADDRESSING 3 @@ -353,7 +348,7 @@ static void handle_insn_ril(struct arch_uprobe *auprobe, struct pt_regs *regs) } break; } - adjust_psw_addr(®s->psw, ilen); + regs->psw.addr = __forward_psw(regs->psw, ilen); switch (rc) { case EMU_ILLEGAL_OP: regs->int_code = ilen << 16 | 0x0001; From 52a1f73d1733e6d5bf2cbfa93296207e542cdea7 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 4 Nov 2025 11:48:57 +0100 Subject: [PATCH 69/92] s390/fault: Print unmodified PSW address on protection exception In case of a kernel crash caused by a protection exception, print the unmodified PSW address as reported by the CPU. The protection exception handler modifies the PSW address in order to keep fault handling easy, however that leads to misleading call traces. Therefore restore the original PSW address before printing it. Before this change the output in case of a protection exception looks like this: Oops: 0004 ilc:2 [#1]SMP Krnl PSW : 0704c00180000000 000003ffe0b40d78 (sysrq_handle_crash+0x28/0x40) R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:3 CC:0 PM:0 RI:0 EA:3 ... Krnl Code: 000003ffe0b40d66: e3e0f0980024 stg %r14,152(%r15) 000003ffe0b40d6c: c010fffffff2 larl %r1,000003ffe0b40d50 #000003ffe0b40d72: c0200046b6bc larl %r2,000003ffe1417aea >000003ffe0b40d78: 92021000 mvi 0(%r1),2 000003ffe0b40d7c: c0e5ffae03d6 brasl %r14,000003ffe0101528 With this change it looks like this: Oops: 0004 ilc:2 [#1]SMP Krnl PSW : 0704c00180000000 000003ffe0b40dfc (sysrq_handle_crash+0x2c/0x40) R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:3 CC:0 PM:0 RI:0 EA:3 ... Krnl Code: 000003ffe0b40dec: c010fffffff2 larl %r1,000003ffe0b40dd0 000003ffe0b40df2: c0200046b67c larl %r2,000003ffe1417aea *000003ffe0b40df8: 92021000 mvi 0(%r1),2 >000003ffe0b40dfc: c0e5ffae03b6 brasl %r14,000003ffe0101568 000003ffe0b40e02: 0707 bcr 0,%r7 Note that with this change the PSW address points to the instruction behind the instruction which caused the exception like it is expected for protection exceptions. This also replaces the '#' marker in the disassembly with '*', which allows to distinguish between new and old behavior. Reviewed-by: Alexander Gordeev Signed-off-by: Heiko Carstens --- arch/s390/include/asm/ptrace.h | 2 ++ arch/s390/kernel/dis.c | 17 ++++++++++------- arch/s390/kernel/dumpstack.c | 8 ++++++-- arch/s390/mm/fault.c | 4 +++- 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h index 8fae167c1bd6..dd87466ba0ea 100644 --- a/arch/s390/include/asm/ptrace.h +++ b/arch/s390/include/asm/ptrace.h @@ -14,11 +14,13 @@ #include #define PIF_SYSCALL 0 /* inside a system call */ +#define PIF_PSW_ADDR_ADJUSTED 1 /* psw address has been adjusted */ #define PIF_SYSCALL_RET_SET 2 /* return value was set via ptrace */ #define PIF_GUEST_FAULT 3 /* indicates program check in sie64a */ #define PIF_FTRACE_FULL_REGS 4 /* all register contents valid (ftrace) */ #define _PIF_SYSCALL BIT(PIF_SYSCALL) +#define _PIF_ADDR_PSW_ADJUSTED BIT(PIF_PSW_ADDR_ADJUSTED) #define _PIF_SYSCALL_RET_SET BIT(PIF_SYSCALL_RET_SET) #define _PIF_GUEST_FAULT BIT(PIF_GUEST_FAULT) #define _PIF_FTRACE_FULL_REGS BIT(PIF_FTRACE_FULL_REGS) diff --git a/arch/s390/kernel/dis.c b/arch/s390/kernel/dis.c index 63a1d4226ff8..1cec93895b3a 100644 --- a/arch/s390/kernel/dis.c +++ b/arch/s390/kernel/dis.c @@ -503,24 +503,27 @@ static int copy_from_regs(struct pt_regs *regs, void *dst, void *src, int len) void show_code(struct pt_regs *regs) { char *mode = user_mode(regs) ? "User" : "Krnl"; + unsigned long addr, pswaddr; unsigned char code[64]; char buffer[128], *ptr; - unsigned long addr; int start, end, opsize, hops, i; + pswaddr = regs->psw.addr; + if (test_pt_regs_flag(regs, PIF_PSW_ADDR_ADJUSTED)) + pswaddr = __forward_psw(regs->psw, regs->int_code >> 16); /* Get a snapshot of the 64 bytes surrounding the fault address. */ - for (start = 32; start && regs->psw.addr >= 34 - start; start -= 2) { - addr = regs->psw.addr - 34 + start; + for (start = 32; start && pswaddr >= 34 - start; start -= 2) { + addr = pswaddr - 34 + start; if (copy_from_regs(regs, code + start - 2, (void *)addr, 2)) break; } for (end = 32; end < 64; end += 2) { - addr = regs->psw.addr + end - 32; + addr = pswaddr + end - 32; if (copy_from_regs(regs, code + end, (void *)addr, 2)) break; } /* Code snapshot usable ? */ - if ((regs->psw.addr & 1) || start >= end) { + if ((pswaddr & 1) || start >= end) { printk("%s Code: Bad PSW.\n", mode); return; } @@ -543,12 +546,12 @@ void show_code(struct pt_regs *regs) while (start < end && hops < 8) { opsize = insn_length(code[start]); if (start + opsize == 32) - *ptr++ = '#'; + *ptr++ = '*'; else if (start == 32) *ptr++ = '>'; else *ptr++ = ' '; - addr = regs->psw.addr + start - 32; + addr = pswaddr + start - 32; ptr += sprintf(ptr, "%px: ", (void *)addr); if (start + opsize >= end) break; diff --git a/arch/s390/kernel/dumpstack.c b/arch/s390/kernel/dumpstack.c index dd410962ecbe..f9d52e05e01e 100644 --- a/arch/s390/kernel/dumpstack.c +++ b/arch/s390/kernel/dumpstack.c @@ -155,12 +155,16 @@ static void show_last_breaking_event(struct pt_regs *regs) void show_registers(struct pt_regs *regs) { struct psw_bits *psw = &psw_bits(regs->psw); + unsigned long pswaddr; char *mode; + pswaddr = regs->psw.addr; + if (test_pt_regs_flag(regs, PIF_PSW_ADDR_ADJUSTED)) + pswaddr = __forward_psw(regs->psw, regs->int_code >> 16); mode = user_mode(regs) ? "User" : "Krnl"; - printk("%s PSW : %px %px", mode, (void *)regs->psw.mask, (void *)regs->psw.addr); + printk("%s PSW : %px %px", mode, (void *)regs->psw.mask, (void *)pswaddr); if (!user_mode(regs)) - pr_cont(" (%pSR)", (void *)regs->psw.addr); + pr_cont(" (%pSR)", (void *)pswaddr); pr_cont("\n"); printk(" R:%x T:%x IO:%x EX:%x Key:%x M:%x W:%x " "P:%x AS:%x CC:%x PM:%x", psw->per, psw->dat, psw->io, psw->ext, diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 20804f1f781a..a8c9aeee632b 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -374,8 +374,10 @@ void do_protection_exception(struct pt_regs *regs) * The exception to this rule are aborted transactions, for these * the PSW already points to the correct location. */ - if (!(regs->int_code & 0x200)) + if (!(regs->int_code & 0x200)) { regs->psw.addr = __rewind_psw(regs->psw, regs->int_code >> 16); + set_pt_regs_flag(regs, PIF_PSW_ADDR_ADJUSTED); + } /* * If bit 61 if the TEID is not set, the remainder of the * TEID is unpredictable. Special handling is required. From 8c633c78c23a85a9efbabbe47d815ebdd7739905 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 10 Nov 2025 19:54:33 +0100 Subject: [PATCH 70/92] s390/ptrace: Rename psw_t32 to psw32_t Use a standard "_t" suffix for psw_t32 and rename it to psw32_t. Reviewed-by: Arnd Bergmann Signed-off-by: Heiko Carstens --- arch/s390/boot/ipl_data.c | 2 +- arch/s390/include/asm/ptrace.h | 2 +- arch/s390/kernel/compat_linux.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/s390/boot/ipl_data.c b/arch/s390/boot/ipl_data.c index c4130a80b058..7957cc6554e7 100644 --- a/arch/s390/boot/ipl_data.c +++ b/arch/s390/boot/ipl_data.c @@ -12,7 +12,7 @@ #define PSW_MASK_DISABLED (PSW_MASK_WAIT | PSW_MASK_EA | PSW_MASK_BA) struct ipl_lowcore { - psw_t32 ipl_psw; /* 0x0000 */ + psw32_t ipl_psw; /* 0x0000 */ struct ccw0 ccwpgm[2]; /* 0x0008 */ u8 fill[56]; /* 0x0018 */ struct ccw0 ccwpgmcc[20]; /* 0x0050 */ diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h index dd87466ba0ea..962cf042c66d 100644 --- a/arch/s390/include/asm/ptrace.h +++ b/arch/s390/include/asm/ptrace.h @@ -102,7 +102,7 @@ enum { typedef struct { unsigned int mask; unsigned int addr; -} psw_t32 __aligned(8); +} psw32_t __aligned(8); #define PGM_INT_CODE_MASK 0x7f #define PGM_INT_CODE_PER 0x80 diff --git a/arch/s390/kernel/compat_linux.h b/arch/s390/kernel/compat_linux.h index ef23739b277c..133f22b5deeb 100644 --- a/arch/s390/kernel/compat_linux.h +++ b/arch/s390/kernel/compat_linux.h @@ -33,7 +33,7 @@ typedef struct { } _s390_fp_regs32; typedef struct { - psw_t32 psw; + psw32_t psw; __u32 gprs[__NUM_GPRS]; __u32 acrs[__NUM_ACRS]; } _s390_regs_common32; From b2da5f6400b458659c4d3fc90d27c2da42435169 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 10 Nov 2025 19:54:34 +0100 Subject: [PATCH 71/92] s390/kvm: Use psw32_t instead of psw_compat_t kvm_s390_handle_lpsw() make use of the psw_compat_t type even though the code has nothing to do with CONFIG_COMPAT, for which the type is supposed to be used. Use psw32_t instead. Reviewed-by: Arnd Bergmann Signed-off-by: Heiko Carstens --- arch/s390/kvm/priv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c index 9a71b6e00948..0b14d894f38a 100644 --- a/arch/s390/kvm/priv.c +++ b/arch/s390/kvm/priv.c @@ -754,7 +754,7 @@ int is_valid_psw(psw_t *psw) int kvm_s390_handle_lpsw(struct kvm_vcpu *vcpu) { psw_t *gpsw = &vcpu->arch.sie_block->gpsw; - psw_compat_t new_psw; + psw32_t new_psw; u64 addr; int rc; u8 ar; From 7afb095df3e3c2f0d2f27d2d27bbe574ca9479f0 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 10 Nov 2025 19:54:35 +0100 Subject: [PATCH 72/92] s390/syscalls: Add pt_regs parameter to SYSCALL_DEFINE0() syscall wrapper All system call wrappers should match the sys_call_ptr_t type. This is not the case for system calls without parameters. Add the missing pt_regs parameter there too. Note: this is currently not a problem, since the parameter is unused. However it prevents to create a correctly typed system call table in C. With the current assembler implementation this works because of missing type checking. Reviewed-by: Arnd Bergmann Signed-off-by: Heiko Carstens --- arch/s390/include/asm/syscall_wrapper.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/s390/include/asm/syscall_wrapper.h b/arch/s390/include/asm/syscall_wrapper.h index 35c1d1b860d8..bf1ff5e9242d 100644 --- a/arch/s390/include/asm/syscall_wrapper.h +++ b/arch/s390/include/asm/syscall_wrapper.h @@ -38,22 +38,22 @@ * named __s390x_sys_*() */ #define COMPAT_SYSCALL_DEFINE0(sname) \ - long __s390_compat_sys_##sname(void); \ + long __s390_compat_sys_##sname(struct pt_regs *__unused); \ ALLOW_ERROR_INJECTION(__s390_compat_sys_##sname, ERRNO); \ - long __s390_compat_sys_##sname(void) + long __s390_compat_sys_##sname(struct pt_regs *__unused) #define SYSCALL_DEFINE0(sname) \ SYSCALL_METADATA(_##sname, 0); \ - long __s390_sys_##sname(void); \ + long __s390_sys_##sname(struct pt_regs *__unused); \ ALLOW_ERROR_INJECTION(__s390_sys_##sname, ERRNO); \ - long __s390x_sys_##sname(void); \ + long __s390x_sys_##sname(struct pt_regs *__unused); \ ALLOW_ERROR_INJECTION(__s390x_sys_##sname, ERRNO); \ static inline long __do_sys_##sname(void); \ - long __s390_sys_##sname(void) \ + long __s390_sys_##sname(struct pt_regs *__unused) \ { \ return __do_sys_##sname(); \ } \ - long __s390x_sys_##sname(void) \ + long __s390x_sys_##sname(struct pt_regs *__unused) \ { \ return __do_sys_##sname(); \ } \ @@ -104,10 +104,10 @@ #define SYSCALL_DEFINE0(sname) \ SYSCALL_METADATA(_##sname, 0); \ - long __s390x_sys_##sname(void); \ + long __s390x_sys_##sname(struct pt_regs *__unused); \ ALLOW_ERROR_INJECTION(__s390x_sys_##sname, ERRNO); \ static inline long __do_sys_##sname(void); \ - long __s390x_sys_##sname(void) \ + long __s390x_sys_##sname(struct pt_regs *__unused) \ { \ return __do_sys_##sname(); \ } \ From 169ebcbb90829bec0429ff9f6012a0313169e45f Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 10 Nov 2025 19:54:36 +0100 Subject: [PATCH 73/92] tools: Remove s390 compat support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove s390 compat support from everything within tools, since s390 compat support will be removed from the kernel. Reviewed-by: Arnd Bergmann Acked-by: Thomas Weißschuh # tools/nolibc selftests/nolibc Reviewed-by: Thomas Weißschuh # selftests/vDSO Acked-by: Alexei Starovoitov # bpf bits Signed-off-by: Heiko Carstens --- .../arch/s390/include/uapi/asm/bitsperlong.h | 4 -- tools/include/nolibc/arch-s390.h | 5 --- tools/include/nolibc/arch.h | 2 +- tools/lib/bpf/libbpf.c | 4 -- tools/lib/bpf/usdt.c | 2 - .../testing/selftests/nolibc/Makefile.nolibc | 5 --- tools/testing/selftests/nolibc/run-tests.sh | 6 +-- tools/testing/selftests/rseq/rseq-s390.h | 39 ------------------- tools/testing/selftests/vDSO/vdso_config.h | 4 -- 9 files changed, 2 insertions(+), 69 deletions(-) diff --git a/tools/arch/s390/include/uapi/asm/bitsperlong.h b/tools/arch/s390/include/uapi/asm/bitsperlong.h index d2bb620119bf..a226a1686a53 100644 --- a/tools/arch/s390/include/uapi/asm/bitsperlong.h +++ b/tools/arch/s390/include/uapi/asm/bitsperlong.h @@ -2,11 +2,7 @@ #ifndef __ASM_S390_BITSPERLONG_H #define __ASM_S390_BITSPERLONG_H -#ifndef __s390x__ -#define __BITS_PER_LONG 32 -#else #define __BITS_PER_LONG 64 -#endif #include diff --git a/tools/include/nolibc/arch-s390.h b/tools/include/nolibc/arch-s390.h index df4c3cc713ac..0a39bee261b9 100644 --- a/tools/include/nolibc/arch-s390.h +++ b/tools/include/nolibc/arch-s390.h @@ -143,13 +143,8 @@ void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void) { __asm__ volatile ( -#ifdef __s390x__ "lgr %r2, %r15\n" /* save stack pointer to %r2, as arg1 of _start_c */ "aghi %r15, -160\n" /* allocate new stackframe */ -#else - "lr %r2, %r15\n" - "ahi %r15, -96\n" -#endif "xc 0(8,%r15), 0(%r15)\n" /* clear backchain */ "brasl %r14, _start_c\n" /* transfer to c runtime */ ); diff --git a/tools/include/nolibc/arch.h b/tools/include/nolibc/arch.h index 426c89198135..ef4743aad188 100644 --- a/tools/include/nolibc/arch.h +++ b/tools/include/nolibc/arch.h @@ -27,7 +27,7 @@ #include "arch-powerpc.h" #elif defined(__riscv) #include "arch-riscv.h" -#elif defined(__s390x__) || defined(__s390__) +#elif defined(__s390x__) #include "arch-s390.h" #elif defined(__loongarch__) #include "arch-loongarch.h" diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index dd3b2f57082d..85abc357da31 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -11325,8 +11325,6 @@ static const char *arch_specific_syscall_pfx(void) return "ia32"; #elif defined(__s390x__) return "s390x"; -#elif defined(__s390__) - return "s390"; #elif defined(__arm__) return "arm"; #elif defined(__aarch64__) @@ -12113,8 +12111,6 @@ static const char *arch_specific_lib_paths(void) return "/lib/i386-linux-gnu"; #elif defined(__s390x__) return "/lib/s390x-linux-gnu"; -#elif defined(__s390__) - return "/lib/s390-linux-gnu"; #elif defined(__arm__) && defined(__SOFTFP__) return "/lib/arm-linux-gnueabi"; #elif defined(__arm__) && !defined(__SOFTFP__) diff --git a/tools/lib/bpf/usdt.c b/tools/lib/bpf/usdt.c index c174b4086673..d1524f6f54ae 100644 --- a/tools/lib/bpf/usdt.c +++ b/tools/lib/bpf/usdt.c @@ -1376,8 +1376,6 @@ static int parse_usdt_arg(const char *arg_str, int arg_num, struct usdt_arg_spec #elif defined(__s390x__) -/* Do not support __s390__ for now, since user_pt_regs is broken with -m31. */ - static int parse_usdt_arg(const char *arg_str, int arg_num, struct usdt_arg_spec *arg, int *arg_sz) { unsigned int reg; diff --git a/tools/testing/selftests/nolibc/Makefile.nolibc b/tools/testing/selftests/nolibc/Makefile.nolibc index 330e000baeb1..9416ae952e18 100644 --- a/tools/testing/selftests/nolibc/Makefile.nolibc +++ b/tools/testing/selftests/nolibc/Makefile.nolibc @@ -87,7 +87,6 @@ IMAGE_riscv = arch/riscv/boot/Image IMAGE_riscv32 = arch/riscv/boot/Image IMAGE_riscv64 = arch/riscv/boot/Image IMAGE_s390x = arch/s390/boot/bzImage -IMAGE_s390 = arch/s390/boot/bzImage IMAGE_loongarch = arch/loongarch/boot/vmlinuz.efi IMAGE_sparc32 = arch/sparc/boot/image IMAGE_sparc64 = arch/sparc/boot/image @@ -117,7 +116,6 @@ DEFCONFIG_riscv = defconfig DEFCONFIG_riscv32 = rv32_defconfig DEFCONFIG_riscv64 = defconfig DEFCONFIG_s390x = defconfig -DEFCONFIG_s390 = defconfig compat.config DEFCONFIG_loongarch = defconfig DEFCONFIG_sparc32 = sparc32_defconfig DEFCONFIG_sparc64 = sparc64_defconfig @@ -156,7 +154,6 @@ QEMU_ARCH_riscv = riscv64 QEMU_ARCH_riscv32 = riscv32 QEMU_ARCH_riscv64 = riscv64 QEMU_ARCH_s390x = s390x -QEMU_ARCH_s390 = s390x QEMU_ARCH_loongarch = loongarch64 QEMU_ARCH_sparc32 = sparc QEMU_ARCH_sparc64 = sparc64 @@ -197,7 +194,6 @@ QEMU_ARGS_riscv = -M virt -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_T QEMU_ARGS_riscv32 = -M virt -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)" QEMU_ARGS_riscv64 = -M virt -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)" QEMU_ARGS_s390x = -M s390-ccw-virtio -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)" -QEMU_ARGS_s390 = -M s390-ccw-virtio -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)" QEMU_ARGS_loongarch = -M virt -append "console=ttyS0,115200 panic=-1 $(TEST:%=NOLIBC_TEST=%)" QEMU_ARGS_sparc32 = -M SS-5 -m 256M -append "console=ttyS0,115200 panic=-1 $(TEST:%=NOLIBC_TEST=%)" QEMU_ARGS_sparc64 = -M sun4u -append "console=ttyS0,115200 panic=-1 $(TEST:%=NOLIBC_TEST=%)" @@ -223,7 +219,6 @@ CFLAGS_ppc = -m32 -mbig-endian -mno-vsx $(call cc-option,-mmultiple) CFLAGS_ppc64 = -m64 -mbig-endian -mno-vsx $(call cc-option,-mmultiple) CFLAGS_ppc64le = -m64 -mlittle-endian -mno-vsx $(call cc-option,-mabi=elfv2) CFLAGS_s390x = -m64 -CFLAGS_s390 = -m31 CFLAGS_mips32le = -EL -mabi=32 -fPIC CFLAGS_mips32be = -EB -mabi=32 CFLAGS_mipsn32le = -EL -mabi=n32 -fPIC -march=mips64r2 diff --git a/tools/testing/selftests/nolibc/run-tests.sh b/tools/testing/selftests/nolibc/run-tests.sh index e8af1fb505cf..210abe715ed9 100755 --- a/tools/testing/selftests/nolibc/run-tests.sh +++ b/tools/testing/selftests/nolibc/run-tests.sh @@ -23,7 +23,7 @@ all_archs=( mips32le mips32be mipsn32le mipsn32be mips64le mips64be ppc ppc64 ppc64le riscv32 riscv64 - s390x s390 + s390x loongarch sparc32 sparc64 m68k @@ -185,10 +185,6 @@ test_arch() { exit 1 esac printf '%-15s' "$arch:" - if [ "$arch" = "s390" ] && ([ "$llvm" = "1" ] || [ "$test_mode" = "user" ]); then - echo "Unsupported configuration" - return - fi if [ "$arch" = "m68k" -o "$arch" = "sh4" ] && [ "$llvm" = "1" ]; then echo "Unsupported configuration" return diff --git a/tools/testing/selftests/rseq/rseq-s390.h b/tools/testing/selftests/rseq/rseq-s390.h index 33baaa9f9997..e7b858cd3736 100644 --- a/tools/testing/selftests/rseq/rseq-s390.h +++ b/tools/testing/selftests/rseq/rseq-s390.h @@ -28,8 +28,6 @@ do { \ RSEQ_WRITE_ONCE(*(p), v); \ } while (0) -#ifdef __s390x__ - #define LONG_L "lg" #define LONG_S "stg" #define LONG_LT_R "ltgr" @@ -63,43 +61,6 @@ do { \ ".quad " __rseq_str(start_ip) ", " __rseq_str(exit_ip) "\n\t" \ ".popsection\n\t" -#elif __s390__ - -#define __RSEQ_ASM_DEFINE_TABLE(label, version, flags, \ - start_ip, post_commit_offset, abort_ip) \ - ".pushsection __rseq_cs, \"aw\"\n\t" \ - ".balign 32\n\t" \ - __rseq_str(label) ":\n\t" \ - ".long " __rseq_str(version) ", " __rseq_str(flags) "\n\t" \ - ".long 0x0, " __rseq_str(start_ip) ", 0x0, " __rseq_str(post_commit_offset) ", 0x0, " __rseq_str(abort_ip) "\n\t" \ - ".popsection\n\t" \ - ".pushsection __rseq_cs_ptr_array, \"aw\"\n\t" \ - ".long 0x0, " __rseq_str(label) "b\n\t" \ - ".popsection\n\t" - -/* - * Exit points of a rseq critical section consist of all instructions outside - * of the critical section where a critical section can either branch to or - * reach through the normal course of its execution. The abort IP and the - * post-commit IP are already part of the __rseq_cs section and should not be - * explicitly defined as additional exit points. Knowing all exit points is - * useful to assist debuggers stepping over the critical section. - */ -#define RSEQ_ASM_DEFINE_EXIT_POINT(start_ip, exit_ip) \ - ".pushsection __rseq_exit_point_array, \"aw\"\n\t" \ - ".long 0x0, " __rseq_str(start_ip) ", 0x0, " __rseq_str(exit_ip) "\n\t" \ - ".popsection\n\t" - -#define LONG_L "l" -#define LONG_S "st" -#define LONG_LT_R "ltr" -#define LONG_CMP "c" -#define LONG_CMP_R "cr" -#define LONG_ADDI "ahi" -#define LONG_ADD_R "ar" - -#endif - #define RSEQ_ASM_DEFINE_TABLE(label, start_ip, post_commit_ip, abort_ip) \ __RSEQ_ASM_DEFINE_TABLE(label, 0x0, 0x0, start_ip, \ (post_commit_ip - start_ip), abort_ip) diff --git a/tools/testing/selftests/vDSO/vdso_config.h b/tools/testing/selftests/vDSO/vdso_config.h index 5fdd0f362337..50c261005111 100644 --- a/tools/testing/selftests/vDSO/vdso_config.h +++ b/tools/testing/selftests/vDSO/vdso_config.h @@ -25,10 +25,6 @@ #define VDSO_VERSION 1 #define VDSO_NAMES 0 #define VDSO_32BIT 1 -#elif defined (__s390__) && !defined(__s390x__) -#define VDSO_VERSION 2 -#define VDSO_NAMES 0 -#define VDSO_32BIT 1 #elif defined (__s390x__) #define VDSO_VERSION 2 #define VDSO_NAMES 0 From 8e0b986c59c67e08ada646249f834655a9e6da16 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 10 Nov 2025 19:54:37 +0100 Subject: [PATCH 74/92] s390: Remove compat support There shouldn't be any 31 bit code around anymore that matters. Remove the compat layer support required to run 31 bit code. Reason for removal is code simplification and reduced test effort. Note that this comes without any deprecation warnings added to config options, or kernel messages, since most likely those would be ignored anyway. If it turns out there is still a reason to keep the compat layer this can be reverted at any time in the future. Reviewed-by: Arnd Bergmann Signed-off-by: Heiko Carstens --- arch/s390/Kconfig | 16 - arch/s390/Makefile | 3 - arch/s390/boot/ipl_data.c | 1 - arch/s390/configs/compat.config | 3 - arch/s390/hypfs/hypfs_sprp.c | 6 +- arch/s390/include/asm/compat.h | 140 ------ arch/s390/include/asm/elf.h | 46 +- arch/s390/include/asm/ftrace.h | 19 +- arch/s390/include/asm/processor.h | 12 +- arch/s390/include/asm/seccomp.h | 5 - arch/s390/include/asm/syscall.h | 19 +- arch/s390/include/asm/syscall_wrapper.h | 91 ---- arch/s390/include/asm/thread_info.h | 2 - arch/s390/include/asm/unistd.h | 5 - arch/s390/include/asm/vdso-symbols.h | 8 - arch/s390/kernel/Makefile | 4 - arch/s390/kernel/audit.c | 16 - arch/s390/kernel/audit.h | 16 - arch/s390/kernel/compat_audit.c | 48 -- arch/s390/kernel/compat_linux.c | 289 ----------- arch/s390/kernel/compat_linux.h | 101 ---- arch/s390/kernel/compat_ptrace.h | 64 --- arch/s390/kernel/compat_signal.c | 420 ---------------- arch/s390/kernel/entry.S | 9 - arch/s390/kernel/perf_cpum_cf.c | 1 - arch/s390/kernel/perf_event.c | 1 - arch/s390/kernel/perf_regs.c | 3 - arch/s390/kernel/process.c | 9 +- arch/s390/kernel/ptrace.c | 524 -------------------- arch/s390/kernel/setup.c | 1 - arch/s390/kernel/signal.c | 23 +- arch/s390/kernel/stacktrace.c | 3 - arch/s390/kernel/uprobes.c | 6 +- arch/s390/kernel/vdso.c | 26 +- arch/s390/kernel/vdso32/.gitignore | 2 - arch/s390/kernel/vdso32/Makefile | 64 --- arch/s390/kernel/vdso32/gen_vdso_offsets.sh | 15 - arch/s390/kernel/vdso32/note.S | 13 - arch/s390/kernel/vdso32/vdso32.lds.S | 140 ------ arch/s390/kernel/vdso32/vdso32_wrapper.S | 15 - arch/s390/kernel/vdso32/vdso_user_wrapper.S | 22 - arch/s390/mm/fault.c | 1 - arch/s390/mm/mmap.c | 1 - arch/s390/pci/pci_clp.c | 4 +- drivers/s390/block/dasd.c | 1 - drivers/s390/block/dasd_eckd.c | 11 - drivers/s390/block/dasd_ioctl.c | 6 +- drivers/s390/char/con3270.c | 19 - drivers/s390/char/fs3270.c | 7 +- drivers/s390/char/sclp_ctl.c | 12 +- drivers/s390/char/tape_char.c | 26 - drivers/s390/char/vmcp.c | 7 +- drivers/s390/cio/chsc_sch.c | 7 +- drivers/s390/crypto/zcrypt_api.c | 195 -------- drivers/s390/crypto/zcrypt_card.c | 1 - drivers/s390/crypto/zcrypt_queue.c | 1 - drivers/s390/net/qeth_core_main.c | 4 +- 57 files changed, 30 insertions(+), 2484 deletions(-) delete mode 100644 arch/s390/configs/compat.config delete mode 100644 arch/s390/include/asm/compat.h delete mode 100644 arch/s390/kernel/audit.h delete mode 100644 arch/s390/kernel/compat_audit.c delete mode 100644 arch/s390/kernel/compat_linux.c delete mode 100644 arch/s390/kernel/compat_linux.h delete mode 100644 arch/s390/kernel/compat_ptrace.h delete mode 100644 arch/s390/kernel/compat_signal.c delete mode 100644 arch/s390/kernel/vdso32/.gitignore delete mode 100644 arch/s390/kernel/vdso32/Makefile delete mode 100755 arch/s390/kernel/vdso32/gen_vdso_offsets.sh delete mode 100644 arch/s390/kernel/vdso32/note.S delete mode 100644 arch/s390/kernel/vdso32/vdso32.lds.S delete mode 100644 arch/s390/kernel/vdso32/vdso32_wrapper.S delete mode 100644 arch/s390/kernel/vdso32/vdso_user_wrapper.S diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index c4145672ca34..9914db771e45 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -505,22 +505,6 @@ config COMMAND_LINE_SIZE This allows you to specify the maximum length of the kernel command line. -config COMPAT - def_bool n - prompt "Kernel support for 31 bit emulation" - select ARCH_WANT_OLD_COMPAT_IPC - select COMPAT_OLD_SIGACTION - select HAVE_UID16 - depends on MULTIUSER - depends on !CC_IS_CLANG && !LD_IS_LLD - help - Select this option if you want to enable your system kernel to - handle system-calls from ELF binaries for 31 bit ESA. This option - (and some other stuff like libraries and such) is needed for - executing 31 bit applications. - - If unsure say N. - config SMP def_bool y diff --git a/arch/s390/Makefile b/arch/s390/Makefile index b4769241332b..f41b8c5c4e56 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile @@ -149,11 +149,8 @@ ifeq ($(KBUILD_EXTMOD),) prepare: vdso_prepare vdso_prepare: prepare0 $(Q)$(MAKE) $(build)=arch/s390/kernel/vdso64 include/generated/vdso64-offsets.h - $(if $(CONFIG_COMPAT),$(Q)$(MAKE) \ - $(build)=arch/s390/kernel/vdso32 include/generated/vdso32-offsets.h) vdso-install-y += arch/s390/kernel/vdso64/vdso64.so.dbg -vdso-install-$(CONFIG_COMPAT) += arch/s390/kernel/vdso32/vdso32.so.dbg endif diff --git a/arch/s390/boot/ipl_data.c b/arch/s390/boot/ipl_data.c index 7957cc6554e7..b0fd8a526b42 100644 --- a/arch/s390/boot/ipl_data.c +++ b/arch/s390/boot/ipl_data.c @@ -1,6 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 -#include #include #include #include diff --git a/arch/s390/configs/compat.config b/arch/s390/configs/compat.config deleted file mode 100644 index 6fd051453ae8..000000000000 --- a/arch/s390/configs/compat.config +++ /dev/null @@ -1,3 +0,0 @@ -# Help: Enable compat support -CONFIG_COMPAT=y -CONFIG_COMPAT_32BIT_TIME=y diff --git a/arch/s390/hypfs/hypfs_sprp.c b/arch/s390/hypfs/hypfs_sprp.c index a2952ed5518b..a72576221cab 100644 --- a/arch/s390/hypfs/hypfs_sprp.c +++ b/arch/s390/hypfs/hypfs_sprp.c @@ -7,7 +7,6 @@ * Author(s): Martin Schwidefsky */ -#include #include #include #include @@ -116,10 +115,7 @@ static long hypfs_sprp_ioctl(struct file *file, unsigned int cmd, if (!capable(CAP_SYS_ADMIN)) return -EACCES; - if (is_compat_task()) - argp = compat_ptr(arg); - else - argp = (void __user *) arg; + argp = (void __user *)arg; switch (cmd) { case HYPFS_DIAG304: return __hypfs_sprp_ioctl(argp); diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h deleted file mode 100644 index 3cb9d813f022..000000000000 --- a/arch/s390/include/asm/compat.h +++ /dev/null @@ -1,140 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _ASM_S390X_COMPAT_H -#define _ASM_S390X_COMPAT_H -/* - * Architecture specific compatibility types - */ -#include -#include -#include -#include -#include - -#define compat_mode_t compat_mode_t -typedef u16 compat_mode_t; - -#define __compat_uid_t __compat_uid_t -typedef u16 __compat_uid_t; -typedef u16 __compat_gid_t; - -#define compat_dev_t compat_dev_t -typedef u16 compat_dev_t; - -#define compat_ipc_pid_t compat_ipc_pid_t -typedef u16 compat_ipc_pid_t; - -#define compat_statfs compat_statfs - -#include - -#define __TYPE_IS_PTR(t) (!__builtin_types_compatible_p( \ - typeof(0?(__force t)0:0ULL), u64)) - -#define __SC_DELOUSE(t,v) ({ \ - BUILD_BUG_ON(sizeof(t) > 4 && !__TYPE_IS_PTR(t)); \ - (__force t)(__TYPE_IS_PTR(t) ? ((v) & 0x7fffffff) : (v)); \ -}) - -#define PSW32_MASK_USER 0x0000FF00UL - -#define PSW32_USER_BITS (PSW32_MASK_DAT | PSW32_MASK_IO | PSW32_MASK_EXT | \ - PSW32_DEFAULT_KEY | PSW32_MASK_BASE | \ - PSW32_MASK_MCHECK | PSW32_MASK_PSTATE | \ - PSW32_ASC_PRIMARY) - -#define COMPAT_UTS_MACHINE "s390\0\0\0\0" - -typedef u16 compat_nlink_t; - -typedef struct { - u32 mask; - u32 addr; -} __aligned(8) psw_compat_t; - -typedef struct { - psw_compat_t psw; - u32 gprs[NUM_GPRS]; - u32 acrs[NUM_ACRS]; - u32 orig_gpr2; -} s390_compat_regs; - -typedef struct { - u32 gprs_high[NUM_GPRS]; -} s390_compat_regs_high; - -struct compat_stat { - compat_dev_t st_dev; - u16 __pad1; - compat_ino_t st_ino; - compat_mode_t st_mode; - compat_nlink_t st_nlink; - __compat_uid_t st_uid; - __compat_gid_t st_gid; - compat_dev_t st_rdev; - u16 __pad2; - u32 st_size; - u32 st_blksize; - u32 st_blocks; - u32 st_atime; - u32 st_atime_nsec; - u32 st_mtime; - u32 st_mtime_nsec; - u32 st_ctime; - u32 st_ctime_nsec; - u32 __unused4; - u32 __unused5; -}; - -struct compat_statfs { - u32 f_type; - u32 f_bsize; - u32 f_blocks; - u32 f_bfree; - u32 f_bavail; - u32 f_files; - u32 f_ffree; - compat_fsid_t f_fsid; - u32 f_namelen; - u32 f_frsize; - u32 f_flags; - u32 f_spare[4]; -}; - -struct compat_statfs64 { - u32 f_type; - u32 f_bsize; - u64 f_blocks; - u64 f_bfree; - u64 f_bavail; - u64 f_files; - u64 f_ffree; - compat_fsid_t f_fsid; - u32 f_namelen; - u32 f_frsize; - u32 f_flags; - u32 f_spare[5]; -}; - -/* - * A pointer passed in from user mode. This should not - * be used for syscall parameters, just declare them - * as pointers because the syscall entry code will have - * appropriately converted them already. - */ - -static inline void __user *compat_ptr(compat_uptr_t uptr) -{ - return (void __user *)(unsigned long)(uptr & 0x7fffffffUL); -} -#define compat_ptr(uptr) compat_ptr(uptr) - -#ifdef CONFIG_COMPAT - -static inline int is_compat_task(void) -{ - return test_thread_flag(TIF_31BIT); -} - -#endif - -#endif /* _ASM_S390X_COMPAT_H */ diff --git a/arch/s390/include/asm/elf.h b/arch/s390/include/asm/elf.h index a03df312081e..2b6ab483b1ca 100644 --- a/arch/s390/include/asm/elf.h +++ b/arch/s390/include/asm/elf.h @@ -162,8 +162,6 @@ enum { * ELF register definitions.. */ -#include - #include #include #include @@ -171,9 +169,6 @@ enum { typedef s390_fp_regs elf_fpregset_t; typedef s390_regs elf_gregset_t; -typedef s390_fp_regs compat_elf_fpregset_t; -typedef s390_compat_regs compat_elf_gregset_t; - #include /* for task_struct */ #include @@ -183,10 +178,6 @@ typedef s390_compat_regs compat_elf_gregset_t; #define elf_check_arch(x) \ (((x)->e_machine == EM_S390 || (x)->e_machine == EM_S390_OLD) \ && (x)->e_ident[EI_CLASS] == ELF_CLASS) -#define compat_elf_check_arch(x) \ - (((x)->e_machine == EM_S390 || (x)->e_machine == EM_S390_OLD) \ - && (x)->e_ident[EI_CLASS] == ELF_CLASS) -#define compat_start_thread start_thread31 /* For SVR4/S390 the function pointer to be registered with `atexit` is passed in R14. */ @@ -203,9 +194,7 @@ typedef s390_compat_regs compat_elf_gregset_t; the loader. We need to make sure that it is out of the way of the program that it will "exec", and that there is sufficient room for the brk. 64-bit tasks are aligned to 4GB. */ -#define ELF_ET_DYN_BASE (is_compat_task() ? \ - (STACK_TOP / 3 * 2) : \ - (STACK_TOP / 3 * 2) & ~((1UL << 32) - 1)) +#define ELF_ET_DYN_BASE ((STACK_TOP / 3 * 2) & ~((1UL << 32) - 1)) /* This yields a mask that user programs can use to figure out what instruction set this CPU supports. */ @@ -224,43 +213,22 @@ extern unsigned long elf_hwcap; extern char elf_platform[]; #define ELF_PLATFORM (elf_platform) -#ifndef CONFIG_COMPAT #define SET_PERSONALITY(ex) \ do { \ set_personality(PER_LINUX | \ (current->personality & (~PER_MASK))); \ current->thread.sys_call_table = sys_call_table; \ } while (0) -#else /* CONFIG_COMPAT */ -#define SET_PERSONALITY(ex) \ -do { \ - if (personality(current->personality) != PER_LINUX32) \ - set_personality(PER_LINUX | \ - (current->personality & ~PER_MASK)); \ - if ((ex).e_ident[EI_CLASS] == ELFCLASS32) { \ - set_thread_flag(TIF_31BIT); \ - current->thread.sys_call_table = \ - sys_call_table_emu; \ - } else { \ - clear_thread_flag(TIF_31BIT); \ - current->thread.sys_call_table = \ - sys_call_table; \ - } \ -} while (0) -#endif /* CONFIG_COMPAT */ /* * Cache aliasing on the latest machines calls for a mapping granularity - * of 512KB for the anonymous mapping base. For 64-bit processes use a - * 512KB alignment and a randomization of up to 1GB. For 31-bit processes - * the virtual address space is limited, use no alignment and limit the - * randomization to 8MB. - * For the additional randomization of the program break use 32MB for - * 64-bit and 8MB for 31-bit. + * of 512KB for the anonymous mapping base. Use a 512KB alignment and a + * randomization of up to 1GB. + * For the additional randomization of the program break use 32MB. */ -#define BRK_RND_MASK (is_compat_task() ? 0x7ffUL : 0x1fffUL) -#define MMAP_RND_MASK (is_compat_task() ? 0x7ffUL : 0x3ff80UL) -#define MMAP_ALIGN_MASK (is_compat_task() ? 0 : 0x7fUL) +#define BRK_RND_MASK (0x1fffUL) +#define MMAP_RND_MASK (0x3ff80UL) +#define MMAP_ALIGN_MASK (0x7fUL) #define STACK_RND_MASK MMAP_RND_MASK /* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */ diff --git a/arch/s390/include/asm/ftrace.h b/arch/s390/include/asm/ftrace.h index bee2d16c2951..692c484ec163 100644 --- a/arch/s390/include/asm/ftrace.h +++ b/arch/s390/include/asm/ftrace.h @@ -105,28 +105,11 @@ static inline void arch_ftrace_set_direct_caller(struct ftrace_regs *fregs, unsi } #endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */ -/* - * Even though the system call numbers are identical for s390/s390x a - * different system call table is used for compat tasks. This may lead - * to e.g. incorrect or missing trace event sysfs files. - * Therefore simply do not trace compat system calls at all. - * See kernel/trace/trace_syscalls.c. - */ -#define ARCH_TRACE_IGNORE_COMPAT_SYSCALLS -static inline bool arch_trace_is_compat_syscall(struct pt_regs *regs) -{ - return is_compat_task(); -} - #define ARCH_HAS_SYSCALL_MATCH_SYM_NAME static inline bool arch_syscall_match_sym_name(const char *sym, const char *name) { - /* - * Skip __s390_ and __s390x_ prefix - due to compat wrappers - * and aliasing some symbols of 64 bit system call functions - * may get the __s390_ prefix instead of the __s390x_ prefix. - */ + /* Skip the __s390x_ prefix. */ return !strcmp(sym + 7, name) || !strcmp(sym + 8, name); } diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index ead1ebc9c61e..e8e9e6baebdd 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h @@ -119,18 +119,12 @@ extern void execve_tail(void); unsigned long vdso_text_size(void); unsigned long vdso_size(void); -/* - * User space process size: 2GB for 31 bit, 4TB or 8PT for 64 bit. - */ - -#define TASK_SIZE (test_thread_flag(TIF_31BIT) ? \ - _REGION3_SIZE : TASK_SIZE_MAX) -#define TASK_UNMAPPED_BASE (test_thread_flag(TIF_31BIT) ? \ - (_REGION3_SIZE >> 1) : (_REGION2_SIZE >> 1)) +#define TASK_SIZE (TASK_SIZE_MAX) +#define TASK_UNMAPPED_BASE (_REGION2_SIZE >> 1) #define TASK_SIZE_MAX (-PAGE_SIZE) #define VDSO_BASE (STACK_TOP + PAGE_SIZE) -#define VDSO_LIMIT (test_thread_flag(TIF_31BIT) ? _REGION3_SIZE : _REGION2_SIZE) +#define VDSO_LIMIT (_REGION2_SIZE) #define STACK_TOP (VDSO_LIMIT - vdso_size() - PAGE_SIZE) #define STACK_TOP_MAX (_REGION2_SIZE - vdso_size() - PAGE_SIZE) diff --git a/arch/s390/include/asm/seccomp.h b/arch/s390/include/asm/seccomp.h index 71d46f0ba97b..f904b674fee0 100644 --- a/arch/s390/include/asm/seccomp.h +++ b/arch/s390/include/asm/seccomp.h @@ -19,10 +19,5 @@ #define SECCOMP_ARCH_NATIVE AUDIT_ARCH_S390X #define SECCOMP_ARCH_NATIVE_NR NR_syscalls #define SECCOMP_ARCH_NATIVE_NAME "s390x" -#ifdef CONFIG_COMPAT -# define SECCOMP_ARCH_COMPAT AUDIT_ARCH_S390 -# define SECCOMP_ARCH_COMPAT_NR NR_syscalls -# define SECCOMP_ARCH_COMPAT_NAME "s390" -#endif #endif /* _ASM_S390_SECCOMP_H */ diff --git a/arch/s390/include/asm/syscall.h b/arch/s390/include/asm/syscall.h index 10ce5c4ccbd6..4271e4169f45 100644 --- a/arch/s390/include/asm/syscall.h +++ b/arch/s390/include/asm/syscall.h @@ -15,7 +15,6 @@ #include extern const sys_call_ptr_t sys_call_table[]; -extern const sys_call_ptr_t sys_call_table_emu[]; static inline long syscall_get_nr(struct task_struct *task, struct pt_regs *regs) @@ -46,15 +45,7 @@ static inline long syscall_get_error(struct task_struct *task, struct pt_regs *regs) { unsigned long error = regs->gprs[2]; -#ifdef CONFIG_COMPAT - if (test_tsk_thread_flag(task, TIF_31BIT)) { - /* - * Sign-extend the value so (int)-EFOO becomes (long)-EFOO - * and will match correctly in comparisons. - */ - error = (long)(int)error; - } -#endif + return IS_ERR_VALUE(error) ? error : 0; } @@ -78,10 +69,6 @@ static inline void syscall_get_arguments(struct task_struct *task, { unsigned long mask = -1UL; -#ifdef CONFIG_COMPAT - if (test_tsk_thread_flag(task, TIF_31BIT)) - mask = 0xffffffff; -#endif for (int i = 1; i < 6; i++) args[i] = regs->gprs[2 + i] & mask; @@ -99,10 +86,6 @@ static inline void syscall_set_arguments(struct task_struct *task, static inline int syscall_get_arch(struct task_struct *task) { -#ifdef CONFIG_COMPAT - if (test_tsk_thread_flag(task, TIF_31BIT)) - return AUDIT_ARCH_S390; -#endif return AUDIT_ARCH_S390X; } diff --git a/arch/s390/include/asm/syscall_wrapper.h b/arch/s390/include/asm/syscall_wrapper.h index bf1ff5e9242d..9eb58d5348d8 100644 --- a/arch/s390/include/asm/syscall_wrapper.h +++ b/arch/s390/include/asm/syscall_wrapper.h @@ -13,95 +13,6 @@ ,, regs->orig_gpr2,, regs->gprs[3],, regs->gprs[4] \ ,, regs->gprs[5],, regs->gprs[6],, regs->gprs[7]) -#ifdef CONFIG_COMPAT - -#define __SC_COMPAT_CAST(t, a) \ -({ \ - long __ReS = a; \ - \ - BUILD_BUG_ON((sizeof(t) > 4) && !__TYPE_IS_L(t) && \ - !__TYPE_IS_UL(t) && !__TYPE_IS_PTR(t) && \ - !__TYPE_IS_LL(t)); \ - if (__TYPE_IS_L(t)) \ - __ReS = (s32)a; \ - if (__TYPE_IS_UL(t)) \ - __ReS = (u32)a; \ - if (__TYPE_IS_PTR(t)) \ - __ReS = a & 0x7fffffff; \ - if (__TYPE_IS_LL(t)) \ - return -ENOSYS; \ - (t)__ReS; \ -}) - -/* - * To keep the naming coherent, re-define SYSCALL_DEFINE0 to create an alias - * named __s390x_sys_*() - */ -#define COMPAT_SYSCALL_DEFINE0(sname) \ - long __s390_compat_sys_##sname(struct pt_regs *__unused); \ - ALLOW_ERROR_INJECTION(__s390_compat_sys_##sname, ERRNO); \ - long __s390_compat_sys_##sname(struct pt_regs *__unused) - -#define SYSCALL_DEFINE0(sname) \ - SYSCALL_METADATA(_##sname, 0); \ - long __s390_sys_##sname(struct pt_regs *__unused); \ - ALLOW_ERROR_INJECTION(__s390_sys_##sname, ERRNO); \ - long __s390x_sys_##sname(struct pt_regs *__unused); \ - ALLOW_ERROR_INJECTION(__s390x_sys_##sname, ERRNO); \ - static inline long __do_sys_##sname(void); \ - long __s390_sys_##sname(struct pt_regs *__unused) \ - { \ - return __do_sys_##sname(); \ - } \ - long __s390x_sys_##sname(struct pt_regs *__unused) \ - { \ - return __do_sys_##sname(); \ - } \ - static inline long __do_sys_##sname(void) - -#define COND_SYSCALL(name) \ - cond_syscall(__s390x_sys_##name); \ - cond_syscall(__s390_sys_##name) - -#define COMPAT_SYSCALL_DEFINEx(x, name, ...) \ - long __s390_compat_sys##name(struct pt_regs *regs); \ - ALLOW_ERROR_INJECTION(__s390_compat_sys##name, ERRNO); \ - static inline long __se_compat_sys##name(__MAP(x, __SC_LONG, __VA_ARGS__)); \ - static inline long __do_compat_sys##name(__MAP(x, __SC_DECL, __VA_ARGS__)); \ - long __s390_compat_sys##name(struct pt_regs *regs) \ - { \ - return __se_compat_sys##name(SC_S390_REGS_TO_ARGS(x, __VA_ARGS__)); \ - } \ - static inline long __se_compat_sys##name(__MAP(x, __SC_LONG, __VA_ARGS__)) \ - { \ - __MAP(x, __SC_TEST, __VA_ARGS__); \ - return __do_compat_sys##name(__MAP(x, __SC_DELOUSE, __VA_ARGS__)); \ - } \ - static inline long __do_compat_sys##name(__MAP(x, __SC_DECL, __VA_ARGS__)) - -/* - * As some compat syscalls may not be implemented, we need to expand - * COND_SYSCALL_COMPAT in kernel/sys_ni.c to cover this case as well. - */ -#define COND_SYSCALL_COMPAT(name) \ - cond_syscall(__s390_compat_sys_##name) - -#define __S390_SYS_STUBx(x, name, ...) \ - long __s390_sys##name(struct pt_regs *regs); \ - ALLOW_ERROR_INJECTION(__s390_sys##name, ERRNO); \ - static inline long ___se_sys##name(__MAP(x, __SC_LONG, __VA_ARGS__)); \ - long __s390_sys##name(struct pt_regs *regs) \ - { \ - return ___se_sys##name(SC_S390_REGS_TO_ARGS(x, __VA_ARGS__)); \ - } \ - static inline long ___se_sys##name(__MAP(x, __SC_LONG, __VA_ARGS__)) \ - { \ - __MAP(x, __SC_TEST, __VA_ARGS__); \ - return __do_sys##name(__MAP(x, __SC_COMPAT_CAST, __VA_ARGS__)); \ - } - -#else /* CONFIG_COMPAT */ - #define SYSCALL_DEFINE0(sname) \ SYSCALL_METADATA(_##sname, 0); \ long __s390x_sys_##sname(struct pt_regs *__unused); \ @@ -118,8 +29,6 @@ #define __S390_SYS_STUBx(x, fullname, name, ...) -#endif /* CONFIG_COMPAT */ - #define __SYSCALL_DEFINEx(x, name, ...) \ long __s390x_sys##name(struct pt_regs *regs); \ ALLOW_ERROR_INJECTION(__s390x_sys##name, ERRNO); \ diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h index 7878e9bfbf07..6a548a819400 100644 --- a/arch/s390/include/asm/thread_info.h +++ b/arch/s390/include/asm/thread_info.h @@ -69,7 +69,6 @@ void arch_setup_new_exec(void); #define TIF_GUARDED_STORAGE 17 /* load guarded storage control block */ #define TIF_ISOLATE_BP_GUEST 18 /* Run KVM guests with isolated BP */ #define TIF_PER_TRAP 19 /* Need to handle PER trap on exit to usermode */ -#define TIF_31BIT 20 /* 32bit process */ #define TIF_SINGLE_STEP 21 /* This task is single stepped */ #define TIF_BLOCK_STEP 22 /* This task is block stepped */ #define TIF_UPROBE_SINGLESTEP 23 /* This task is uprobe single stepped */ @@ -78,7 +77,6 @@ void arch_setup_new_exec(void); #define _TIF_GUARDED_STORAGE BIT(TIF_GUARDED_STORAGE) #define _TIF_ISOLATE_BP_GUEST BIT(TIF_ISOLATE_BP_GUEST) #define _TIF_PER_TRAP BIT(TIF_PER_TRAP) -#define _TIF_31BIT BIT(TIF_31BIT) #define _TIF_SINGLE_STEP BIT(TIF_SINGLE_STEP) #define _TIF_BLOCK_STEP BIT(TIF_BLOCK_STEP) #define _TIF_UPROBE_SINGLESTEP BIT(TIF_UPROBE_SINGLESTEP) diff --git a/arch/s390/include/asm/unistd.h b/arch/s390/include/asm/unistd.h index 70fc671397da..252d7ac7a6b2 100644 --- a/arch/s390/include/asm/unistd.h +++ b/arch/s390/include/asm/unistd.h @@ -27,11 +27,6 @@ #define __ARCH_WANT_SYS_OLDUMOUNT #define __ARCH_WANT_SYS_SIGPENDING #define __ARCH_WANT_SYS_SIGPROCMASK -# ifdef CONFIG_COMPAT -# define __ARCH_WANT_COMPAT_STAT -# define __ARCH_WANT_SYS_TIME32 -# define __ARCH_WANT_SYS_UTIME32 -# endif #define __ARCH_WANT_SYS_FORK #define __ARCH_WANT_SYS_VFORK #define __ARCH_WANT_SYS_CLONE diff --git a/arch/s390/include/asm/vdso-symbols.h b/arch/s390/include/asm/vdso-symbols.h index 0df17574d788..205da2c565c2 100644 --- a/arch/s390/include/asm/vdso-symbols.h +++ b/arch/s390/include/asm/vdso-symbols.h @@ -3,15 +3,7 @@ #define __S390_VDSO_SYMBOLS_H__ #include -#ifdef CONFIG_COMPAT -#include -#endif #define VDSO64_SYMBOL(tsk, name) ((tsk)->mm->context.vdso_base + (vdso64_offset_##name)) -#ifdef CONFIG_COMPAT -#define VDSO32_SYMBOL(tsk, name) ((tsk)->mm->context.vdso_base + (vdso32_offset_##name)) -#else -#define VDSO32_SYMBOL(tsk, name) (-1UL) -#endif #endif /* __S390_VDSO_SYMBOLS_H__ */ diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index c5791179b4b0..810000355ac5 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile @@ -56,9 +56,6 @@ obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_SCHED_TOPOLOGY) += topology.o hiperdispatch.o obj-$(CONFIG_NUMA) += numa.o obj-$(CONFIG_AUDIT) += audit.o -compat-obj-$(CONFIG_AUDIT) += compat_audit.o -obj-$(CONFIG_COMPAT) += compat_linux.o compat_signal.o -obj-$(CONFIG_COMPAT) += $(compat-obj-y) obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_KPROBES) += mcount.o @@ -85,4 +82,3 @@ obj-$(CONFIG_TRACEPOINTS) += trace.o # vdso obj-y += vdso64/ -obj-$(CONFIG_COMPAT) += vdso32/ diff --git a/arch/s390/kernel/audit.c b/arch/s390/kernel/audit.c index 02051a596b87..7897d9411e13 100644 --- a/arch/s390/kernel/audit.c +++ b/arch/s390/kernel/audit.c @@ -3,7 +3,6 @@ #include #include #include -#include "audit.h" static unsigned dir_class[] = { #include @@ -32,19 +31,11 @@ static unsigned signal_class[] = { int audit_classify_arch(int arch) { -#ifdef CONFIG_COMPAT - if (arch == AUDIT_ARCH_S390) - return 1; -#endif return 0; } int audit_classify_syscall(int abi, unsigned syscall) { -#ifdef CONFIG_COMPAT - if (abi == AUDIT_ARCH_S390) - return s390_classify_syscall(syscall); -#endif switch(syscall) { case __NR_open: return AUDITSC_OPEN; @@ -63,13 +54,6 @@ int audit_classify_syscall(int abi, unsigned syscall) static int __init audit_classes_init(void) { -#ifdef CONFIG_COMPAT - audit_register_class(AUDIT_CLASS_WRITE_32, s390_write_class); - audit_register_class(AUDIT_CLASS_READ_32, s390_read_class); - audit_register_class(AUDIT_CLASS_DIR_WRITE_32, s390_dir_class); - audit_register_class(AUDIT_CLASS_CHATTR_32, s390_chattr_class); - audit_register_class(AUDIT_CLASS_SIGNAL_32, s390_signal_class); -#endif audit_register_class(AUDIT_CLASS_WRITE, write_class); audit_register_class(AUDIT_CLASS_READ, read_class); audit_register_class(AUDIT_CLASS_DIR_WRITE, dir_class); diff --git a/arch/s390/kernel/audit.h b/arch/s390/kernel/audit.h deleted file mode 100644 index 4d4b596412ec..000000000000 --- a/arch/s390/kernel/audit.h +++ /dev/null @@ -1,16 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __ARCH_S390_KERNEL_AUDIT_H -#define __ARCH_S390_KERNEL_AUDIT_H - -#include - -#ifdef CONFIG_COMPAT -extern int s390_classify_syscall(unsigned); -extern __u32 s390_dir_class[]; -extern __u32 s390_write_class[]; -extern __u32 s390_read_class[]; -extern __u32 s390_chattr_class[]; -extern __u32 s390_signal_class[]; -#endif /* CONFIG_COMPAT */ - -#endif /* __ARCH_S390_KERNEL_AUDIT_H */ diff --git a/arch/s390/kernel/compat_audit.c b/arch/s390/kernel/compat_audit.c deleted file mode 100644 index a7c46e8310f0..000000000000 --- a/arch/s390/kernel/compat_audit.c +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#undef __s390x__ -#include -#include -#include "audit.h" - -unsigned s390_dir_class[] = { -#include -~0U -}; - -unsigned s390_chattr_class[] = { -#include -~0U -}; - -unsigned s390_write_class[] = { -#include -~0U -}; - -unsigned s390_read_class[] = { -#include -~0U -}; - -unsigned s390_signal_class[] = { -#include -~0U -}; - -int s390_classify_syscall(unsigned syscall) -{ - switch(syscall) { - case __NR_open: - return AUDITSC_OPEN; - case __NR_openat: - return AUDITSC_OPENAT; - case __NR_socketcall: - return AUDITSC_SOCKETCALL; - case __NR_execve: - return AUDITSC_EXECVE; - case __NR_openat2: - return AUDITSC_OPENAT2; - default: - return AUDITSC_COMPAT; - } -} diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c deleted file mode 100644 index f9d418d1b619..000000000000 --- a/arch/s390/kernel/compat_linux.c +++ /dev/null @@ -1,289 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * S390 version - * Copyright IBM Corp. 2000 - * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), - * Gerhard Tonn (ton@de.ibm.com) - * Thomas Spatzier (tspat@de.ibm.com) - * - * Conversion between 31bit and 64bit native syscalls. - * - * Heavily inspired by the 32-bit Sparc compat code which is - * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) - * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) - * - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include "compat_linux.h" - -#ifdef CONFIG_SYSVIPC -COMPAT_SYSCALL_DEFINE5(s390_ipc, uint, call, int, first, compat_ulong_t, second, - compat_ulong_t, third, compat_uptr_t, ptr) -{ - if (call >> 16) /* hack for backward compatibility */ - return -EINVAL; - return compat_ksys_ipc(call, first, second, third, ptr, third); -} -#endif - -COMPAT_SYSCALL_DEFINE3(s390_truncate64, const char __user *, path, u32, high, u32, low) -{ - return ksys_truncate(path, (unsigned long)high << 32 | low); -} - -COMPAT_SYSCALL_DEFINE3(s390_ftruncate64, unsigned int, fd, u32, high, u32, low) -{ - return ksys_ftruncate(fd, (unsigned long)high << 32 | low); -} - -COMPAT_SYSCALL_DEFINE5(s390_pread64, unsigned int, fd, char __user *, ubuf, - compat_size_t, count, u32, high, u32, low) -{ - if ((compat_ssize_t) count < 0) - return -EINVAL; - return ksys_pread64(fd, ubuf, count, (unsigned long)high << 32 | low); -} - -COMPAT_SYSCALL_DEFINE5(s390_pwrite64, unsigned int, fd, const char __user *, ubuf, - compat_size_t, count, u32, high, u32, low) -{ - if ((compat_ssize_t) count < 0) - return -EINVAL; - return ksys_pwrite64(fd, ubuf, count, (unsigned long)high << 32 | low); -} - -COMPAT_SYSCALL_DEFINE4(s390_readahead, int, fd, u32, high, u32, low, s32, count) -{ - return ksys_readahead(fd, (unsigned long)high << 32 | low, count); -} - -struct stat64_emu31 { - unsigned long long st_dev; - unsigned int __pad1; -#define STAT64_HAS_BROKEN_ST_INO 1 - u32 __st_ino; - unsigned int st_mode; - unsigned int st_nlink; - u32 st_uid; - u32 st_gid; - unsigned long long st_rdev; - unsigned int __pad3; - long st_size; - u32 st_blksize; - unsigned char __pad4[4]; - u32 __pad5; /* future possible st_blocks high bits */ - u32 st_blocks; /* Number 512-byte blocks allocated. */ - u32 st_atime; - u32 __pad6; - u32 st_mtime; - u32 __pad7; - u32 st_ctime; - u32 __pad8; /* will be high 32 bits of ctime someday */ - unsigned long st_ino; -}; - -static int cp_stat64(struct stat64_emu31 __user *ubuf, struct kstat *stat) -{ - struct stat64_emu31 tmp; - - memset(&tmp, 0, sizeof(tmp)); - - tmp.st_dev = huge_encode_dev(stat->dev); - tmp.st_ino = stat->ino; - tmp.__st_ino = (u32)stat->ino; - tmp.st_mode = stat->mode; - tmp.st_nlink = (unsigned int)stat->nlink; - tmp.st_uid = from_kuid_munged(current_user_ns(), stat->uid); - tmp.st_gid = from_kgid_munged(current_user_ns(), stat->gid); - tmp.st_rdev = huge_encode_dev(stat->rdev); - tmp.st_size = stat->size; - tmp.st_blksize = (u32)stat->blksize; - tmp.st_blocks = (u32)stat->blocks; - tmp.st_atime = (u32)stat->atime.tv_sec; - tmp.st_mtime = (u32)stat->mtime.tv_sec; - tmp.st_ctime = (u32)stat->ctime.tv_sec; - - return copy_to_user(ubuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; -} - -COMPAT_SYSCALL_DEFINE2(s390_stat64, const char __user *, filename, struct stat64_emu31 __user *, statbuf) -{ - struct kstat stat; - int ret = vfs_stat(filename, &stat); - if (!ret) - ret = cp_stat64(statbuf, &stat); - return ret; -} - -COMPAT_SYSCALL_DEFINE2(s390_lstat64, const char __user *, filename, struct stat64_emu31 __user *, statbuf) -{ - struct kstat stat; - int ret = vfs_lstat(filename, &stat); - if (!ret) - ret = cp_stat64(statbuf, &stat); - return ret; -} - -COMPAT_SYSCALL_DEFINE2(s390_fstat64, unsigned int, fd, struct stat64_emu31 __user *, statbuf) -{ - struct kstat stat; - int ret = vfs_fstat(fd, &stat); - if (!ret) - ret = cp_stat64(statbuf, &stat); - return ret; -} - -COMPAT_SYSCALL_DEFINE4(s390_fstatat64, unsigned int, dfd, const char __user *, filename, - struct stat64_emu31 __user *, statbuf, int, flag) -{ - struct kstat stat; - int error; - - error = vfs_fstatat(dfd, filename, &stat, flag); - if (error) - return error; - return cp_stat64(statbuf, &stat); -} - -/* - * Linux/i386 didn't use to be able to handle more than - * 4 system call parameters, so these system calls used a memory - * block for parameter passing.. - */ - -struct mmap_arg_struct_emu31 { - compat_ulong_t addr; - compat_ulong_t len; - compat_ulong_t prot; - compat_ulong_t flags; - compat_ulong_t fd; - compat_ulong_t offset; -}; - -COMPAT_SYSCALL_DEFINE1(s390_old_mmap, struct mmap_arg_struct_emu31 __user *, arg) -{ - struct mmap_arg_struct_emu31 a; - - if (copy_from_user(&a, arg, sizeof(a))) - return -EFAULT; - if (a.offset & ~PAGE_MASK) - return -EINVAL; - return ksys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, - a.offset >> PAGE_SHIFT); -} - -COMPAT_SYSCALL_DEFINE1(s390_mmap2, struct mmap_arg_struct_emu31 __user *, arg) -{ - struct mmap_arg_struct_emu31 a; - - if (copy_from_user(&a, arg, sizeof(a))) - return -EFAULT; - return ksys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset); -} - -COMPAT_SYSCALL_DEFINE3(s390_read, unsigned int, fd, char __user *, buf, compat_size_t, count) -{ - if ((compat_ssize_t) count < 0) - return -EINVAL; - - return ksys_read(fd, buf, count); -} - -COMPAT_SYSCALL_DEFINE3(s390_write, unsigned int, fd, const char __user *, buf, compat_size_t, count) -{ - if ((compat_ssize_t) count < 0) - return -EINVAL; - - return ksys_write(fd, buf, count); -} - -/* - * 31 bit emulation wrapper functions for sys_fadvise64/fadvise64_64. - * These need to rewrite the advise values for POSIX_FADV_{DONTNEED,NOREUSE} - * because the 31 bit values differ from the 64 bit values. - */ - -COMPAT_SYSCALL_DEFINE5(s390_fadvise64, int, fd, u32, high, u32, low, compat_size_t, len, int, advise) -{ - if (advise == 4) - advise = POSIX_FADV_DONTNEED; - else if (advise == 5) - advise = POSIX_FADV_NOREUSE; - return ksys_fadvise64_64(fd, (unsigned long)high << 32 | low, len, - advise); -} - -struct fadvise64_64_args { - int fd; - long long offset; - long long len; - int advice; -}; - -COMPAT_SYSCALL_DEFINE1(s390_fadvise64_64, struct fadvise64_64_args __user *, args) -{ - struct fadvise64_64_args a; - - if ( copy_from_user(&a, args, sizeof(a)) ) - return -EFAULT; - if (a.advice == 4) - a.advice = POSIX_FADV_DONTNEED; - else if (a.advice == 5) - a.advice = POSIX_FADV_NOREUSE; - return ksys_fadvise64_64(a.fd, a.offset, a.len, a.advice); -} - -COMPAT_SYSCALL_DEFINE6(s390_sync_file_range, int, fd, u32, offhigh, u32, offlow, - u32, nhigh, u32, nlow, unsigned int, flags) -{ - return ksys_sync_file_range(fd, ((loff_t)offhigh << 32) + offlow, - ((u64)nhigh << 32) + nlow, flags); -} - -COMPAT_SYSCALL_DEFINE6(s390_fallocate, int, fd, int, mode, u32, offhigh, u32, offlow, - u32, lenhigh, u32, lenlow) -{ - return ksys_fallocate(fd, mode, ((loff_t)offhigh << 32) + offlow, - ((u64)lenhigh << 32) + lenlow); -} diff --git a/arch/s390/kernel/compat_linux.h b/arch/s390/kernel/compat_linux.h deleted file mode 100644 index 133f22b5deeb..000000000000 --- a/arch/s390/kernel/compat_linux.h +++ /dev/null @@ -1,101 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _ASM_S390X_S390_H -#define _ASM_S390X_S390_H - -#include -#include -#include -#include - -/* - * Macro that masks the high order bit of a 32 bit pointer and - * converts it to a 64 bit pointer. - */ -#define A(__x) ((unsigned long)((__x) & 0x7FFFFFFFUL)) -#define AA(__x) ((unsigned long)(__x)) - -/* Now 32bit compatibility types */ -struct ipc_kludge_32 { - __u32 msgp; /* pointer */ - __s32 msgtyp; -}; - -/* asm/sigcontext.h */ -typedef union { - __u64 d; - __u32 f; -} freg_t32; - -typedef struct { - unsigned int fpc; - unsigned int pad; - freg_t32 fprs[__NUM_FPRS]; -} _s390_fp_regs32; - -typedef struct { - psw32_t psw; - __u32 gprs[__NUM_GPRS]; - __u32 acrs[__NUM_ACRS]; -} _s390_regs_common32; - -typedef struct { - _s390_regs_common32 regs; - _s390_fp_regs32 fpregs; -} _sigregs32; - -typedef struct { - __u32 gprs_high[__NUM_GPRS]; - __u64 vxrs_low[__NUM_VXRS_LOW]; - __vector128 vxrs_high[__NUM_VXRS_HIGH]; - __u8 __reserved[128]; -} _sigregs_ext32; - -#define _SIGCONTEXT_NSIG32 64 -#define _SIGCONTEXT_NSIG_BPW32 32 -#define __SIGNAL_FRAMESIZE32 96 -#define _SIGMASK_COPY_SIZE32 (sizeof(u32) * 2) - -struct sigcontext32 { - __u32 oldmask[_COMPAT_NSIG_WORDS]; - __u32 sregs; /* pointer */ -}; - -/* asm/signal.h */ - -/* asm/ucontext.h */ -struct ucontext32 { - __u32 uc_flags; - __u32 uc_link; /* pointer */ - compat_stack_t uc_stack; - _sigregs32 uc_mcontext; - compat_sigset_t uc_sigmask; - /* Allow for uc_sigmask growth. Glibc uses a 1024-bit sigset_t. */ - unsigned char __unused[128 - sizeof(compat_sigset_t)]; - _sigregs_ext32 uc_mcontext_ext; -}; - -struct stat64_emu31; -struct mmap_arg_struct_emu31; -struct fadvise64_64_args; - -long compat_sys_s390_truncate64(const char __user *path, u32 high, u32 low); -long compat_sys_s390_ftruncate64(unsigned int fd, u32 high, u32 low); -long compat_sys_s390_pread64(unsigned int fd, char __user *ubuf, compat_size_t count, u32 high, u32 low); -long compat_sys_s390_pwrite64(unsigned int fd, const char __user *ubuf, compat_size_t count, u32 high, u32 low); -long compat_sys_s390_readahead(int fd, u32 high, u32 low, s32 count); -long compat_sys_s390_stat64(const char __user *filename, struct stat64_emu31 __user *statbuf); -long compat_sys_s390_lstat64(const char __user *filename, struct stat64_emu31 __user *statbuf); -long compat_sys_s390_fstat64(unsigned int fd, struct stat64_emu31 __user *statbuf); -long compat_sys_s390_fstatat64(unsigned int dfd, const char __user *filename, struct stat64_emu31 __user *statbuf, int flag); -long compat_sys_s390_old_mmap(struct mmap_arg_struct_emu31 __user *arg); -long compat_sys_s390_mmap2(struct mmap_arg_struct_emu31 __user *arg); -long compat_sys_s390_read(unsigned int fd, char __user *buf, compat_size_t count); -long compat_sys_s390_write(unsigned int fd, const char __user *buf, compat_size_t count); -long compat_sys_s390_fadvise64(int fd, u32 high, u32 low, compat_size_t len, int advise); -long compat_sys_s390_fadvise64_64(struct fadvise64_64_args __user *args); -long compat_sys_s390_sync_file_range(int fd, u32 offhigh, u32 offlow, u32 nhigh, u32 nlow, unsigned int flags); -long compat_sys_s390_fallocate(int fd, int mode, u32 offhigh, u32 offlow, u32 lenhigh, u32 lenlow); -long compat_sys_sigreturn(void); -long compat_sys_rt_sigreturn(void); - -#endif /* _ASM_S390X_S390_H */ diff --git a/arch/s390/kernel/compat_ptrace.h b/arch/s390/kernel/compat_ptrace.h deleted file mode 100644 index 3c400fc7e987..000000000000 --- a/arch/s390/kernel/compat_ptrace.h +++ /dev/null @@ -1,64 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _PTRACE32_H -#define _PTRACE32_H - -#include /* needed for NUM_CR_WORDS */ -#include "compat_linux.h" /* needed for psw_compat_t */ - -struct compat_per_struct_kernel { - __u32 cr9; /* PER control bits */ - __u32 cr10; /* PER starting address */ - __u32 cr11; /* PER ending address */ - __u32 bits; /* Obsolete software bits */ - __u32 starting_addr; /* User specified start address */ - __u32 ending_addr; /* User specified end address */ - __u16 perc_atmid; /* PER trap ATMID */ - __u32 address; /* PER trap instruction address */ - __u8 access_id; /* PER trap access identification */ -}; - -struct compat_user_regs_struct -{ - psw_compat_t psw; - u32 gprs[NUM_GPRS]; - u32 acrs[NUM_ACRS]; - u32 orig_gpr2; - /* nb: there's a 4-byte hole here */ - s390_fp_regs fp_regs; - /* - * These per registers are in here so that gdb can modify them - * itself as there is no "official" ptrace interface for hardware - * watchpoints. This is the way intel does it. - */ - struct compat_per_struct_kernel per_info; - u32 ieee_instruction_pointer; /* obsolete, always 0 */ -}; - -struct compat_user { - /* We start with the registers, to mimic the way that "memory" - is returned from the ptrace(3,...) function. */ - struct compat_user_regs_struct regs; - /* The rest of this junk is to help gdb figure out what goes where */ - u32 u_tsize; /* Text segment size (pages). */ - u32 u_dsize; /* Data segment size (pages). */ - u32 u_ssize; /* Stack segment size (pages). */ - u32 start_code; /* Starting virtual address of text. */ - u32 start_stack; /* Starting virtual address of stack area. - This is actually the bottom of the stack, - the top of the stack is always found in the - esp register. */ - s32 signal; /* Signal that caused the core dump. */ - u32 u_ar0; /* Used by gdb to help find the values for */ - /* the registers. */ - u32 magic; /* To uniquely identify a core file */ - char u_comm[32]; /* User command that was responsible */ -}; - -typedef struct -{ - __u32 len; - __u32 kernel_addr; - __u32 process_addr; -} compat_ptrace_area; - -#endif /* _PTRACE32_H */ diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c deleted file mode 100644 index 5a86b9d1da71..000000000000 --- a/arch/s390/kernel/compat_signal.c +++ /dev/null @@ -1,420 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright IBM Corp. 2000, 2006 - * Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) - * Gerhard Tonn (ton@de.ibm.com) - * - * Copyright (C) 1991, 1992 Linus Torvalds - * - * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "compat_linux.h" -#include "compat_ptrace.h" -#include "entry.h" - -typedef struct -{ - __u8 callee_used_stack[__SIGNAL_FRAMESIZE32]; - struct sigcontext32 sc; - _sigregs32 sregs; - int signo; - _sigregs_ext32 sregs_ext; - __u16 svc_insn; /* Offset of svc_insn is NOT fixed! */ -} sigframe32; - -typedef struct -{ - __u8 callee_used_stack[__SIGNAL_FRAMESIZE32]; - __u16 svc_insn; - compat_siginfo_t info; - struct ucontext32 uc; -} rt_sigframe32; - -/* Store registers needed to create the signal frame */ -static void store_sigregs(void) -{ - save_access_regs(current->thread.acrs); - save_user_fpu_regs(); -} - -/* Load registers after signal return */ -static void load_sigregs(void) -{ - restore_access_regs(current->thread.acrs); -} - -static int save_sigregs32(struct pt_regs *regs, _sigregs32 __user *sregs) -{ - _sigregs32 user_sregs; - int i; - - user_sregs.regs.psw.mask = (__u32)(regs->psw.mask >> 32); - user_sregs.regs.psw.mask &= PSW32_MASK_USER | PSW32_MASK_RI; - user_sregs.regs.psw.mask |= PSW32_USER_BITS; - user_sregs.regs.psw.addr = (__u32) regs->psw.addr | - (__u32)(regs->psw.mask & PSW_MASK_BA); - for (i = 0; i < NUM_GPRS; i++) - user_sregs.regs.gprs[i] = (__u32) regs->gprs[i]; - memcpy(&user_sregs.regs.acrs, current->thread.acrs, - sizeof(user_sregs.regs.acrs)); - fpregs_store((_s390_fp_regs *) &user_sregs.fpregs, ¤t->thread.ufpu); - if (__copy_to_user(sregs, &user_sregs, sizeof(_sigregs32))) - return -EFAULT; - return 0; -} - -static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs) -{ - _sigregs32 user_sregs; - int i; - - /* Always make any pending restarted system call return -EINTR */ - current->restart_block.fn = do_no_restart_syscall; - - if (__copy_from_user(&user_sregs, &sregs->regs, sizeof(user_sregs))) - return -EFAULT; - - if (!is_ri_task(current) && (user_sregs.regs.psw.mask & PSW32_MASK_RI)) - return -EINVAL; - - /* Use regs->psw.mask instead of PSW_USER_BITS to preserve PER bit. */ - regs->psw.mask = (regs->psw.mask & ~(PSW_MASK_USER | PSW_MASK_RI)) | - (__u64)(user_sregs.regs.psw.mask & PSW32_MASK_USER) << 32 | - (__u64)(user_sregs.regs.psw.mask & PSW32_MASK_RI) << 32 | - (__u64)(user_sregs.regs.psw.addr & PSW32_ADDR_AMODE); - /* Check for invalid user address space control. */ - if ((regs->psw.mask & PSW_MASK_ASC) == PSW_ASC_HOME) - regs->psw.mask = PSW_ASC_PRIMARY | - (regs->psw.mask & ~PSW_MASK_ASC); - regs->psw.addr = (__u64)(user_sregs.regs.psw.addr & PSW32_ADDR_INSN); - for (i = 0; i < NUM_GPRS; i++) - regs->gprs[i] = (__u64) user_sregs.regs.gprs[i]; - memcpy(¤t->thread.acrs, &user_sregs.regs.acrs, - sizeof(current->thread.acrs)); - fpregs_load((_s390_fp_regs *)&user_sregs.fpregs, ¤t->thread.ufpu); - - clear_pt_regs_flag(regs, PIF_SYSCALL); /* No longer in a system call */ - return 0; -} - -static int save_sigregs_ext32(struct pt_regs *regs, - _sigregs_ext32 __user *sregs_ext) -{ - __u32 gprs_high[NUM_GPRS]; - __u64 vxrs[__NUM_VXRS_LOW]; - int i; - - /* Save high gprs to signal stack */ - for (i = 0; i < NUM_GPRS; i++) - gprs_high[i] = regs->gprs[i] >> 32; - if (__copy_to_user(&sregs_ext->gprs_high, &gprs_high, - sizeof(sregs_ext->gprs_high))) - return -EFAULT; - - /* Save vector registers to signal stack */ - if (cpu_has_vx()) { - for (i = 0; i < __NUM_VXRS_LOW; i++) - vxrs[i] = current->thread.ufpu.vxrs[i].low; - if (__copy_to_user(&sregs_ext->vxrs_low, vxrs, - sizeof(sregs_ext->vxrs_low)) || - __copy_to_user(&sregs_ext->vxrs_high, - current->thread.ufpu.vxrs + __NUM_VXRS_LOW, - sizeof(sregs_ext->vxrs_high))) - return -EFAULT; - } - return 0; -} - -static int restore_sigregs_ext32(struct pt_regs *regs, - _sigregs_ext32 __user *sregs_ext) -{ - __u32 gprs_high[NUM_GPRS]; - __u64 vxrs[__NUM_VXRS_LOW]; - int i; - - /* Restore high gprs from signal stack */ - if (__copy_from_user(&gprs_high, &sregs_ext->gprs_high, - sizeof(sregs_ext->gprs_high))) - return -EFAULT; - for (i = 0; i < NUM_GPRS; i++) - *(__u32 *)®s->gprs[i] = gprs_high[i]; - - /* Restore vector registers from signal stack */ - if (cpu_has_vx()) { - if (__copy_from_user(vxrs, &sregs_ext->vxrs_low, - sizeof(sregs_ext->vxrs_low)) || - __copy_from_user(current->thread.ufpu.vxrs + __NUM_VXRS_LOW, - &sregs_ext->vxrs_high, - sizeof(sregs_ext->vxrs_high))) - return -EFAULT; - for (i = 0; i < __NUM_VXRS_LOW; i++) - current->thread.ufpu.vxrs[i].low = vxrs[i]; - } - return 0; -} - -COMPAT_SYSCALL_DEFINE0(sigreturn) -{ - struct pt_regs *regs = task_pt_regs(current); - sigframe32 __user *frame = (sigframe32 __user *)regs->gprs[15]; - sigset_t set; - - if (get_compat_sigset(&set, (compat_sigset_t __user *)frame->sc.oldmask)) - goto badframe; - set_current_blocked(&set); - save_user_fpu_regs(); - if (restore_sigregs32(regs, &frame->sregs)) - goto badframe; - if (restore_sigregs_ext32(regs, &frame->sregs_ext)) - goto badframe; - load_sigregs(); - return regs->gprs[2]; -badframe: - force_sig(SIGSEGV); - return 0; -} - -COMPAT_SYSCALL_DEFINE0(rt_sigreturn) -{ - struct pt_regs *regs = task_pt_regs(current); - rt_sigframe32 __user *frame = (rt_sigframe32 __user *)regs->gprs[15]; - sigset_t set; - - if (get_compat_sigset(&set, &frame->uc.uc_sigmask)) - goto badframe; - set_current_blocked(&set); - if (compat_restore_altstack(&frame->uc.uc_stack)) - goto badframe; - save_user_fpu_regs(); - if (restore_sigregs32(regs, &frame->uc.uc_mcontext)) - goto badframe; - if (restore_sigregs_ext32(regs, &frame->uc.uc_mcontext_ext)) - goto badframe; - load_sigregs(); - return regs->gprs[2]; -badframe: - force_sig(SIGSEGV); - return 0; -} - -/* - * Set up a signal frame. - */ - - -/* - * Determine which stack to use.. - */ -static inline void __user * -get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) -{ - unsigned long sp; - - /* Default to using normal stack */ - sp = (unsigned long) A(regs->gprs[15]); - - /* Overflow on alternate signal stack gives SIGSEGV. */ - if (on_sig_stack(sp) && !on_sig_stack((sp - frame_size) & -8UL)) - return (void __user *) -1UL; - - /* This is the X/Open sanctioned signal stack switching. */ - if (ka->sa.sa_flags & SA_ONSTACK) { - if (! sas_ss_flags(sp)) - sp = current->sas_ss_sp + current->sas_ss_size; - } - - return (void __user *)((sp - frame_size) & -8ul); -} - -static int setup_frame32(struct ksignal *ksig, sigset_t *set, - struct pt_regs *regs) -{ - int sig = ksig->sig; - sigframe32 __user *frame; - unsigned long restorer; - size_t frame_size; - - /* - * gprs_high are always present for 31-bit compat tasks. - * The space for vector registers is only allocated if - * the machine supports it - */ - frame_size = sizeof(*frame) - sizeof(frame->sregs_ext.__reserved); - if (!cpu_has_vx()) - frame_size -= sizeof(frame->sregs_ext.vxrs_low) + - sizeof(frame->sregs_ext.vxrs_high); - frame = get_sigframe(&ksig->ka, regs, frame_size); - if (frame == (void __user *) -1UL) - return -EFAULT; - - /* Set up backchain. */ - if (__put_user(regs->gprs[15], (unsigned int __user *) frame)) - return -EFAULT; - - /* Create struct sigcontext32 on the signal stack */ - if (put_compat_sigset((compat_sigset_t __user *)frame->sc.oldmask, - set, sizeof(compat_sigset_t))) - return -EFAULT; - if (__put_user(ptr_to_compat(&frame->sregs), &frame->sc.sregs)) - return -EFAULT; - - /* Store registers needed to create the signal frame */ - store_sigregs(); - - /* Create _sigregs32 on the signal stack */ - if (save_sigregs32(regs, &frame->sregs)) - return -EFAULT; - - /* Place signal number on stack to allow backtrace from handler. */ - if (__put_user(regs->gprs[2], (int __force __user *) &frame->signo)) - return -EFAULT; - - /* Create _sigregs_ext32 on the signal stack */ - if (save_sigregs_ext32(regs, &frame->sregs_ext)) - return -EFAULT; - - /* Set up to return from userspace. If provided, use a stub - already in userspace. */ - if (ksig->ka.sa.sa_flags & SA_RESTORER) { - restorer = (unsigned long __force) - ksig->ka.sa.sa_restorer | PSW32_ADDR_AMODE; - } else { - restorer = VDSO32_SYMBOL(current, sigreturn); - } - - /* Set up registers for signal handler */ - regs->gprs[14] = restorer; - regs->gprs[15] = (__force __u64) frame; - /* Force 31 bit amode and default user address space control. */ - regs->psw.mask = PSW_MASK_BA | - (PSW_USER_BITS & PSW_MASK_ASC) | - (regs->psw.mask & ~PSW_MASK_ASC); - regs->psw.addr = (__force __u64) ksig->ka.sa.sa_handler; - - regs->gprs[2] = sig; - regs->gprs[3] = (__force __u64) &frame->sc; - - /* We forgot to include these in the sigcontext. - To avoid breaking binary compatibility, they are passed as args. */ - if (sig == SIGSEGV || sig == SIGBUS || sig == SIGILL || - sig == SIGTRAP || sig == SIGFPE) { - /* set extra registers only for synchronous signals */ - regs->gprs[4] = regs->int_code & 127; - regs->gprs[5] = regs->int_parm_long; - regs->gprs[6] = current->thread.last_break; - } - - return 0; -} - -static int setup_rt_frame32(struct ksignal *ksig, sigset_t *set, - struct pt_regs *regs) -{ - rt_sigframe32 __user *frame; - unsigned long restorer; - size_t frame_size; - u32 uc_flags; - - frame_size = sizeof(*frame) - - sizeof(frame->uc.uc_mcontext_ext.__reserved); - /* - * gprs_high are always present for 31-bit compat tasks. - * The space for vector registers is only allocated if - * the machine supports it - */ - uc_flags = UC_GPRS_HIGH; - if (cpu_has_vx()) { - uc_flags |= UC_VXRS; - } else { - frame_size -= sizeof(frame->uc.uc_mcontext_ext.vxrs_low) + - sizeof(frame->uc.uc_mcontext_ext.vxrs_high); - } - frame = get_sigframe(&ksig->ka, regs, frame_size); - if (frame == (void __user *) -1UL) - return -EFAULT; - - /* Set up backchain. */ - if (__put_user(regs->gprs[15], (unsigned int __force __user *) frame)) - return -EFAULT; - - /* Set up to return from userspace. If provided, use a stub - already in userspace. */ - if (ksig->ka.sa.sa_flags & SA_RESTORER) { - restorer = (unsigned long __force) - ksig->ka.sa.sa_restorer | PSW32_ADDR_AMODE; - } else { - restorer = VDSO32_SYMBOL(current, rt_sigreturn); - } - - /* Create siginfo on the signal stack */ - if (copy_siginfo_to_user32(&frame->info, &ksig->info)) - return -EFAULT; - - /* Store registers needed to create the signal frame */ - store_sigregs(); - - /* Create ucontext on the signal stack. */ - if (__put_user(uc_flags, &frame->uc.uc_flags) || - __put_user(0, &frame->uc.uc_link) || - __compat_save_altstack(&frame->uc.uc_stack, regs->gprs[15]) || - save_sigregs32(regs, &frame->uc.uc_mcontext) || - put_compat_sigset(&frame->uc.uc_sigmask, set, sizeof(compat_sigset_t)) || - save_sigregs_ext32(regs, &frame->uc.uc_mcontext_ext)) - return -EFAULT; - - /* Set up registers for signal handler */ - regs->gprs[14] = restorer; - regs->gprs[15] = (__force __u64) frame; - /* Force 31 bit amode and default user address space control. */ - regs->psw.mask = PSW_MASK_BA | - (PSW_USER_BITS & PSW_MASK_ASC) | - (regs->psw.mask & ~PSW_MASK_ASC); - regs->psw.addr = (__u64 __force) ksig->ka.sa.sa_handler; - - regs->gprs[2] = ksig->sig; - regs->gprs[3] = (__force __u64) &frame->info; - regs->gprs[4] = (__force __u64) &frame->uc; - regs->gprs[5] = current->thread.last_break; - return 0; -} - -/* - * OK, we're invoking a handler - */ - -void handle_signal32(struct ksignal *ksig, sigset_t *oldset, - struct pt_regs *regs) -{ - int ret; - - /* Set up the stack frame */ - if (ksig->ka.sa.sa_flags & SA_SIGINFO) - ret = setup_rt_frame32(ksig, oldset, regs); - else - ret = setup_frame32(ksig, oldset, regs); - - signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLE_STEP)); -} - diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 75b0fbb236d0..3c7f183a945d 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -614,12 +614,3 @@ SYM_DATA_START(sys_call_table) #include SYM_DATA_END(sys_call_table) #undef SYSCALL - -#ifdef CONFIG_COMPAT - -#define SYSCALL(esame,emu) .quad __s390_ ## emu -SYM_DATA_START(sys_call_table_emu) -#include -SYM_DATA_END(sys_call_table_emu) -#undef SYSCALL -#endif diff --git a/arch/s390/kernel/perf_cpum_cf.c b/arch/s390/kernel/perf_cpum_cf.c index 04457d88e589..b7fa9712ee1e 100644 --- a/arch/s390/kernel/perf_cpum_cf.c +++ b/arch/s390/kernel/perf_cpum_cf.c @@ -1689,7 +1689,6 @@ static const struct file_operations cfset_fops = { .open = cfset_open, .release = cfset_release, .unlocked_ioctl = cfset_ioctl, - .compat_ioctl = cfset_ioctl, }; static struct miscdevice cfset_dev = { diff --git a/arch/s390/kernel/perf_event.c b/arch/s390/kernel/perf_event.c index 91b8716c883a..2de1574d95b2 100644 --- a/arch/s390/kernel/perf_event.c +++ b/arch/s390/kernel/perf_event.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/s390/kernel/perf_regs.c b/arch/s390/kernel/perf_regs.c index a6b058ee4a36..7b305f1456f8 100644 --- a/arch/s390/kernel/perf_regs.c +++ b/arch/s390/kernel/perf_regs.c @@ -44,9 +44,6 @@ int perf_reg_validate(u64 mask) u64 perf_reg_abi(struct task_struct *task) { - if (test_tsk_thread_flag(task, TIF_31BIT)) - return PERF_SAMPLE_REGS_ABI_32; - return PERF_SAMPLE_REGS_ABI_64; } diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index b107dbca4ed7..0df95dcb2101 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -166,12 +165,8 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) /* Set a new TLS ? */ if (clone_flags & CLONE_SETTLS) { - if (is_compat_task()) { - p->thread.acrs[0] = (unsigned int)tls; - } else { - p->thread.acrs[0] = (unsigned int)(tls >> 32); - p->thread.acrs[1] = (unsigned int)tls; - } + p->thread.acrs[0] = (unsigned int)(tls >> 32); + p->thread.acrs[1] = (unsigned int)tls; } /* * s390 stores the svc return address in arch_data when calling diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 494216c4b4f3..ceaa1726e328 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -38,10 +37,6 @@ #include "entry.h" -#ifdef CONFIG_COMPAT -#include "compat_ptrace.h" -#endif - void update_cr_regs(struct task_struct *task) { struct pt_regs *regs = task_pt_regs(task); @@ -507,308 +502,6 @@ long arch_ptrace(struct task_struct *child, long request, } } -#ifdef CONFIG_COMPAT -/* - * Now the fun part starts... a 31 bit program running in the - * 31 bit emulation tracing another program. PTRACE_PEEKTEXT, - * PTRACE_PEEKDATA, PTRACE_POKETEXT and PTRACE_POKEDATA are easy - * to handle, the difference to the 64 bit versions of the requests - * is that the access is done in multiples of 4 byte instead of - * 8 bytes (sizeof(unsigned long) on 31/64 bit). - * The ugly part are PTRACE_PEEKUSR, PTRACE_PEEKUSR_AREA, - * PTRACE_POKEUSR and PTRACE_POKEUSR_AREA. If the traced program - * is a 31 bit program too, the content of struct user can be - * emulated. A 31 bit program peeking into the struct user of - * a 64 bit program is a no-no. - */ - -/* - * Same as peek_user_per but for a 31 bit program. - */ -static inline __u32 __peek_user_per_compat(struct task_struct *child, - addr_t addr) -{ - if (addr == offsetof(struct compat_per_struct_kernel, cr9)) - /* Control bits of the active per set. */ - return (__u32) test_thread_flag(TIF_SINGLE_STEP) ? - PER_EVENT_IFETCH : child->thread.per_user.control; - else if (addr == offsetof(struct compat_per_struct_kernel, cr10)) - /* Start address of the active per set. */ - return (__u32) test_thread_flag(TIF_SINGLE_STEP) ? - 0 : child->thread.per_user.start; - else if (addr == offsetof(struct compat_per_struct_kernel, cr11)) - /* End address of the active per set. */ - return test_thread_flag(TIF_SINGLE_STEP) ? - PSW32_ADDR_INSN : child->thread.per_user.end; - else if (addr == offsetof(struct compat_per_struct_kernel, bits)) - /* Single-step bit. */ - return (__u32) test_thread_flag(TIF_SINGLE_STEP) ? - 0x80000000 : 0; - else if (addr == offsetof(struct compat_per_struct_kernel, starting_addr)) - /* Start address of the user specified per set. */ - return (__u32) child->thread.per_user.start; - else if (addr == offsetof(struct compat_per_struct_kernel, ending_addr)) - /* End address of the user specified per set. */ - return (__u32) child->thread.per_user.end; - else if (addr == offsetof(struct compat_per_struct_kernel, perc_atmid)) - /* PER code, ATMID and AI of the last PER trap */ - return (__u32) child->thread.per_event.cause << 16; - else if (addr == offsetof(struct compat_per_struct_kernel, address)) - /* Address of the last PER trap */ - return (__u32) child->thread.per_event.address; - else if (addr == offsetof(struct compat_per_struct_kernel, access_id)) - /* Access id of the last PER trap */ - return (__u32) child->thread.per_event.paid << 24; - return 0; -} - -/* - * Same as peek_user but for a 31 bit program. - */ -static u32 __peek_user_compat(struct task_struct *child, addr_t addr) -{ - addr_t offset; - __u32 tmp; - - if (addr < offsetof(struct compat_user, regs.acrs)) { - struct pt_regs *regs = task_pt_regs(child); - /* - * psw and gprs are stored on the stack - */ - if (addr == offsetof(struct compat_user, regs.psw.mask)) { - /* Fake a 31 bit psw mask. */ - tmp = (__u32)(regs->psw.mask >> 32); - tmp &= PSW32_MASK_USER | PSW32_MASK_RI; - tmp |= PSW32_USER_BITS; - } else if (addr == offsetof(struct compat_user, regs.psw.addr)) { - /* Fake a 31 bit psw address. */ - tmp = (__u32) regs->psw.addr | - (__u32)(regs->psw.mask & PSW_MASK_BA); - } else { - /* gpr 0-15 */ - tmp = *(__u32 *)((addr_t) ®s->psw + addr*2 + 4); - } - } else if (addr < offsetof(struct compat_user, regs.orig_gpr2)) { - /* - * access registers are stored in the thread structure - */ - offset = addr - offsetof(struct compat_user, regs.acrs); - tmp = *(__u32*)((addr_t) &child->thread.acrs + offset); - - } else if (addr == offsetof(struct compat_user, regs.orig_gpr2)) { - /* - * orig_gpr2 is stored on the kernel stack - */ - tmp = *(__u32*)((addr_t) &task_pt_regs(child)->orig_gpr2 + 4); - - } else if (addr < offsetof(struct compat_user, regs.fp_regs)) { - /* - * prevent reads of padding hole between - * orig_gpr2 and fp_regs on s390. - */ - tmp = 0; - - } else if (addr == offsetof(struct compat_user, regs.fp_regs.fpc)) { - /* - * floating point control reg. is in the thread structure - */ - tmp = child->thread.ufpu.fpc; - - } else if (addr < offsetof(struct compat_user, regs.fp_regs) + sizeof(s390_fp_regs)) { - /* - * floating point regs. are in the child->thread.ufpu.vxrs array - */ - offset = addr - offsetof(struct compat_user, regs.fp_regs.fprs); - tmp = *(__u32 *)((addr_t)child->thread.ufpu.vxrs + 2 * offset); - } else if (addr < offsetof(struct compat_user, regs.per_info) + sizeof(struct compat_per_struct_kernel)) { - /* - * Handle access to the per_info structure. - */ - addr -= offsetof(struct compat_user, regs.per_info); - tmp = __peek_user_per_compat(child, addr); - - } else - tmp = 0; - - return tmp; -} - -static int peek_user_compat(struct task_struct *child, - addr_t addr, addr_t data) -{ - __u32 tmp; - - if (!is_compat_task() || (addr & 3) || addr > sizeof(struct user) - 3) - return -EIO; - - tmp = __peek_user_compat(child, addr); - return put_user(tmp, (__u32 __user *) data); -} - -/* - * Same as poke_user_per but for a 31 bit program. - */ -static inline void __poke_user_per_compat(struct task_struct *child, - addr_t addr, __u32 data) -{ - if (addr == offsetof(struct compat_per_struct_kernel, cr9)) - /* PER event mask of the user specified per set. */ - child->thread.per_user.control = - data & (PER_EVENT_MASK | PER_CONTROL_MASK); - else if (addr == offsetof(struct compat_per_struct_kernel, starting_addr)) - /* Starting address of the user specified per set. */ - child->thread.per_user.start = data; - else if (addr == offsetof(struct compat_per_struct_kernel, ending_addr)) - /* Ending address of the user specified per set. */ - child->thread.per_user.end = data; -} - -/* - * Same as poke_user but for a 31 bit program. - */ -static int __poke_user_compat(struct task_struct *child, - addr_t addr, addr_t data) -{ - __u32 tmp = (__u32) data; - addr_t offset; - - if (addr < offsetof(struct compat_user, regs.acrs)) { - struct pt_regs *regs = task_pt_regs(child); - /* - * psw, gprs, acrs and orig_gpr2 are stored on the stack - */ - if (addr == offsetof(struct compat_user, regs.psw.mask)) { - __u32 mask = PSW32_MASK_USER; - - mask |= is_ri_task(child) ? PSW32_MASK_RI : 0; - /* Build a 64 bit psw mask from 31 bit mask. */ - if ((tmp ^ PSW32_USER_BITS) & ~mask) - /* Invalid psw mask. */ - return -EINVAL; - if ((data & PSW32_MASK_ASC) == PSW32_ASC_HOME) - /* Invalid address-space-control bits */ - return -EINVAL; - regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) | - (regs->psw.mask & PSW_MASK_BA) | - (__u64)(tmp & mask) << 32; - } else if (addr == offsetof(struct compat_user, regs.psw.addr)) { - /* Build a 64 bit psw address from 31 bit address. */ - regs->psw.addr = (__u64) tmp & PSW32_ADDR_INSN; - /* Transfer 31 bit amode bit to psw mask. */ - regs->psw.mask = (regs->psw.mask & ~PSW_MASK_BA) | - (__u64)(tmp & PSW32_ADDR_AMODE); - } else { - if (test_pt_regs_flag(regs, PIF_SYSCALL) && - addr == offsetof(struct compat_user, regs.gprs[2])) { - struct pt_regs *regs = task_pt_regs(child); - - regs->int_code = 0x20000 | (data & 0xffff); - } - /* gpr 0-15 */ - *(__u32*)((addr_t) ®s->psw + addr*2 + 4) = tmp; - } - } else if (addr < offsetof(struct compat_user, regs.orig_gpr2)) { - /* - * access registers are stored in the thread structure - */ - offset = addr - offsetof(struct compat_user, regs.acrs); - *(__u32*)((addr_t) &child->thread.acrs + offset) = tmp; - - } else if (addr == offsetof(struct compat_user, regs.orig_gpr2)) { - /* - * orig_gpr2 is stored on the kernel stack - */ - *(__u32*)((addr_t) &task_pt_regs(child)->orig_gpr2 + 4) = tmp; - - } else if (addr < offsetof(struct compat_user, regs.fp_regs)) { - /* - * prevent writess of padding hole between - * orig_gpr2 and fp_regs on s390. - */ - return 0; - - } else if (addr == offsetof(struct compat_user, regs.fp_regs.fpc)) { - /* - * floating point control reg. is in the thread structure - */ - child->thread.ufpu.fpc = data; - - } else if (addr < offsetof(struct compat_user, regs.fp_regs) + sizeof(s390_fp_regs)) { - /* - * floating point regs. are in the child->thread.ufpu.vxrs array - */ - offset = addr - offsetof(struct compat_user, regs.fp_regs.fprs); - *(__u32 *)((addr_t)child->thread.ufpu.vxrs + 2 * offset) = tmp; - } else if (addr < offsetof(struct compat_user, regs.per_info) + sizeof(struct compat_per_struct_kernel)) { - /* - * Handle access to the per_info structure. - */ - addr -= offsetof(struct compat_user, regs.per_info); - __poke_user_per_compat(child, addr, data); - } - - return 0; -} - -static int poke_user_compat(struct task_struct *child, - addr_t addr, addr_t data) -{ - if (!is_compat_task() || (addr & 3) || - addr > sizeof(struct compat_user) - 3) - return -EIO; - - return __poke_user_compat(child, addr, data); -} - -long compat_arch_ptrace(struct task_struct *child, compat_long_t request, - compat_ulong_t caddr, compat_ulong_t cdata) -{ - unsigned long addr = caddr; - unsigned long data = cdata; - compat_ptrace_area parea; - int copied, ret; - - switch (request) { - case PTRACE_PEEKUSR: - /* read the word at location addr in the USER area. */ - return peek_user_compat(child, addr, data); - - case PTRACE_POKEUSR: - /* write the word at location addr in the USER area */ - return poke_user_compat(child, addr, data); - - case PTRACE_PEEKUSR_AREA: - case PTRACE_POKEUSR_AREA: - if (copy_from_user(&parea, (void __force __user *) addr, - sizeof(parea))) - return -EFAULT; - addr = parea.kernel_addr; - data = parea.process_addr; - copied = 0; - while (copied < parea.len) { - if (request == PTRACE_PEEKUSR_AREA) - ret = peek_user_compat(child, addr, data); - else { - __u32 utmp; - if (get_user(utmp, - (__u32 __force __user *) data)) - return -EFAULT; - ret = poke_user_compat(child, addr, utmp); - } - if (ret) - return ret; - addr += sizeof(unsigned int); - data += sizeof(unsigned int); - copied += sizeof(unsigned int); - } - return 0; - case PTRACE_GET_LAST_BREAK: - return put_user(child->thread.last_break, (unsigned int __user *)data); - } - return compat_ptrace_request(child, request, addr, data); -} -#endif - /* * user_regset definitions. */ @@ -1297,225 +990,8 @@ static const struct user_regset_view user_s390_view = { .n = ARRAY_SIZE(s390_regsets) }; -#ifdef CONFIG_COMPAT -static int s390_compat_regs_get(struct task_struct *target, - const struct user_regset *regset, - struct membuf to) -{ - unsigned n; - - if (target == current) - save_access_regs(target->thread.acrs); - - for (n = 0; n < sizeof(s390_compat_regs); n += sizeof(compat_ulong_t)) - membuf_store(&to, __peek_user_compat(target, n)); - return 0; -} - -static int s390_compat_regs_set(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - const void *kbuf, const void __user *ubuf) -{ - int rc = 0; - - if (target == current) - save_access_regs(target->thread.acrs); - - if (kbuf) { - const compat_ulong_t *k = kbuf; - while (count > 0 && !rc) { - rc = __poke_user_compat(target, pos, *k++); - count -= sizeof(*k); - pos += sizeof(*k); - } - } else { - const compat_ulong_t __user *u = ubuf; - while (count > 0 && !rc) { - compat_ulong_t word; - rc = __get_user(word, u++); - if (rc) - break; - rc = __poke_user_compat(target, pos, word); - count -= sizeof(*u); - pos += sizeof(*u); - } - } - - if (rc == 0 && target == current) - restore_access_regs(target->thread.acrs); - - return rc; -} - -static int s390_compat_regs_high_get(struct task_struct *target, - const struct user_regset *regset, - struct membuf to) -{ - compat_ulong_t *gprs_high; - int i; - - gprs_high = (compat_ulong_t *)task_pt_regs(target)->gprs; - for (i = 0; i < NUM_GPRS; i++, gprs_high += 2) - membuf_store(&to, *gprs_high); - return 0; -} - -static int s390_compat_regs_high_set(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - const void *kbuf, const void __user *ubuf) -{ - compat_ulong_t *gprs_high; - int rc = 0; - - gprs_high = (compat_ulong_t *) - &task_pt_regs(target)->gprs[pos / sizeof(compat_ulong_t)]; - if (kbuf) { - const compat_ulong_t *k = kbuf; - while (count > 0) { - *gprs_high = *k++; - *gprs_high += 2; - count -= sizeof(*k); - } - } else { - const compat_ulong_t __user *u = ubuf; - while (count > 0 && !rc) { - unsigned long word; - rc = __get_user(word, u++); - if (rc) - break; - *gprs_high = word; - *gprs_high += 2; - count -= sizeof(*u); - } - } - - return rc; -} - -static int s390_compat_last_break_get(struct task_struct *target, - const struct user_regset *regset, - struct membuf to) -{ - compat_ulong_t last_break = target->thread.last_break; - - return membuf_store(&to, (unsigned long)last_break); -} - -static int s390_compat_last_break_set(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - const void *kbuf, const void __user *ubuf) -{ - return 0; -} - -static const struct user_regset s390_compat_regsets[] = { - { - USER_REGSET_NOTE_TYPE(PRSTATUS), - .n = sizeof(s390_compat_regs) / sizeof(compat_long_t), - .size = sizeof(compat_long_t), - .align = sizeof(compat_long_t), - .regset_get = s390_compat_regs_get, - .set = s390_compat_regs_set, - }, - { - USER_REGSET_NOTE_TYPE(PRFPREG), - .n = sizeof(s390_fp_regs) / sizeof(compat_long_t), - .size = sizeof(compat_long_t), - .align = sizeof(compat_long_t), - .regset_get = s390_fpregs_get, - .set = s390_fpregs_set, - }, - { - USER_REGSET_NOTE_TYPE(S390_SYSTEM_CALL), - .n = 1, - .size = sizeof(compat_uint_t), - .align = sizeof(compat_uint_t), - .regset_get = s390_system_call_get, - .set = s390_system_call_set, - }, - { - USER_REGSET_NOTE_TYPE(S390_LAST_BREAK), - .n = 1, - .size = sizeof(long), - .align = sizeof(long), - .regset_get = s390_compat_last_break_get, - .set = s390_compat_last_break_set, - }, - { - USER_REGSET_NOTE_TYPE(S390_TDB), - .n = 1, - .size = 256, - .align = 1, - .regset_get = s390_tdb_get, - .set = s390_tdb_set, - }, - { - USER_REGSET_NOTE_TYPE(S390_VXRS_LOW), - .n = __NUM_VXRS_LOW, - .size = sizeof(__u64), - .align = sizeof(__u64), - .regset_get = s390_vxrs_low_get, - .set = s390_vxrs_low_set, - }, - { - USER_REGSET_NOTE_TYPE(S390_VXRS_HIGH), - .n = __NUM_VXRS_HIGH, - .size = sizeof(__vector128), - .align = sizeof(__vector128), - .regset_get = s390_vxrs_high_get, - .set = s390_vxrs_high_set, - }, - { - USER_REGSET_NOTE_TYPE(S390_HIGH_GPRS), - .n = sizeof(s390_compat_regs_high) / sizeof(compat_long_t), - .size = sizeof(compat_long_t), - .align = sizeof(compat_long_t), - .regset_get = s390_compat_regs_high_get, - .set = s390_compat_regs_high_set, - }, - { - USER_REGSET_NOTE_TYPE(S390_GS_CB), - .n = sizeof(struct gs_cb) / sizeof(__u64), - .size = sizeof(__u64), - .align = sizeof(__u64), - .regset_get = s390_gs_cb_get, - .set = s390_gs_cb_set, - }, - { - USER_REGSET_NOTE_TYPE(S390_GS_BC), - .n = sizeof(struct gs_cb) / sizeof(__u64), - .size = sizeof(__u64), - .align = sizeof(__u64), - .regset_get = s390_gs_bc_get, - .set = s390_gs_bc_set, - }, - { - USER_REGSET_NOTE_TYPE(S390_RI_CB), - .n = sizeof(struct runtime_instr_cb) / sizeof(__u64), - .size = sizeof(__u64), - .align = sizeof(__u64), - .regset_get = s390_runtime_instr_get, - .set = s390_runtime_instr_set, - }, -}; - -static const struct user_regset_view user_s390_compat_view = { - .name = "s390", - .e_machine = EM_S390, - .regsets = s390_compat_regsets, - .n = ARRAY_SIZE(s390_compat_regsets) -}; -#endif - const struct user_regset_view *task_user_regset_view(struct task_struct *task) { -#ifdef CONFIG_COMPAT - if (test_tsk_thread_flag(task, TIF_31BIT)) - return &user_s390_compat_view; -#endif return &user_s390_view; } diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 892fce2b7549..3c50246dc8c5 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -47,7 +47,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index e48013cd832c..e7775d121fa1 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -290,12 +289,6 @@ static int setup_frame(int sig, struct k_sigaction *ka, unsigned long restorer; size_t frame_size; - /* - * gprs_high are only present for a 31-bit task running on - * a 64-bit kernel (see compat_signal.c) but the space for - * gprs_high need to be allocated if vector registers are - * included in the signal frame on a 31-bit system. - */ frame_size = sizeof(*frame) - sizeof(frame->sregs_ext); if (cpu_has_vx()) frame_size += sizeof(frame->sregs_ext); @@ -367,12 +360,6 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set, size_t frame_size; frame_size = sizeof(struct rt_sigframe) - sizeof(_sigregs_ext); - /* - * gprs_high are only present for a 31-bit task running on - * a 64-bit kernel (see compat_signal.c) but the space for - * gprs_high need to be allocated if vector registers are - * included in the signal frame on a 31-bit system. - */ uc_flags = 0; if (cpu_has_vx()) { frame_size += sizeof(_sigregs_ext); @@ -490,10 +477,7 @@ void arch_do_signal_or_restart(struct pt_regs *regs) clear_pt_regs_flag(regs, PIF_SYSCALL); rseq_signal_deliver(&ksig, regs); - if (is_compat_task()) - handle_signal32(&ksig, oldset, regs); - else - handle_signal(&ksig, oldset, regs); + handle_signal(&ksig, oldset, regs); return; } @@ -506,10 +490,7 @@ void arch_do_signal_or_restart(struct pt_regs *regs) /* Restart with sys_restart_syscall */ regs->gprs[2] = regs->orig_gpr2; current->restart_block.arch_data = regs->psw.addr; - if (is_compat_task()) - regs->psw.addr = VDSO32_SYMBOL(current, restart_syscall); - else - regs->psw.addr = VDSO64_SYMBOL(current, restart_syscall); + regs->psw.addr = VDSO64_SYMBOL(current, restart_syscall); if (test_thread_flag(TIF_SINGLE_STEP)) clear_thread_flag(TIF_PER_TRAP); break; diff --git a/arch/s390/kernel/stacktrace.c b/arch/s390/kernel/stacktrace.c index b153a395f46d..3aae7f70e6ab 100644 --- a/arch/s390/kernel/stacktrace.c +++ b/arch/s390/kernel/stacktrace.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include @@ -107,8 +106,6 @@ void arch_stack_walk_user_common(stack_trace_consume_fn consume_entry, void *coo unsigned long ip, sp; bool first = true; - if (is_compat_task()) - return; if (!current->mm) return; ip = instruction_pointer(regs); diff --git a/arch/s390/kernel/uprobes.c b/arch/s390/kernel/uprobes.c index a91b4fd01bf4..c624f3361e43 100644 --- a/arch/s390/kernel/uprobes.c +++ b/arch/s390/kernel/uprobes.c @@ -8,7 +8,6 @@ #include #include -#include #include #include @@ -29,7 +28,7 @@ int arch_uprobe_pre_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) { if (psw_bits(regs->psw).eaba == PSW_BITS_AMODE_24BIT) return -EINVAL; - if (!is_compat_task() && psw_bits(regs->psw).eaba == PSW_BITS_AMODE_31BIT) + if (psw_bits(regs->psw).eaba == PSW_BITS_AMODE_31BIT) return -EINVAL; clear_thread_flag(TIF_PER_TRAP); auprobe->saved_per = psw_bits(regs->psw).per; @@ -368,8 +367,7 @@ static void handle_insn_ril(struct arch_uprobe *auprobe, struct pt_regs *regs) bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs) { if ((psw_bits(regs->psw).eaba == PSW_BITS_AMODE_24BIT) || - ((psw_bits(regs->psw).eaba == PSW_BITS_AMODE_31BIT) && - !is_compat_task())) { + (psw_bits(regs->psw).eaba == PSW_BITS_AMODE_31BIT)) { regs->psw.addr = __rewind_psw(regs->psw, UPROBE_SWBP_INSN_SIZE); do_report_trap(regs, SIGILL, ILL_ILLADR, NULL); return true; diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c index 430feb1a5013..83cc67cf21c8 100644 --- a/arch/s390/kernel/vdso.c +++ b/arch/s390/kernel/vdso.c @@ -7,7 +7,6 @@ */ #include -#include #include #include #include @@ -24,7 +23,6 @@ #include extern char vdso64_start[], vdso64_end[]; -extern char vdso32_start[], vdso32_end[]; static int vdso_mremap(const struct vm_special_mapping *sm, struct vm_area_struct *vma) @@ -38,11 +36,6 @@ static struct vm_special_mapping vdso64_mapping = { .mremap = vdso_mremap, }; -static struct vm_special_mapping vdso32_mapping = { - .name = "[vdso]", - .mremap = vdso_mremap, -}; - int vdso_getcpu_init(void) { set_tod_programmable_field(smp_processor_id()); @@ -62,13 +55,8 @@ static int map_vdso(unsigned long addr, unsigned long vdso_mapping_len) if (mmap_write_lock_killable(mm)) return -EINTR; - if (is_compat_task()) { - vdso_text_len = vdso32_end - vdso32_start; - vdso_mapping = &vdso32_mapping; - } else { - vdso_text_len = vdso64_end - vdso64_start; - vdso_mapping = &vdso64_mapping; - } + vdso_text_len = vdso64_end - vdso64_start; + vdso_mapping = &vdso64_mapping; vvar_start = get_unmapped_area(NULL, addr, vdso_mapping_len, 0, 0); rc = vvar_start; if (IS_ERR_VALUE(vvar_start)) @@ -122,13 +110,7 @@ static unsigned long vdso_addr(unsigned long start, unsigned long len) unsigned long vdso_text_size(void) { - unsigned long size; - - if (is_compat_task()) - size = vdso32_end - vdso32_start; - else - size = vdso64_end - vdso64_start; - return PAGE_ALIGN(size); + return PAGE_ALIGN(vdso64_end - vdso64_start); } unsigned long vdso_size(void) @@ -180,8 +162,6 @@ static int __init vdso_init(void) { vdso_apply_alternatives(); vdso64_mapping.pages = vdso_setup_pages(vdso64_start, vdso64_end); - if (IS_ENABLED(CONFIG_COMPAT)) - vdso32_mapping.pages = vdso_setup_pages(vdso32_start, vdso32_end); return 0; } arch_initcall(vdso_init); diff --git a/arch/s390/kernel/vdso32/.gitignore b/arch/s390/kernel/vdso32/.gitignore deleted file mode 100644 index 5167384843b9..000000000000 --- a/arch/s390/kernel/vdso32/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -vdso32.lds diff --git a/arch/s390/kernel/vdso32/Makefile b/arch/s390/kernel/vdso32/Makefile deleted file mode 100644 index 1e4ddd1a683f..000000000000 --- a/arch/s390/kernel/vdso32/Makefile +++ /dev/null @@ -1,64 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# List of files in the vdso - -# Include the generic Makefile to check the built vdso. -include $(srctree)/lib/vdso/Makefile.include -obj-vdso32 = vdso_user_wrapper-32.o note-32.o - -# Build rules - -targets := $(obj-vdso32) vdso32.so vdso32.so.dbg -obj-vdso32 := $(addprefix $(obj)/, $(obj-vdso32)) - -KBUILD_AFLAGS += -DBUILD_VDSO -KBUILD_CFLAGS += -DBUILD_VDSO -DDISABLE_BRANCH_PROFILING - -KBUILD_AFLAGS_32 := $(filter-out -m64,$(KBUILD_AFLAGS)) -KBUILD_AFLAGS_32 += -m31 -s - -KBUILD_CFLAGS_32 := $(filter-out -m64,$(KBUILD_CFLAGS)) -KBUILD_CFLAGS_32 := $(filter-out -mpacked-stack,$(KBUILD_CFLAGS)) -KBUILD_CFLAGS_32 := $(filter-out -mno-pic-data-is-text-relative,$(KBUILD_CFLAGS_32)) -KBUILD_CFLAGS_32 := $(filter-out -fno-asynchronous-unwind-tables,$(KBUILD_CFLAGS_32)) -KBUILD_CFLAGS_32 += -m31 -fPIC -shared -fno-common -fno-builtin -fasynchronous-unwind-tables - -LDFLAGS_vdso32.so.dbg += -shared -soname=linux-vdso32.so.1 \ - --hash-style=both --build-id=sha1 -melf_s390 -T - -$(targets:%=$(obj)/%.dbg): KBUILD_CFLAGS = $(KBUILD_CFLAGS_32) -$(targets:%=$(obj)/%.dbg): KBUILD_AFLAGS = $(KBUILD_AFLAGS_32) - -obj-y += vdso32_wrapper.o -targets += vdso32.lds -CPPFLAGS_vdso32.lds += -P -C -U$(ARCH) - -# Force dependency (incbin is bad) -$(obj)/vdso32_wrapper.o : $(obj)/vdso32.so - -quiet_cmd_vdso_and_check = VDSO $@ - cmd_vdso_and_check = $(cmd_ld); $(cmd_vdso_check) - -$(obj)/vdso32.so.dbg: $(obj)/vdso32.lds $(obj-vdso32) FORCE - $(call if_changed,vdso_and_check) - -# strip rule for the .so file -$(obj)/%.so: OBJCOPYFLAGS := -S -$(obj)/%.so: $(obj)/%.so.dbg FORCE - $(call if_changed,objcopy) - -$(obj-vdso32): %-32.o: %.S FORCE - $(call if_changed_dep,vdso32as) - -# actual build commands -quiet_cmd_vdso32as = VDSO32A $@ - cmd_vdso32as = $(CC) $(a_flags) -c -o $@ $< -quiet_cmd_vdso32cc = VDSO32C $@ - cmd_vdso32cc = $(CC) $(c_flags) -c -o $@ $< - -# Generate VDSO offsets using helper script -gen-vdsosym := $(src)/gen_vdso_offsets.sh -quiet_cmd_vdsosym = VDSOSYM $@ - cmd_vdsosym = $(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@ - -include/generated/vdso32-offsets.h: $(obj)/vdso32.so.dbg FORCE - $(call if_changed,vdsosym) diff --git a/arch/s390/kernel/vdso32/gen_vdso_offsets.sh b/arch/s390/kernel/vdso32/gen_vdso_offsets.sh deleted file mode 100755 index 9c4f951e227d..000000000000 --- a/arch/s390/kernel/vdso32/gen_vdso_offsets.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh -# SPDX-License-Identifier: GPL-2.0 - -# -# Match symbols in the DSO that look like VDSO_*; produce a header file -# of constant offsets into the shared object. -# -# Doing this inside the Makefile will break the $(filter-out) function, -# causing Kbuild to rebuild the vdso-offsets header file every time. -# -# Inspired by arm64 version. -# - -LC_ALL=C -sed -n 's/\([0-9a-f]*\) . __kernel_compat_\(.*\)/\#define vdso32_offset_\2\t0x\1/p' diff --git a/arch/s390/kernel/vdso32/note.S b/arch/s390/kernel/vdso32/note.S deleted file mode 100644 index db19d0680a0a..000000000000 --- a/arch/s390/kernel/vdso32/note.S +++ /dev/null @@ -1,13 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * This supplies .note.* sections to go into the PT_NOTE inside the vDSO text. - * Here we can supply some information useful to userland. - */ - -#include -#include -#include - -ELFNOTE_START(Linux, 0, "a") - .long LINUX_VERSION_CODE -ELFNOTE_END diff --git a/arch/s390/kernel/vdso32/vdso32.lds.S b/arch/s390/kernel/vdso32/vdso32.lds.S deleted file mode 100644 index 9630d58c2080..000000000000 --- a/arch/s390/kernel/vdso32/vdso32.lds.S +++ /dev/null @@ -1,140 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * This is the infamous ld script for the 64 bits vdso - * library - */ - -#include -#include -#include - -OUTPUT_FORMAT("elf32-s390", "elf32-s390", "elf32-s390") -OUTPUT_ARCH(s390:31-bit) - -SECTIONS -{ - VDSO_VVAR_SYMS - - . = SIZEOF_HEADERS; - - .hash : { *(.hash) } :text - .gnu.hash : { *(.gnu.hash) } - .dynsym : { *(.dynsym) } - .dynstr : { *(.dynstr) } - .gnu.version : { *(.gnu.version) } - .gnu.version_d : { *(.gnu.version_d) } - .gnu.version_r : { *(.gnu.version_r) } - - .note : { *(.note.*) } :text :note - - . = ALIGN(16); - .text : { - *(.text .stub .text.* .gnu.linkonce.t.*) - } :text - PROVIDE(__etext = .); - PROVIDE(_etext = .); - PROVIDE(etext = .); - - /* - * Other stuff is appended to the text segment: - */ - .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } - .rodata1 : { *(.rodata1) } - - .dynamic : { *(.dynamic) } :text :dynamic - - .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr - .eh_frame : { KEEP (*(.eh_frame)) } :text - .gcc_except_table : { *(.gcc_except_table .gcc_except_table.*) } - - .rela.dyn ALIGN(8) : { *(.rela.dyn) } - .got ALIGN(8) : { *(.got .toc) } - .got.plt ALIGN(8) : { *(.got.plt) } - - _end = .; - PROVIDE(end = .); - - /* - * Stabs debugging sections are here too. - */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } - - /* - * DWARF debug sections. - * Symbols in the DWARF debugging sections are relative to the - * beginning of the section so we begin them at 0. - */ - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } - /* DWARF 3 */ - .debug_pubtypes 0 : { *(.debug_pubtypes) } - .debug_ranges 0 : { *(.debug_ranges) } - .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) } - - /DISCARD/ : { - *(.note.GNU-stack) - *(.branch_lt) - *(.data .data.* .gnu.linkonce.d.* .sdata*) - *(.bss .sbss .dynbss .dynsbss) - } -} - -/* - * Very old versions of ld do not recognize this name token; use the constant. - */ -#define PT_GNU_EH_FRAME 0x6474e550 - -/* - * We must supply the ELF program headers explicitly to get just one - * PT_LOAD segment, and set the flags explicitly to make segments read-only. - */ -PHDRS -{ - text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */ - dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ - note PT_NOTE FLAGS(4); /* PF_R */ - eh_frame_hdr PT_GNU_EH_FRAME; -} - -/* - * This controls what symbols we export from the DSO. - */ -VERSION -{ - VDSO_VERSION_STRING { - global: - /* - * Has to be there for the kernel to find - */ - __kernel_compat_restart_syscall; - __kernel_compat_rt_sigreturn; - __kernel_compat_sigreturn; - local: *; - }; -} diff --git a/arch/s390/kernel/vdso32/vdso32_wrapper.S b/arch/s390/kernel/vdso32/vdso32_wrapper.S deleted file mode 100644 index de2fb930471a..000000000000 --- a/arch/s390/kernel/vdso32/vdso32_wrapper.S +++ /dev/null @@ -1,15 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#include -#include -#include - - __PAGE_ALIGNED_DATA - - .globl vdso32_start, vdso32_end - .balign PAGE_SIZE -vdso32_start: - .incbin "arch/s390/kernel/vdso32/vdso32.so" - .balign PAGE_SIZE -vdso32_end: - - .previous diff --git a/arch/s390/kernel/vdso32/vdso_user_wrapper.S b/arch/s390/kernel/vdso32/vdso_user_wrapper.S deleted file mode 100644 index 2e645003fdaf..000000000000 --- a/arch/s390/kernel/vdso32/vdso_user_wrapper.S +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ - -#include -#include -#include - -.macro vdso_syscall func,syscall - .globl __kernel_compat_\func - .type __kernel_compat_\func,@function - __ALIGN -__kernel_compat_\func: - CFI_STARTPROC - svc \syscall - /* Make sure we notice when a syscall returns, which shouldn't happen */ - .word 0 - CFI_ENDPROC - .size __kernel_compat_\func,.-__kernel_compat_\func -.endm - -vdso_syscall restart_syscall,__NR_restart_syscall -vdso_syscall sigreturn,__NR_sigreturn -vdso_syscall rt_sigreturn,__NR_rt_sigreturn diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index a8c9aeee632b..e2e13778c36a 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c index 197c1d9497a7..2a222a7e14f4 100644 --- a/arch/s390/mm/mmap.c +++ b/arch/s390/mm/mmap.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/s390/pci/pci_clp.c b/arch/s390/pci/pci_clp.c index 241f7251c873..02b73d4b6c7e 100644 --- a/arch/s390/pci/pci_clp.c +++ b/arch/s390/pci/pci_clp.c @@ -9,7 +9,6 @@ #define KMSG_COMPONENT "zpci" #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt -#include #include #include #include @@ -651,7 +650,7 @@ static long clp_misc_ioctl(struct file *filp, unsigned int cmd, if (cmd != CLP_SYNC) return -EINVAL; - argp = is_compat_task() ? compat_ptr(arg) : (void __user *) arg; + argp = (void __user *)arg; if (copy_from_user(&req, argp, sizeof(req))) return -EFAULT; if (req.r != 0) @@ -669,7 +668,6 @@ static const struct file_operations clp_misc_fops = { .open = nonseekable_open, .release = clp_misc_release, .unlocked_ioctl = clp_misc_ioctl, - .compat_ioctl = clp_misc_ioctl, }; static struct miscdevice clp_misc_device = { diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 7765e40f7cea..2f3039cca6f2 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -3350,7 +3350,6 @@ dasd_device_operations = { .open = dasd_open, .release = dasd_release, .ioctl = dasd_ioctl, - .compat_ioctl = dasd_ioctl, .getgeo = dasd_getgeo, .set_read_only = dasd_set_read_only, }; diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 88fa17aea2ec..687396703788 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c @@ -16,7 +16,6 @@ #include /* HDIO_GETGEO */ #include #include -#include #include #include #include @@ -5389,16 +5388,6 @@ static int dasd_symm_io(struct dasd_device *device, void __user *argp) rc = -EFAULT; if (copy_from_user(&usrparm, argp, sizeof(usrparm))) goto out; - if (is_compat_task()) { - /* Make sure pointers are sane even on 31 bit. */ - rc = -EINVAL; - if ((usrparm.psf_data >> 32) != 0) - goto out; - if ((usrparm.rssd_result >> 32) != 0) - goto out; - usrparm.psf_data &= 0x7fffffffULL; - usrparm.rssd_result &= 0x7fffffffULL; - } /* at least 2 bytes are accessed and should be allocated */ if (usrparm.psf_data_len < 2) { DBF_DEV_EVENT(DBF_WARNING, device, diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c index 8308046a9f8f..f883990be626 100644 --- a/drivers/s390/block/dasd_ioctl.c +++ b/drivers/s390/block/dasd_ioctl.c @@ -11,7 +11,6 @@ */ #include -#include #include #include #include @@ -616,10 +615,7 @@ int dasd_ioctl(struct block_device *bdev, blk_mode_t mode, void __user *argp; int rc; - if (is_compat_task()) - argp = compat_ptr(arg); - else - argp = (void __user *)arg; + argp = (void __user *)arg; if ((_IOC_DIR(cmd) != _IOC_NONE) && !arg) return -EINVAL; diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c index 5a505972e571..4a7c084e68a6 100644 --- a/drivers/s390/char/con3270.c +++ b/drivers/s390/char/con3270.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include @@ -1947,21 +1946,6 @@ static int tty3270_ioctl(struct tty_struct *tty, unsigned int cmd, return kbd_ioctl(tp->kbd, cmd, arg); } -#ifdef CONFIG_COMPAT -static long tty3270_compat_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct tty3270 *tp; - - tp = tty->driver_data; - if (!tp) - return -ENODEV; - if (tty_io_error(tty)) - return -EIO; - return kbd_ioctl(tp->kbd, cmd, (unsigned long)compat_ptr(arg)); -} -#endif - static const struct tty_operations tty3270_ops = { .install = tty3270_install, .cleanup = tty3270_cleanup, @@ -1976,9 +1960,6 @@ static const struct tty_operations tty3270_ops = { .hangup = tty3270_hangup, .wait_until_sent = tty3270_wait_until_sent, .ioctl = tty3270_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = tty3270_compat_ioctl, -#endif .set_termios = tty3270_set_termios }; diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c index cfe7efd5b5da..73555dbe30d0 100644 --- a/drivers/s390/char/fs3270.c +++ b/drivers/s390/char/fs3270.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -330,10 +329,7 @@ static long fs3270_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) fp = filp->private_data; if (!fp) return -ENODEV; - if (is_compat_task()) - argp = compat_ptr(arg); - else - argp = (char __user *)arg; + argp = (char __user *)arg; rc = 0; mutex_lock(&fs3270_mutex); switch (cmd) { @@ -512,7 +508,6 @@ static const struct file_operations fs3270_fops = { .read = fs3270_read, /* read */ .write = fs3270_write, /* write */ .unlocked_ioctl = fs3270_ioctl, /* ioctl */ - .compat_ioctl = fs3270_ioctl, /* ioctl */ .open = fs3270_open, /* open */ .release = fs3270_close, /* release */ }; diff --git a/drivers/s390/char/sclp_ctl.c b/drivers/s390/char/sclp_ctl.c index dd6051602070..e23a97359286 100644 --- a/drivers/s390/char/sclp_ctl.c +++ b/drivers/s390/char/sclp_ctl.c @@ -7,7 +7,6 @@ * Author: Michael Holzheu */ -#include #include #include #include @@ -43,10 +42,7 @@ static int sclp_ctl_cmdw_supported(unsigned int cmdw) static void __user *u64_to_uptr(u64 value) { - if (is_compat_task()) - return compat_ptr(value); - else - return (void __user *)(unsigned long)value; + return (void __user *)(unsigned long)value; } /* @@ -95,10 +91,7 @@ static long sclp_ctl_ioctl(struct file *filp, unsigned int cmd, { void __user *argp; - if (is_compat_task()) - argp = compat_ptr(arg); - else - argp = (void __user *) arg; + argp = (void __user *)arg; switch (cmd) { case SCLP_CTL_SCCB: return sclp_ctl_ioctl_sccb(argp); @@ -114,7 +107,6 @@ static const struct file_operations sclp_ctl_fops = { .owner = THIS_MODULE, .open = nonseekable_open, .unlocked_ioctl = sclp_ctl_ioctl, - .compat_ioctl = sclp_ctl_ioctl, }; /* diff --git a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c index 5bcb22d9e47a..4f175474335e 100644 --- a/drivers/s390/char/tape_char.c +++ b/drivers/s390/char/tape_char.c @@ -17,7 +17,6 @@ #include #include #include -#include #include @@ -37,9 +36,6 @@ static ssize_t tapechar_write(struct file *, const char __user *, size_t, loff_t static int tapechar_open(struct inode *,struct file *); static int tapechar_release(struct inode *,struct file *); static long tapechar_ioctl(struct file *, unsigned int, unsigned long); -#ifdef CONFIG_COMPAT -static long tapechar_compat_ioctl(struct file *, unsigned int, unsigned long); -#endif static const struct file_operations tape_fops = { @@ -47,9 +43,6 @@ static const struct file_operations tape_fops = .read = tapechar_read, .write = tapechar_write, .unlocked_ioctl = tapechar_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = tapechar_compat_ioctl, -#endif .open = tapechar_open, .release = tapechar_release, }; @@ -441,25 +434,6 @@ tapechar_ioctl(struct file *filp, unsigned int no, unsigned long data) return rc; } -#ifdef CONFIG_COMPAT -static long -tapechar_compat_ioctl(struct file *filp, unsigned int no, unsigned long data) -{ - struct tape_device *device = filp->private_data; - long rc; - - if (no == MTIOCPOS32) - no = MTIOCPOS; - else if (no == MTIOCGET32) - no = MTIOCGET; - - mutex_lock(&device->mutex); - rc = __tapechar_ioctl(device, no, compat_ptr(data)); - mutex_unlock(&device->mutex); - return rc; -} -#endif /* CONFIG_COMPAT */ - /* * Initialize character device frontend. */ diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c index 69899bb86b3e..bde6c9e59166 100644 --- a/drivers/s390/char/vmcp.c +++ b/drivers/s390/char/vmcp.c @@ -14,7 +14,6 @@ #include #include -#include #include #include #include @@ -204,10 +203,7 @@ static long vmcp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) int __user *argp; session = file->private_data; - if (is_compat_task()) - argp = compat_ptr(arg); - else - argp = (int __user *)arg; + argp = (int __user *)arg; if (mutex_lock_interruptible(&session->mutex)) return -ERESTARTSYS; switch (cmd) { @@ -241,7 +237,6 @@ static const struct file_operations vmcp_fops = { .read = vmcp_read, .write = vmcp_write, .unlocked_ioctl = vmcp_ioctl, - .compat_ioctl = vmcp_ioctl, }; static struct miscdevice vmcp_dev = { diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c index 1e58ee3cc87d..ce992b2107cb 100644 --- a/drivers/s390/cio/chsc_sch.c +++ b/drivers/s390/cio/chsc_sch.c @@ -9,7 +9,6 @@ */ #include -#include #include #include #include @@ -845,10 +844,7 @@ static long chsc_ioctl(struct file *filp, unsigned int cmd, void __user *argp; CHSC_MSG(2, "chsc_ioctl called, cmd=%x\n", cmd); - if (is_compat_task()) - argp = compat_ptr(arg); - else - argp = (void __user *)arg; + argp = (void __user *)arg; switch (cmd) { case CHSC_START: return chsc_ioctl_start(argp); @@ -923,7 +919,6 @@ static const struct file_operations chsc_fops = { .open = chsc_open, .release = chsc_release, .unlocked_ioctl = chsc_ioctl, - .compat_ioctl = chsc_ioctl, }; static struct miscdevice chsc_misc_device = { diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c index 2b67b6b02ad5..351934f818de 100644 --- a/drivers/s390/crypto/zcrypt_api.c +++ b/drivers/s390/crypto/zcrypt_api.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -1734,197 +1733,6 @@ static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd, } } -#ifdef CONFIG_COMPAT -/* - * ioctl32 conversion routines - */ -struct compat_ica_rsa_modexpo { - compat_uptr_t inputdata; - unsigned int inputdatalength; - compat_uptr_t outputdata; - unsigned int outputdatalength; - compat_uptr_t b_key; - compat_uptr_t n_modulus; -}; - -static long trans_modexpo32(struct ap_perms *perms, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - struct compat_ica_rsa_modexpo __user *umex32 = compat_ptr(arg); - struct compat_ica_rsa_modexpo mex32; - struct ica_rsa_modexpo mex64; - struct zcrypt_track tr; - long rc; - - memset(&tr, 0, sizeof(tr)); - if (copy_from_user(&mex32, umex32, sizeof(mex32))) - return -EFAULT; - mex64.inputdata = compat_ptr(mex32.inputdata); - mex64.inputdatalength = mex32.inputdatalength; - mex64.outputdata = compat_ptr(mex32.outputdata); - mex64.outputdatalength = mex32.outputdatalength; - mex64.b_key = compat_ptr(mex32.b_key); - mex64.n_modulus = compat_ptr(mex32.n_modulus); - do { - rc = zcrypt_rsa_modexpo(perms, &tr, &mex64); - } while (rc == -EAGAIN && ++tr.again_counter < TRACK_AGAIN_MAX); - - /* on ENODEV failure: retry once again after a requested rescan */ - if (rc == -ENODEV && zcrypt_process_rescan()) - do { - rc = zcrypt_rsa_modexpo(perms, &tr, &mex64); - } while (rc == -EAGAIN && ++tr.again_counter < TRACK_AGAIN_MAX); - if (rc == -EAGAIN && tr.again_counter >= TRACK_AGAIN_MAX) - rc = -EIO; - if (rc) - return rc; - return put_user(mex64.outputdatalength, - &umex32->outputdatalength); -} - -struct compat_ica_rsa_modexpo_crt { - compat_uptr_t inputdata; - unsigned int inputdatalength; - compat_uptr_t outputdata; - unsigned int outputdatalength; - compat_uptr_t bp_key; - compat_uptr_t bq_key; - compat_uptr_t np_prime; - compat_uptr_t nq_prime; - compat_uptr_t u_mult_inv; -}; - -static long trans_modexpo_crt32(struct ap_perms *perms, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - struct compat_ica_rsa_modexpo_crt __user *ucrt32 = compat_ptr(arg); - struct compat_ica_rsa_modexpo_crt crt32; - struct ica_rsa_modexpo_crt crt64; - struct zcrypt_track tr; - long rc; - - memset(&tr, 0, sizeof(tr)); - if (copy_from_user(&crt32, ucrt32, sizeof(crt32))) - return -EFAULT; - crt64.inputdata = compat_ptr(crt32.inputdata); - crt64.inputdatalength = crt32.inputdatalength; - crt64.outputdata = compat_ptr(crt32.outputdata); - crt64.outputdatalength = crt32.outputdatalength; - crt64.bp_key = compat_ptr(crt32.bp_key); - crt64.bq_key = compat_ptr(crt32.bq_key); - crt64.np_prime = compat_ptr(crt32.np_prime); - crt64.nq_prime = compat_ptr(crt32.nq_prime); - crt64.u_mult_inv = compat_ptr(crt32.u_mult_inv); - do { - rc = zcrypt_rsa_crt(perms, &tr, &crt64); - } while (rc == -EAGAIN && ++tr.again_counter < TRACK_AGAIN_MAX); - - /* on ENODEV failure: retry once again after a requested rescan */ - if (rc == -ENODEV && zcrypt_process_rescan()) - do { - rc = zcrypt_rsa_crt(perms, &tr, &crt64); - } while (rc == -EAGAIN && ++tr.again_counter < TRACK_AGAIN_MAX); - if (rc == -EAGAIN && tr.again_counter >= TRACK_AGAIN_MAX) - rc = -EIO; - if (rc) - return rc; - return put_user(crt64.outputdatalength, - &ucrt32->outputdatalength); -} - -struct compat_ica_xcrb { - unsigned short agent_ID; - unsigned int user_defined; - unsigned short request_ID; - unsigned int request_control_blk_length; - unsigned char padding1[16 - sizeof(compat_uptr_t)]; - compat_uptr_t request_control_blk_addr; - unsigned int request_data_length; - char padding2[16 - sizeof(compat_uptr_t)]; - compat_uptr_t request_data_address; - unsigned int reply_control_blk_length; - char padding3[16 - sizeof(compat_uptr_t)]; - compat_uptr_t reply_control_blk_addr; - unsigned int reply_data_length; - char padding4[16 - sizeof(compat_uptr_t)]; - compat_uptr_t reply_data_addr; - unsigned short priority_window; - unsigned int status; -} __packed; - -static long trans_xcrb32(struct ap_perms *perms, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - struct compat_ica_xcrb __user *uxcrb32 = compat_ptr(arg); - u32 xflags = ZCRYPT_XFLAG_USERSPACE; - struct compat_ica_xcrb xcrb32; - struct zcrypt_track tr; - struct ica_xcRB xcrb64; - long rc; - - memset(&tr, 0, sizeof(tr)); - if (copy_from_user(&xcrb32, uxcrb32, sizeof(xcrb32))) - return -EFAULT; - xcrb64.agent_ID = xcrb32.agent_ID; - xcrb64.user_defined = xcrb32.user_defined; - xcrb64.request_ID = xcrb32.request_ID; - xcrb64.request_control_blk_length = - xcrb32.request_control_blk_length; - xcrb64.request_control_blk_addr = - compat_ptr(xcrb32.request_control_blk_addr); - xcrb64.request_data_length = - xcrb32.request_data_length; - xcrb64.request_data_address = - compat_ptr(xcrb32.request_data_address); - xcrb64.reply_control_blk_length = - xcrb32.reply_control_blk_length; - xcrb64.reply_control_blk_addr = - compat_ptr(xcrb32.reply_control_blk_addr); - xcrb64.reply_data_length = xcrb32.reply_data_length; - xcrb64.reply_data_addr = - compat_ptr(xcrb32.reply_data_addr); - xcrb64.priority_window = xcrb32.priority_window; - xcrb64.status = xcrb32.status; - do { - rc = _zcrypt_send_cprb(xflags, perms, &tr, &xcrb64); - } while (rc == -EAGAIN && ++tr.again_counter < TRACK_AGAIN_MAX); - - /* on ENODEV failure: retry once again after a requested rescan */ - if (rc == -ENODEV && zcrypt_process_rescan()) - do { - rc = _zcrypt_send_cprb(xflags, perms, &tr, &xcrb64); - } while (rc == -EAGAIN && ++tr.again_counter < TRACK_AGAIN_MAX); - if (rc == -EAGAIN && tr.again_counter >= TRACK_AGAIN_MAX) - rc = -EIO; - xcrb32.reply_control_blk_length = xcrb64.reply_control_blk_length; - xcrb32.reply_data_length = xcrb64.reply_data_length; - xcrb32.status = xcrb64.status; - if (copy_to_user(uxcrb32, &xcrb32, sizeof(xcrb32))) - return -EFAULT; - return rc; -} - -static long zcrypt_compat_ioctl(struct file *filp, unsigned int cmd, - unsigned long arg) -{ - int rc; - struct ap_perms *perms = - (struct ap_perms *)filp->private_data; - - rc = zcrypt_check_ioctl(perms, cmd); - if (rc) - return rc; - - if (cmd == ICARSAMODEXPO) - return trans_modexpo32(perms, filp, cmd, arg); - if (cmd == ICARSACRT) - return trans_modexpo_crt32(perms, filp, cmd, arg); - if (cmd == ZSECSENDCPRB) - return trans_xcrb32(perms, filp, cmd, arg); - return zcrypt_unlocked_ioctl(filp, cmd, arg); -} -#endif - /* * Misc device file operations. */ @@ -1933,9 +1741,6 @@ static const struct file_operations zcrypt_fops = { .read = zcrypt_read, .write = zcrypt_write, .unlocked_ioctl = zcrypt_unlocked_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = zcrypt_compat_ioctl, -#endif .open = zcrypt_open, .release = zcrypt_release, }; diff --git a/drivers/s390/crypto/zcrypt_card.c b/drivers/s390/crypto/zcrypt_card.c index aa2c8ff2740e..6dea702a5cac 100644 --- a/drivers/s390/crypto/zcrypt_card.c +++ b/drivers/s390/crypto/zcrypt_card.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/s390/crypto/zcrypt_queue.c b/drivers/s390/crypto/zcrypt_queue.c index 76a8678bdad6..a173d32eb6e8 100644 --- a/drivers/s390/crypto/zcrypt_queue.c +++ b/drivers/s390/crypto/zcrypt_queue.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index edc0bcd46923..6d415e9d5c9f 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -10,7 +10,6 @@ #define KMSG_COMPONENT "qeth" #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt -#include #include #include #include @@ -4805,8 +4804,7 @@ static int qeth_query_oat_command(struct qeth_card *card, char __user *udata) rc = qeth_send_ipa_cmd(card, iob, qeth_setadpparms_query_oat_cb, &priv); if (!rc) { - tmp = is_compat_task() ? compat_ptr(oat_data.ptr) : - u64_to_user_ptr(oat_data.ptr); + tmp = u64_to_user_ptr(oat_data.ptr); oat_data.response_len = priv.response_len; if (copy_to_user(tmp, priv.buffer, priv.response_len) || From 3db5cf9354710c3b9268af74a0dca88514279453 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 10 Nov 2025 19:54:38 +0100 Subject: [PATCH 75/92] s390/uapi: Remove 31 bit support from uapi header files Since the kernel does not support running 31 bit / compat binaries anymore, remove also the corresponding 31 bit support from uapi header files. Reviewed-by: Arnd Bergmann Signed-off-by: Heiko Carstens --- arch/s390/include/uapi/asm/bitsperlong.h | 4 - arch/s390/include/uapi/asm/ipcbuf.h | 3 - arch/s390/include/uapi/asm/posix_types.h | 13 --- arch/s390/include/uapi/asm/ptrace.h | 124 ----------------------- arch/s390/include/uapi/asm/sigcontext.h | 15 --- arch/s390/include/uapi/asm/stat.h | 70 ------------- arch/s390/include/uapi/asm/unistd.h | 4 - 7 files changed, 233 deletions(-) diff --git a/arch/s390/include/uapi/asm/bitsperlong.h b/arch/s390/include/uapi/asm/bitsperlong.h index cceaf47b021a..7af27a985f25 100644 --- a/arch/s390/include/uapi/asm/bitsperlong.h +++ b/arch/s390/include/uapi/asm/bitsperlong.h @@ -2,11 +2,7 @@ #ifndef __ASM_S390_BITSPERLONG_H #define __ASM_S390_BITSPERLONG_H -#ifndef __s390x__ -#define __BITS_PER_LONG 32 -#else #define __BITS_PER_LONG 64 -#endif #include diff --git a/arch/s390/include/uapi/asm/ipcbuf.h b/arch/s390/include/uapi/asm/ipcbuf.h index 1030cd186899..9277e76d6d72 100644 --- a/arch/s390/include/uapi/asm/ipcbuf.h +++ b/arch/s390/include/uapi/asm/ipcbuf.h @@ -24,9 +24,6 @@ struct ipc64_perm __kernel_mode_t mode; unsigned short __pad1; unsigned short seq; -#ifndef __s390x__ - unsigned short __pad2; -#endif /* ! __s390x__ */ unsigned long __unused1; unsigned long __unused2; }; diff --git a/arch/s390/include/uapi/asm/posix_types.h b/arch/s390/include/uapi/asm/posix_types.h index 1913613e71b6..ad5ab940d192 100644 --- a/arch/s390/include/uapi/asm/posix_types.h +++ b/arch/s390/include/uapi/asm/posix_types.h @@ -26,17 +26,6 @@ typedef unsigned short __kernel_old_gid_t; #define __kernel_old_uid_t __kernel_old_uid_t #endif -#ifndef __s390x__ - -typedef unsigned long __kernel_ino_t; -typedef unsigned short __kernel_mode_t; -typedef unsigned short __kernel_ipc_pid_t; -typedef unsigned short __kernel_uid_t; -typedef unsigned short __kernel_gid_t; -typedef int __kernel_ptrdiff_t; - -#else /* __s390x__ */ - typedef unsigned int __kernel_ino_t; typedef unsigned int __kernel_mode_t; typedef int __kernel_ipc_pid_t; @@ -45,8 +34,6 @@ typedef unsigned int __kernel_gid_t; typedef long __kernel_ptrdiff_t; typedef unsigned long __kernel_sigset_t; /* at least 32 bits */ -#endif /* __s390x__ */ - #define __kernel_ino_t __kernel_ino_t #define __kernel_mode_t __kernel_mode_t #define __kernel_ipc_pid_t __kernel_ipc_pid_t diff --git a/arch/s390/include/uapi/asm/ptrace.h b/arch/s390/include/uapi/asm/ptrace.h index ea202072f1ad..ea29ba470e5a 100644 --- a/arch/s390/include/uapi/asm/ptrace.h +++ b/arch/s390/include/uapi/asm/ptrace.h @@ -14,94 +14,6 @@ * Offsets in the user_regs_struct. They are used for the ptrace * system call and in entry.S */ -#ifndef __s390x__ - -#define PT_PSWMASK 0x00 -#define PT_PSWADDR 0x04 -#define PT_GPR0 0x08 -#define PT_GPR1 0x0C -#define PT_GPR2 0x10 -#define PT_GPR3 0x14 -#define PT_GPR4 0x18 -#define PT_GPR5 0x1C -#define PT_GPR6 0x20 -#define PT_GPR7 0x24 -#define PT_GPR8 0x28 -#define PT_GPR9 0x2C -#define PT_GPR10 0x30 -#define PT_GPR11 0x34 -#define PT_GPR12 0x38 -#define PT_GPR13 0x3C -#define PT_GPR14 0x40 -#define PT_GPR15 0x44 -#define PT_ACR0 0x48 -#define PT_ACR1 0x4C -#define PT_ACR2 0x50 -#define PT_ACR3 0x54 -#define PT_ACR4 0x58 -#define PT_ACR5 0x5C -#define PT_ACR6 0x60 -#define PT_ACR7 0x64 -#define PT_ACR8 0x68 -#define PT_ACR9 0x6C -#define PT_ACR10 0x70 -#define PT_ACR11 0x74 -#define PT_ACR12 0x78 -#define PT_ACR13 0x7C -#define PT_ACR14 0x80 -#define PT_ACR15 0x84 -#define PT_ORIGGPR2 0x88 -#define PT_FPC 0x90 -/* - * A nasty fact of life that the ptrace api - * only supports passing of longs. - */ -#define PT_FPR0_HI 0x98 -#define PT_FPR0_LO 0x9C -#define PT_FPR1_HI 0xA0 -#define PT_FPR1_LO 0xA4 -#define PT_FPR2_HI 0xA8 -#define PT_FPR2_LO 0xAC -#define PT_FPR3_HI 0xB0 -#define PT_FPR3_LO 0xB4 -#define PT_FPR4_HI 0xB8 -#define PT_FPR4_LO 0xBC -#define PT_FPR5_HI 0xC0 -#define PT_FPR5_LO 0xC4 -#define PT_FPR6_HI 0xC8 -#define PT_FPR6_LO 0xCC -#define PT_FPR7_HI 0xD0 -#define PT_FPR7_LO 0xD4 -#define PT_FPR8_HI 0xD8 -#define PT_FPR8_LO 0XDC -#define PT_FPR9_HI 0xE0 -#define PT_FPR9_LO 0xE4 -#define PT_FPR10_HI 0xE8 -#define PT_FPR10_LO 0xEC -#define PT_FPR11_HI 0xF0 -#define PT_FPR11_LO 0xF4 -#define PT_FPR12_HI 0xF8 -#define PT_FPR12_LO 0xFC -#define PT_FPR13_HI 0x100 -#define PT_FPR13_LO 0x104 -#define PT_FPR14_HI 0x108 -#define PT_FPR14_LO 0x10C -#define PT_FPR15_HI 0x110 -#define PT_FPR15_LO 0x114 -#define PT_CR_9 0x118 -#define PT_CR_10 0x11C -#define PT_CR_11 0x120 -#define PT_IEEE_IP 0x13C -#define PT_LASTOFF PT_IEEE_IP -#define PT_ENDREGS 0x140-1 - -#define GPR_SIZE 4 -#define CR_SIZE 4 - -#define STACK_FRAME_OVERHEAD 96 /* size of minimum stack frame */ - -#else /* __s390x__ */ - #define PT_PSWMASK 0x00 #define PT_PSWADDR 0x08 #define PT_GPR0 0x10 @@ -166,38 +78,6 @@ #define STACK_FRAME_OVERHEAD 160 /* size of minimum stack frame */ -#endif /* __s390x__ */ - -#ifndef __s390x__ - -#define PSW_MASK_PER _AC(0x40000000, UL) -#define PSW_MASK_DAT _AC(0x04000000, UL) -#define PSW_MASK_IO _AC(0x02000000, UL) -#define PSW_MASK_EXT _AC(0x01000000, UL) -#define PSW_MASK_KEY _AC(0x00F00000, UL) -#define PSW_MASK_BASE _AC(0x00080000, UL) /* always one */ -#define PSW_MASK_MCHECK _AC(0x00040000, UL) -#define PSW_MASK_WAIT _AC(0x00020000, UL) -#define PSW_MASK_PSTATE _AC(0x00010000, UL) -#define PSW_MASK_ASC _AC(0x0000C000, UL) -#define PSW_MASK_CC _AC(0x00003000, UL) -#define PSW_MASK_PM _AC(0x00000F00, UL) -#define PSW_MASK_RI _AC(0x00000000, UL) -#define PSW_MASK_EA _AC(0x00000000, UL) -#define PSW_MASK_BA _AC(0x00000000, UL) - -#define PSW_MASK_USER _AC(0x0000FF00, UL) - -#define PSW_ADDR_AMODE _AC(0x80000000, UL) -#define PSW_ADDR_INSN _AC(0x7FFFFFFF, UL) - -#define PSW_ASC_PRIMARY _AC(0x00000000, UL) -#define PSW_ASC_ACCREG _AC(0x00004000, UL) -#define PSW_ASC_SECONDARY _AC(0x00008000, UL) -#define PSW_ASC_HOME _AC(0x0000C000, UL) - -#else /* __s390x__ */ - #define PSW_MASK_PER _AC(0x4000000000000000, UL) #define PSW_MASK_DAT _AC(0x0400000000000000, UL) #define PSW_MASK_IO _AC(0x0200000000000000, UL) @@ -224,8 +104,6 @@ #define PSW_ASC_SECONDARY _AC(0x0000800000000000, UL) #define PSW_ASC_HOME _AC(0x0000C00000000000, UL) -#endif /* __s390x__ */ - #define NUM_GPRS 16 #define NUM_FPRS 16 #define NUM_CRS 16 @@ -308,9 +186,7 @@ typedef struct { #define PER_EM_MASK 0xE8000000UL typedef struct { -#ifdef __s390x__ unsigned : 32; -#endif /* __s390x__ */ unsigned em_branching : 1; unsigned em_instruction_fetch : 1; /* diff --git a/arch/s390/include/uapi/asm/sigcontext.h b/arch/s390/include/uapi/asm/sigcontext.h index 8b35033334c4..7c90b30c50fd 100644 --- a/arch/s390/include/uapi/asm/sigcontext.h +++ b/arch/s390/include/uapi/asm/sigcontext.h @@ -17,24 +17,12 @@ #define __NUM_VXRS_LOW 16 #define __NUM_VXRS_HIGH 16 -#ifndef __s390x__ - -/* Has to be at least _NSIG_WORDS from asm/signal.h */ -#define _SIGCONTEXT_NSIG 64 -#define _SIGCONTEXT_NSIG_BPW 32 -/* Size of stack frame allocated when calling signal handler. */ -#define __SIGNAL_FRAMESIZE 96 - -#else /* __s390x__ */ - /* Has to be at least _NSIG_WORDS from asm/signal.h */ #define _SIGCONTEXT_NSIG 64 #define _SIGCONTEXT_NSIG_BPW 64 /* Size of stack frame allocated when calling signal handler. */ #define __SIGNAL_FRAMESIZE 160 -#endif /* __s390x__ */ - #define _SIGCONTEXT_NSIG_WORDS (_SIGCONTEXT_NSIG / _SIGCONTEXT_NSIG_BPW) #define _SIGMASK_COPY_SIZE (sizeof(unsigned long)*_SIGCONTEXT_NSIG_WORDS) @@ -66,9 +54,6 @@ typedef struct typedef struct { -#ifndef __s390x__ - unsigned long gprs_high[__NUM_GPRS]; -#endif unsigned long long vxrs_low[__NUM_VXRS_LOW]; __vector128 vxrs_high[__NUM_VXRS_HIGH]; unsigned char __reserved[128]; diff --git a/arch/s390/include/uapi/asm/stat.h b/arch/s390/include/uapi/asm/stat.h index ac253d23606b..21599298c2f5 100644 --- a/arch/s390/include/uapi/asm/stat.h +++ b/arch/s390/include/uapi/asm/stat.h @@ -8,74 +8,6 @@ #ifndef _S390_STAT_H #define _S390_STAT_H -#ifndef __s390x__ -struct __old_kernel_stat { - unsigned short st_dev; - unsigned short st_ino; - unsigned short st_mode; - unsigned short st_nlink; - unsigned short st_uid; - unsigned short st_gid; - unsigned short st_rdev; - unsigned long st_size; - unsigned long st_atime; - unsigned long st_mtime; - unsigned long st_ctime; -}; - -struct stat { - unsigned short st_dev; - unsigned short __pad1; - unsigned long st_ino; - unsigned short st_mode; - unsigned short st_nlink; - unsigned short st_uid; - unsigned short st_gid; - unsigned short st_rdev; - unsigned short __pad2; - unsigned long st_size; - unsigned long st_blksize; - unsigned long st_blocks; - unsigned long st_atime; - unsigned long st_atime_nsec; - unsigned long st_mtime; - unsigned long st_mtime_nsec; - unsigned long st_ctime; - unsigned long st_ctime_nsec; - unsigned long __unused4; - unsigned long __unused5; -}; - -/* This matches struct stat64 in glibc2.1, hence the absolutely - * insane amounts of padding around dev_t's. - */ -struct stat64 { - unsigned long long st_dev; - unsigned int __pad1; -#define STAT64_HAS_BROKEN_ST_INO 1 - unsigned long __st_ino; - unsigned int st_mode; - unsigned int st_nlink; - unsigned long st_uid; - unsigned long st_gid; - unsigned long long st_rdev; - unsigned int __pad3; - long long st_size; - unsigned long st_blksize; - unsigned char __pad4[4]; - unsigned long __pad5; /* future possible st_blocks high bits */ - unsigned long st_blocks; /* Number 512-byte blocks allocated. */ - unsigned long st_atime; - unsigned long st_atime_nsec; - unsigned long st_mtime; - unsigned long st_mtime_nsec; - unsigned long st_ctime; - unsigned long st_ctime_nsec; /* will be high 32 bits of ctime someday */ - unsigned long long st_ino; -}; - -#else /* __s390x__ */ - struct stat { unsigned long st_dev; unsigned long st_ino; @@ -97,8 +29,6 @@ struct stat { unsigned long __unused[3]; }; -#endif /* __s390x__ */ - #define STAT_HAVE_NSEC 1 #endif diff --git a/arch/s390/include/uapi/asm/unistd.h b/arch/s390/include/uapi/asm/unistd.h index 01b5fe8b9db6..b0c5afe19db2 100644 --- a/arch/s390/include/uapi/asm/unistd.h +++ b/arch/s390/include/uapi/asm/unistd.h @@ -8,10 +8,6 @@ #ifndef _UAPI_ASM_S390_UNISTD_H_ #define _UAPI_ASM_S390_UNISTD_H_ -#ifdef __s390x__ #include -#else -#include -#endif #endif /* _UAPI_ASM_S390_UNISTD_H_ */ From f4e1f1b1379df5b44fffbf09940761921d35da66 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 10 Nov 2025 19:54:39 +0100 Subject: [PATCH 76/92] s390/syscalls: Remove system call table pointer from thread_struct With compat support gone there is only one system call table left. Therefore remove the sys_call_table pointer from thread_struct and use the sys_call_table directly. Reviewed-by: Arnd Bergmann Signed-off-by: Heiko Carstens --- arch/s390/include/asm/elf.h | 1 - arch/s390/include/asm/processor.h | 1 - arch/s390/kernel/syscall.c | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/s390/include/asm/elf.h b/arch/s390/include/asm/elf.h index 2b6ab483b1ca..bb63fa4d20bb 100644 --- a/arch/s390/include/asm/elf.h +++ b/arch/s390/include/asm/elf.h @@ -217,7 +217,6 @@ extern char elf_platform[]; do { \ set_personality(PER_LINUX | \ (current->personality & (~PER_MASK))); \ - current->thread.sys_call_table = sys_call_table; \ } while (0) /* diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index e8e9e6baebdd..3affba95845b 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h @@ -175,7 +175,6 @@ struct thread_struct { unsigned long system_timer; /* task cputime in kernel space */ unsigned long hardirq_timer; /* task cputime in hardirq context */ unsigned long softirq_timer; /* task cputime in softirq context */ - const sys_call_ptr_t *sys_call_table; /* system call table address */ union teid gmap_teid; /* address and flags of last gmap fault */ unsigned int gmap_int_code; /* int code of last gmap fault */ int ufpu_flags; /* user fpu flags */ diff --git a/arch/s390/kernel/syscall.c b/arch/s390/kernel/syscall.c index 4fee74553ca2..3b7ea1ef468a 100644 --- a/arch/s390/kernel/syscall.c +++ b/arch/s390/kernel/syscall.c @@ -122,7 +122,7 @@ void noinstr __do_syscall(struct pt_regs *regs, int per_trap) goto out; regs->gprs[2] = -ENOSYS; if (likely(nr < NR_syscalls)) - regs->gprs[2] = current->thread.sys_call_table[nr](regs); + regs->gprs[2] = sys_call_table[nr](regs); out: syscall_exit_to_user_mode(regs); } From 4ac286c4a8d904c8818a6f019da8117ec31b2c27 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 10 Nov 2025 19:54:40 +0100 Subject: [PATCH 77/92] s390/syscalls: Switch to generic system call table generation The s390 syscall.tbl format differs slightly from most others, and therefore requires an s390 specific system call table generation script. With compat support gone use the opportunity to switch to generic system call table generation. The abi for all 64 bit system calls is now common, since there is no need to specify if system call entry points are only for 64 bit anymore. Furthermore create the system call table in C instead of assembler code in order to get type checking for all system call functions contained within the table. Reviewed-by: Arnd Bergmann Signed-off-by: Heiko Carstens --- arch/s390/Makefile | 3 +- arch/s390/include/asm/unistd.h | 3 +- arch/s390/kernel/entry.S | 8 - arch/s390/kernel/syscall.c | 10 + arch/s390/kernel/syscalls/Makefile | 58 +- arch/s390/kernel/syscalls/syscall.tbl | 856 ++++++++++++-------------- arch/s390/kernel/syscalls/syscalltbl | 232 ------- 7 files changed, 424 insertions(+), 746 deletions(-) delete mode 100755 arch/s390/kernel/syscalls/syscalltbl diff --git a/arch/s390/Makefile b/arch/s390/Makefile index f41b8c5c4e56..bf53e7d1487a 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile @@ -134,10 +134,9 @@ zfcpdump: $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ archheaders: - $(Q)$(MAKE) $(build)=$(syscalls) uapi + $(Q)$(MAKE) $(build)=$(syscalls) all archprepare: - $(Q)$(MAKE) $(build)=$(syscalls) kapi $(Q)$(MAKE) $(build)=$(tools) kapi $(extra_tools) ifeq ($(KBUILD_EXTMOD),) # We need to generate vdso-offsets.h before compiling certain files in kernel/. diff --git a/arch/s390/include/asm/unistd.h b/arch/s390/include/asm/unistd.h index 252d7ac7a6b2..921c3fb3586b 100644 --- a/arch/s390/include/asm/unistd.h +++ b/arch/s390/include/asm/unistd.h @@ -8,7 +8,8 @@ #define _ASM_S390_UNISTD_H_ #include -#include + +#define NR_syscalls (__NR_syscalls) #define __ARCH_WANT_NEW_STAT #define __ARCH_WANT_OLD_READDIR diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 3c7f183a945d..1e266c0eae2c 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -606,11 +606,3 @@ SYM_DATA_START_LOCAL(daton_psw) .quad PSW_KERNEL_BITS .quad .Ldaton SYM_DATA_END(daton_psw) - - .section .rodata, "a" - .balign 8 -#define SYSCALL(esame,emu) .quad __s390x_ ## esame -SYM_DATA_START(sys_call_table) -#include -SYM_DATA_END(sys_call_table) -#undef SYSCALL diff --git a/arch/s390/kernel/syscall.c b/arch/s390/kernel/syscall.c index 3b7ea1ef468a..795b6cca74c9 100644 --- a/arch/s390/kernel/syscall.c +++ b/arch/s390/kernel/syscall.c @@ -39,6 +39,16 @@ #include "entry.h" +#define __SYSCALL(nr, sym) long __s390x_##sym(struct pt_regs *); +#include +#undef __SYSCALL + +#define __SYSCALL(nr, sym) [nr] = (__s390x_##sym), +const sys_call_ptr_t sys_call_table[__NR_syscalls] = { +#include +}; +#undef __SYSCALL + #ifdef CONFIG_SYSVIPC /* * sys_ipc() is the de-multiplexer for the SysV IPC calls. diff --git a/arch/s390/kernel/syscalls/Makefile b/arch/s390/kernel/syscalls/Makefile index c5d958a09ff4..d5fca0ca0890 100644 --- a/arch/s390/kernel/syscalls/Makefile +++ b/arch/s390/kernel/syscalls/Makefile @@ -1,48 +1,32 @@ # SPDX-License-Identifier: GPL-2.0 +kapi := arch/$(SRCARCH)/include/generated/asm +uapi := arch/$(SRCARCH)/include/generated/uapi/asm -gen := arch/$(ARCH)/include/generated -kapi := $(gen)/asm -uapi := $(gen)/uapi/asm - -syscall := $(src)/syscall.tbl -systbl := $(src)/syscalltbl - -gen-y := $(kapi)/syscall_table.h -kapi-hdrs-y := $(kapi)/unistd_nr.h -uapi-hdrs-y := $(uapi)/unistd_32.h -uapi-hdrs-y += $(uapi)/unistd_64.h - -targets += $(addprefix ../../../../,$(gen-y) $(kapi-hdrs-y) $(uapi-hdrs-y)) - -PHONY += kapi uapi - -kapi: $(gen-y) $(kapi-hdrs-y) -uapi: $(uapi-hdrs-y) - - -# Create output directory if not already present $(shell mkdir -p $(uapi) $(kapi)) +syscall := $(src)/syscall.tbl +syshdr := $(srctree)/scripts/syscallhdr.sh +systbl := $(srctree)/scripts/syscalltbl.sh + quiet_cmd_syshdr = SYSHDR $@ - cmd_syshdr = $(CONFIG_SHELL) '$(systbl)' -H -a $(syshdr_abi_$(basetarget)) -f "$@" < $< > $@ + cmd_syshdr = $(CONFIG_SHELL) $(syshdr) --emit-nr --abis common,$* $< $@ -quiet_cmd_sysnr = SYSNR $@ - cmd_sysnr = $(CONFIG_SHELL) '$(systbl)' -N -a $(sysnr_abi_$(basetarget)) < $< > $@ +quiet_cmd_systbl = SYSTBL $@ + cmd_systbl = $(CONFIG_SHELL) $(systbl) --abis common,$* $< $@ -quiet_cmd_syscalls = SYSTBL $@ - cmd_syscalls = $(CONFIG_SHELL) '$(systbl)' -S < $< > $@ - -syshdr_abi_unistd_32 := common,32 -$(uapi)/unistd_32.h: $(syscall) $(systbl) FORCE - $(call if_changed,syshdr) - -syshdr_abi_unistd_64 := common,64 -$(uapi)/unistd_64.h: $(syscall) $(systbl) FORCE +$(uapi)/unistd_%.h: $(syscall) $(syshdr) FORCE $(call if_changed,syshdr) $(kapi)/syscall_table.h: $(syscall) $(systbl) FORCE - $(call if_changed,syscalls) + $(call if_changed,systbl) -sysnr_abi_unistd_nr := common,32,64 -$(kapi)/unistd_nr.h: $(syscall) $(systbl) FORCE - $(call if_changed,sysnr) +uapisyshdr-y += unistd_64.h +kapisyshdr-y += syscall_table.h + +uapisyshdr-y := $(addprefix $(uapi)/, $(uapisyshdr-y)) +kapisyshdr-y := $(addprefix $(kapi)/, $(kapisyshdr-y)) +targets += $(addprefix ../../../../, $(uapisyshdr-y) $(kapisyshdr-y)) + +PHONY += all +all: $(uapisyshdr-y) $(kapisyshdr-y) + @: diff --git a/arch/s390/kernel/syscalls/syscall.tbl b/arch/s390/kernel/syscalls/syscall.tbl index 8a6744d658db..eb1175d627cf 100644 --- a/arch/s390/kernel/syscalls/syscall.tbl +++ b/arch/s390/kernel/syscalls/syscall.tbl @@ -3,472 +3,396 @@ # System call table for s390 # # Format: +# # -# -# -# where can be common, 64, or 32 +# is always common. -1 common exit sys_exit sys_exit -2 common fork sys_fork sys_fork -3 common read sys_read compat_sys_s390_read -4 common write sys_write compat_sys_s390_write -5 common open sys_open compat_sys_open -6 common close sys_close sys_close -7 common restart_syscall sys_restart_syscall sys_restart_syscall -8 common creat sys_creat sys_creat -9 common link sys_link sys_link -10 common unlink sys_unlink sys_unlink -11 common execve sys_execve compat_sys_execve -12 common chdir sys_chdir sys_chdir -13 32 time - sys_time32 -14 common mknod sys_mknod sys_mknod -15 common chmod sys_chmod sys_chmod -16 32 lchown - sys_lchown16 -19 common lseek sys_lseek compat_sys_lseek -20 common getpid sys_getpid sys_getpid -21 common mount sys_mount sys_mount -22 common umount sys_oldumount sys_oldumount -23 32 setuid - sys_setuid16 -24 32 getuid - sys_getuid16 -25 32 stime - sys_stime32 -26 common ptrace sys_ptrace compat_sys_ptrace -27 common alarm sys_alarm sys_alarm -29 common pause sys_pause sys_pause -30 common utime sys_utime sys_utime32 -33 common access sys_access sys_access -34 common nice sys_nice sys_nice -36 common sync sys_sync sys_sync -37 common kill sys_kill sys_kill -38 common rename sys_rename sys_rename -39 common mkdir sys_mkdir sys_mkdir -40 common rmdir sys_rmdir sys_rmdir -41 common dup sys_dup sys_dup -42 common pipe sys_pipe sys_pipe -43 common times sys_times compat_sys_times -45 common brk sys_brk sys_brk -46 32 setgid - sys_setgid16 -47 32 getgid - sys_getgid16 -48 common signal sys_signal sys_signal -49 32 geteuid - sys_geteuid16 -50 32 getegid - sys_getegid16 -51 common acct sys_acct sys_acct -52 common umount2 sys_umount sys_umount -54 common ioctl sys_ioctl compat_sys_ioctl -55 common fcntl sys_fcntl compat_sys_fcntl -57 common setpgid sys_setpgid sys_setpgid -60 common umask sys_umask sys_umask -61 common chroot sys_chroot sys_chroot -62 common ustat sys_ustat compat_sys_ustat -63 common dup2 sys_dup2 sys_dup2 -64 common getppid sys_getppid sys_getppid -65 common getpgrp sys_getpgrp sys_getpgrp -66 common setsid sys_setsid sys_setsid -67 common sigaction sys_sigaction compat_sys_sigaction -70 32 setreuid - sys_setreuid16 -71 32 setregid - sys_setregid16 -72 common sigsuspend sys_sigsuspend sys_sigsuspend -73 common sigpending sys_sigpending compat_sys_sigpending -74 common sethostname sys_sethostname sys_sethostname -75 common setrlimit sys_setrlimit compat_sys_setrlimit -76 32 getrlimit - compat_sys_old_getrlimit -77 common getrusage sys_getrusage compat_sys_getrusage -78 common gettimeofday sys_gettimeofday compat_sys_gettimeofday -79 common settimeofday sys_settimeofday compat_sys_settimeofday -80 32 getgroups - sys_getgroups16 -81 32 setgroups - sys_setgroups16 -83 common symlink sys_symlink sys_symlink -85 common readlink sys_readlink sys_readlink -86 common uselib sys_uselib sys_uselib -87 common swapon sys_swapon sys_swapon -88 common reboot sys_reboot sys_reboot -89 common readdir - compat_sys_old_readdir -90 common mmap sys_old_mmap compat_sys_s390_old_mmap -91 common munmap sys_munmap sys_munmap -92 common truncate sys_truncate compat_sys_truncate -93 common ftruncate sys_ftruncate compat_sys_ftruncate -94 common fchmod sys_fchmod sys_fchmod -95 32 fchown - sys_fchown16 -96 common getpriority sys_getpriority sys_getpriority -97 common setpriority sys_setpriority sys_setpriority -99 common statfs sys_statfs compat_sys_statfs -100 common fstatfs sys_fstatfs compat_sys_fstatfs -101 32 ioperm - - -102 common socketcall sys_socketcall compat_sys_socketcall -103 common syslog sys_syslog sys_syslog -104 common setitimer sys_setitimer compat_sys_setitimer -105 common getitimer sys_getitimer compat_sys_getitimer -106 common stat sys_newstat compat_sys_newstat -107 common lstat sys_newlstat compat_sys_newlstat -108 common fstat sys_newfstat compat_sys_newfstat -110 common lookup_dcookie - - -111 common vhangup sys_vhangup sys_vhangup -112 common idle - - -114 common wait4 sys_wait4 compat_sys_wait4 -115 common swapoff sys_swapoff sys_swapoff -116 common sysinfo sys_sysinfo compat_sys_sysinfo -117 common ipc sys_s390_ipc compat_sys_s390_ipc -118 common fsync sys_fsync sys_fsync -119 common sigreturn sys_sigreturn compat_sys_sigreturn -120 common clone sys_clone sys_clone -121 common setdomainname sys_setdomainname sys_setdomainname -122 common uname sys_newuname sys_newuname -124 common adjtimex sys_adjtimex sys_adjtimex_time32 -125 common mprotect sys_mprotect sys_mprotect -126 common sigprocmask sys_sigprocmask compat_sys_sigprocmask -127 common create_module - - -128 common init_module sys_init_module sys_init_module -129 common delete_module sys_delete_module sys_delete_module -130 common get_kernel_syms - - -131 common quotactl sys_quotactl sys_quotactl -132 common getpgid sys_getpgid sys_getpgid -133 common fchdir sys_fchdir sys_fchdir -134 common bdflush sys_ni_syscall sys_ni_syscall -135 common sysfs sys_sysfs sys_sysfs -136 common personality sys_s390_personality sys_s390_personality -137 common afs_syscall - - -138 32 setfsuid - sys_setfsuid16 -139 32 setfsgid - sys_setfsgid16 -140 32 _llseek - sys_llseek -141 common getdents sys_getdents compat_sys_getdents -142 32 _newselect - compat_sys_select -142 64 select sys_select - -143 common flock sys_flock sys_flock -144 common msync sys_msync sys_msync -145 common readv sys_readv sys_readv -146 common writev sys_writev sys_writev -147 common getsid sys_getsid sys_getsid -148 common fdatasync sys_fdatasync sys_fdatasync -149 common _sysctl - - -150 common mlock sys_mlock sys_mlock -151 common munlock sys_munlock sys_munlock -152 common mlockall sys_mlockall sys_mlockall -153 common munlockall sys_munlockall sys_munlockall -154 common sched_setparam sys_sched_setparam sys_sched_setparam -155 common sched_getparam sys_sched_getparam sys_sched_getparam -156 common sched_setscheduler sys_sched_setscheduler sys_sched_setscheduler -157 common sched_getscheduler sys_sched_getscheduler sys_sched_getscheduler -158 common sched_yield sys_sched_yield sys_sched_yield -159 common sched_get_priority_max sys_sched_get_priority_max sys_sched_get_priority_max -160 common sched_get_priority_min sys_sched_get_priority_min sys_sched_get_priority_min -161 common sched_rr_get_interval sys_sched_rr_get_interval sys_sched_rr_get_interval_time32 -162 common nanosleep sys_nanosleep sys_nanosleep_time32 -163 common mremap sys_mremap sys_mremap -164 32 setresuid - sys_setresuid16 -165 32 getresuid - sys_getresuid16 -167 common query_module - - -168 common poll sys_poll sys_poll -169 common nfsservctl - - -170 32 setresgid - sys_setresgid16 -171 32 getresgid - sys_getresgid16 -172 common prctl sys_prctl sys_prctl -173 common rt_sigreturn sys_rt_sigreturn compat_sys_rt_sigreturn -174 common rt_sigaction sys_rt_sigaction compat_sys_rt_sigaction -175 common rt_sigprocmask sys_rt_sigprocmask compat_sys_rt_sigprocmask -176 common rt_sigpending sys_rt_sigpending compat_sys_rt_sigpending -177 common rt_sigtimedwait sys_rt_sigtimedwait compat_sys_rt_sigtimedwait_time32 -178 common rt_sigqueueinfo sys_rt_sigqueueinfo compat_sys_rt_sigqueueinfo -179 common rt_sigsuspend sys_rt_sigsuspend compat_sys_rt_sigsuspend -180 common pread64 sys_pread64 compat_sys_s390_pread64 -181 common pwrite64 sys_pwrite64 compat_sys_s390_pwrite64 -182 32 chown - sys_chown16 -183 common getcwd sys_getcwd sys_getcwd -184 common capget sys_capget sys_capget -185 common capset sys_capset sys_capset -186 common sigaltstack sys_sigaltstack compat_sys_sigaltstack -187 common sendfile sys_sendfile64 compat_sys_sendfile -188 common getpmsg - - -189 common putpmsg - - -190 common vfork sys_vfork sys_vfork -191 32 ugetrlimit - compat_sys_getrlimit -191 64 getrlimit sys_getrlimit - -192 32 mmap2 - compat_sys_s390_mmap2 -193 32 truncate64 - compat_sys_s390_truncate64 -194 32 ftruncate64 - compat_sys_s390_ftruncate64 -195 32 stat64 - compat_sys_s390_stat64 -196 32 lstat64 - compat_sys_s390_lstat64 -197 32 fstat64 - compat_sys_s390_fstat64 -198 32 lchown32 - sys_lchown -198 64 lchown sys_lchown - -199 32 getuid32 - sys_getuid -199 64 getuid sys_getuid - -200 32 getgid32 - sys_getgid -200 64 getgid sys_getgid - -201 32 geteuid32 - sys_geteuid -201 64 geteuid sys_geteuid - -202 32 getegid32 - sys_getegid -202 64 getegid sys_getegid - -203 32 setreuid32 - sys_setreuid -203 64 setreuid sys_setreuid - -204 32 setregid32 - sys_setregid -204 64 setregid sys_setregid - -205 32 getgroups32 - sys_getgroups -205 64 getgroups sys_getgroups - -206 32 setgroups32 - sys_setgroups -206 64 setgroups sys_setgroups - -207 32 fchown32 - sys_fchown -207 64 fchown sys_fchown - -208 32 setresuid32 - sys_setresuid -208 64 setresuid sys_setresuid - -209 32 getresuid32 - sys_getresuid -209 64 getresuid sys_getresuid - -210 32 setresgid32 - sys_setresgid -210 64 setresgid sys_setresgid - -211 32 getresgid32 - sys_getresgid -211 64 getresgid sys_getresgid - -212 32 chown32 - sys_chown -212 64 chown sys_chown - -213 32 setuid32 - sys_setuid -213 64 setuid sys_setuid - -214 32 setgid32 - sys_setgid -214 64 setgid sys_setgid - -215 32 setfsuid32 - sys_setfsuid -215 64 setfsuid sys_setfsuid - -216 32 setfsgid32 - sys_setfsgid -216 64 setfsgid sys_setfsgid - -217 common pivot_root sys_pivot_root sys_pivot_root -218 common mincore sys_mincore sys_mincore -219 common madvise sys_madvise sys_madvise -220 common getdents64 sys_getdents64 sys_getdents64 -221 32 fcntl64 - compat_sys_fcntl64 -222 common readahead sys_readahead compat_sys_s390_readahead -223 32 sendfile64 - compat_sys_sendfile64 -224 common setxattr sys_setxattr sys_setxattr -225 common lsetxattr sys_lsetxattr sys_lsetxattr -226 common fsetxattr sys_fsetxattr sys_fsetxattr -227 common getxattr sys_getxattr sys_getxattr -228 common lgetxattr sys_lgetxattr sys_lgetxattr -229 common fgetxattr sys_fgetxattr sys_fgetxattr -230 common listxattr sys_listxattr sys_listxattr -231 common llistxattr sys_llistxattr sys_llistxattr -232 common flistxattr sys_flistxattr sys_flistxattr -233 common removexattr sys_removexattr sys_removexattr -234 common lremovexattr sys_lremovexattr sys_lremovexattr -235 common fremovexattr sys_fremovexattr sys_fremovexattr -236 common gettid sys_gettid sys_gettid -237 common tkill sys_tkill sys_tkill -238 common futex sys_futex sys_futex_time32 -239 common sched_setaffinity sys_sched_setaffinity compat_sys_sched_setaffinity -240 common sched_getaffinity sys_sched_getaffinity compat_sys_sched_getaffinity -241 common tgkill sys_tgkill sys_tgkill -243 common io_setup sys_io_setup compat_sys_io_setup -244 common io_destroy sys_io_destroy sys_io_destroy -245 common io_getevents sys_io_getevents sys_io_getevents_time32 -246 common io_submit sys_io_submit compat_sys_io_submit -247 common io_cancel sys_io_cancel sys_io_cancel -248 common exit_group sys_exit_group sys_exit_group -249 common epoll_create sys_epoll_create sys_epoll_create -250 common epoll_ctl sys_epoll_ctl sys_epoll_ctl -251 common epoll_wait sys_epoll_wait sys_epoll_wait -252 common set_tid_address sys_set_tid_address sys_set_tid_address -253 common fadvise64 sys_fadvise64_64 compat_sys_s390_fadvise64 -254 common timer_create sys_timer_create compat_sys_timer_create -255 common timer_settime sys_timer_settime sys_timer_settime32 -256 common timer_gettime sys_timer_gettime sys_timer_gettime32 -257 common timer_getoverrun sys_timer_getoverrun sys_timer_getoverrun -258 common timer_delete sys_timer_delete sys_timer_delete -259 common clock_settime sys_clock_settime sys_clock_settime32 -260 common clock_gettime sys_clock_gettime sys_clock_gettime32 -261 common clock_getres sys_clock_getres sys_clock_getres_time32 -262 common clock_nanosleep sys_clock_nanosleep sys_clock_nanosleep_time32 -264 32 fadvise64_64 - compat_sys_s390_fadvise64_64 -265 common statfs64 sys_statfs64 compat_sys_statfs64 -266 common fstatfs64 sys_fstatfs64 compat_sys_fstatfs64 -267 common remap_file_pages sys_remap_file_pages sys_remap_file_pages -268 common mbind sys_mbind sys_mbind -269 common get_mempolicy sys_get_mempolicy sys_get_mempolicy -270 common set_mempolicy sys_set_mempolicy sys_set_mempolicy -271 common mq_open sys_mq_open compat_sys_mq_open -272 common mq_unlink sys_mq_unlink sys_mq_unlink -273 common mq_timedsend sys_mq_timedsend sys_mq_timedsend_time32 -274 common mq_timedreceive sys_mq_timedreceive sys_mq_timedreceive_time32 -275 common mq_notify sys_mq_notify compat_sys_mq_notify -276 common mq_getsetattr sys_mq_getsetattr compat_sys_mq_getsetattr -277 common kexec_load sys_kexec_load compat_sys_kexec_load -278 common add_key sys_add_key sys_add_key -279 common request_key sys_request_key sys_request_key -280 common keyctl sys_keyctl compat_sys_keyctl -281 common waitid sys_waitid compat_sys_waitid -282 common ioprio_set sys_ioprio_set sys_ioprio_set -283 common ioprio_get sys_ioprio_get sys_ioprio_get -284 common inotify_init sys_inotify_init sys_inotify_init -285 common inotify_add_watch sys_inotify_add_watch sys_inotify_add_watch -286 common inotify_rm_watch sys_inotify_rm_watch sys_inotify_rm_watch -287 common migrate_pages sys_migrate_pages sys_migrate_pages -288 common openat sys_openat compat_sys_openat -289 common mkdirat sys_mkdirat sys_mkdirat -290 common mknodat sys_mknodat sys_mknodat -291 common fchownat sys_fchownat sys_fchownat -292 common futimesat sys_futimesat sys_futimesat_time32 -293 32 fstatat64 - compat_sys_s390_fstatat64 -293 64 newfstatat sys_newfstatat - -294 common unlinkat sys_unlinkat sys_unlinkat -295 common renameat sys_renameat sys_renameat -296 common linkat sys_linkat sys_linkat -297 common symlinkat sys_symlinkat sys_symlinkat -298 common readlinkat sys_readlinkat sys_readlinkat -299 common fchmodat sys_fchmodat sys_fchmodat -300 common faccessat sys_faccessat sys_faccessat -301 common pselect6 sys_pselect6 compat_sys_pselect6_time32 -302 common ppoll sys_ppoll compat_sys_ppoll_time32 -303 common unshare sys_unshare sys_unshare -304 common set_robust_list sys_set_robust_list compat_sys_set_robust_list -305 common get_robust_list sys_get_robust_list compat_sys_get_robust_list -306 common splice sys_splice sys_splice -307 common sync_file_range sys_sync_file_range compat_sys_s390_sync_file_range -308 common tee sys_tee sys_tee -309 common vmsplice sys_vmsplice sys_vmsplice -310 common move_pages sys_move_pages sys_move_pages -311 common getcpu sys_getcpu sys_getcpu -312 common epoll_pwait sys_epoll_pwait compat_sys_epoll_pwait -313 common utimes sys_utimes sys_utimes_time32 -314 common fallocate sys_fallocate compat_sys_s390_fallocate -315 common utimensat sys_utimensat sys_utimensat_time32 -316 common signalfd sys_signalfd compat_sys_signalfd -317 common timerfd - - -318 common eventfd sys_eventfd sys_eventfd -319 common timerfd_create sys_timerfd_create sys_timerfd_create -320 common timerfd_settime sys_timerfd_settime sys_timerfd_settime32 -321 common timerfd_gettime sys_timerfd_gettime sys_timerfd_gettime32 -322 common signalfd4 sys_signalfd4 compat_sys_signalfd4 -323 common eventfd2 sys_eventfd2 sys_eventfd2 -324 common inotify_init1 sys_inotify_init1 sys_inotify_init1 -325 common pipe2 sys_pipe2 sys_pipe2 -326 common dup3 sys_dup3 sys_dup3 -327 common epoll_create1 sys_epoll_create1 sys_epoll_create1 -328 common preadv sys_preadv compat_sys_preadv -329 common pwritev sys_pwritev compat_sys_pwritev -330 common rt_tgsigqueueinfo sys_rt_tgsigqueueinfo compat_sys_rt_tgsigqueueinfo -331 common perf_event_open sys_perf_event_open sys_perf_event_open -332 common fanotify_init sys_fanotify_init sys_fanotify_init -333 common fanotify_mark sys_fanotify_mark compat_sys_fanotify_mark -334 common prlimit64 sys_prlimit64 sys_prlimit64 -335 common name_to_handle_at sys_name_to_handle_at sys_name_to_handle_at -336 common open_by_handle_at sys_open_by_handle_at compat_sys_open_by_handle_at -337 common clock_adjtime sys_clock_adjtime sys_clock_adjtime32 -338 common syncfs sys_syncfs sys_syncfs -339 common setns sys_setns sys_setns -340 common process_vm_readv sys_process_vm_readv sys_process_vm_readv -341 common process_vm_writev sys_process_vm_writev sys_process_vm_writev -342 common s390_runtime_instr sys_s390_runtime_instr sys_s390_runtime_instr -343 common kcmp sys_kcmp sys_kcmp -344 common finit_module sys_finit_module sys_finit_module -345 common sched_setattr sys_sched_setattr sys_sched_setattr -346 common sched_getattr sys_sched_getattr sys_sched_getattr -347 common renameat2 sys_renameat2 sys_renameat2 -348 common seccomp sys_seccomp sys_seccomp -349 common getrandom sys_getrandom sys_getrandom -350 common memfd_create sys_memfd_create sys_memfd_create -351 common bpf sys_bpf sys_bpf -352 common s390_pci_mmio_write sys_s390_pci_mmio_write sys_s390_pci_mmio_write -353 common s390_pci_mmio_read sys_s390_pci_mmio_read sys_s390_pci_mmio_read -354 common execveat sys_execveat compat_sys_execveat -355 common userfaultfd sys_userfaultfd sys_userfaultfd -356 common membarrier sys_membarrier sys_membarrier -357 common recvmmsg sys_recvmmsg compat_sys_recvmmsg_time32 -358 common sendmmsg sys_sendmmsg compat_sys_sendmmsg -359 common socket sys_socket sys_socket -360 common socketpair sys_socketpair sys_socketpair -361 common bind sys_bind sys_bind -362 common connect sys_connect sys_connect -363 common listen sys_listen sys_listen -364 common accept4 sys_accept4 sys_accept4 -365 common getsockopt sys_getsockopt sys_getsockopt -366 common setsockopt sys_setsockopt sys_setsockopt -367 common getsockname sys_getsockname sys_getsockname -368 common getpeername sys_getpeername sys_getpeername -369 common sendto sys_sendto sys_sendto -370 common sendmsg sys_sendmsg compat_sys_sendmsg -371 common recvfrom sys_recvfrom compat_sys_recvfrom -372 common recvmsg sys_recvmsg compat_sys_recvmsg -373 common shutdown sys_shutdown sys_shutdown -374 common mlock2 sys_mlock2 sys_mlock2 -375 common copy_file_range sys_copy_file_range sys_copy_file_range -376 common preadv2 sys_preadv2 compat_sys_preadv2 -377 common pwritev2 sys_pwritev2 compat_sys_pwritev2 -378 common s390_guarded_storage sys_s390_guarded_storage sys_s390_guarded_storage -379 common statx sys_statx sys_statx -380 common s390_sthyi sys_s390_sthyi sys_s390_sthyi -381 common kexec_file_load sys_kexec_file_load sys_kexec_file_load -382 common io_pgetevents sys_io_pgetevents compat_sys_io_pgetevents -383 common rseq sys_rseq sys_rseq -384 common pkey_mprotect sys_pkey_mprotect sys_pkey_mprotect -385 common pkey_alloc sys_pkey_alloc sys_pkey_alloc -386 common pkey_free sys_pkey_free sys_pkey_free +1 common exit sys_exit +2 common fork sys_fork +3 common read sys_read +4 common write sys_write +5 common open sys_open +6 common close sys_close +7 common restart_syscall sys_restart_syscall +8 common creat sys_creat +9 common link sys_link +10 common unlink sys_unlink +11 common execve sys_execve +12 common chdir sys_chdir +14 common mknod sys_mknod +15 common chmod sys_chmod +19 common lseek sys_lseek +20 common getpid sys_getpid +21 common mount sys_mount +22 common umount sys_oldumount +26 common ptrace sys_ptrace +27 common alarm sys_alarm +29 common pause sys_pause +30 common utime sys_utime +33 common access sys_access +34 common nice sys_nice +36 common sync sys_sync +37 common kill sys_kill +38 common rename sys_rename +39 common mkdir sys_mkdir +40 common rmdir sys_rmdir +41 common dup sys_dup +42 common pipe sys_pipe +43 common times sys_times +45 common brk sys_brk +48 common signal sys_signal +51 common acct sys_acct +52 common umount2 sys_umount +54 common ioctl sys_ioctl +55 common fcntl sys_fcntl +57 common setpgid sys_setpgid +60 common umask sys_umask +61 common chroot sys_chroot +62 common ustat sys_ustat +63 common dup2 sys_dup2 +64 common getppid sys_getppid +65 common getpgrp sys_getpgrp +66 common setsid sys_setsid +67 common sigaction sys_sigaction +72 common sigsuspend sys_sigsuspend +73 common sigpending sys_sigpending +74 common sethostname sys_sethostname +75 common setrlimit sys_setrlimit +77 common getrusage sys_getrusage +78 common gettimeofday sys_gettimeofday +79 common settimeofday sys_settimeofday +83 common symlink sys_symlink +85 common readlink sys_readlink +86 common uselib sys_uselib +87 common swapon sys_swapon +88 common reboot sys_reboot +89 common readdir sys_ni_syscall +90 common mmap sys_old_mmap +91 common munmap sys_munmap +92 common truncate sys_truncate +93 common ftruncate sys_ftruncate +94 common fchmod sys_fchmod +96 common getpriority sys_getpriority +97 common setpriority sys_setpriority +99 common statfs sys_statfs +100 common fstatfs sys_fstatfs +102 common socketcall sys_socketcall +103 common syslog sys_syslog +104 common setitimer sys_setitimer +105 common getitimer sys_getitimer +106 common stat sys_newstat +107 common lstat sys_newlstat +108 common fstat sys_newfstat +110 common lookup_dcookie sys_ni_syscall +111 common vhangup sys_vhangup +112 common idle sys_ni_syscall +114 common wait4 sys_wait4 +115 common swapoff sys_swapoff +116 common sysinfo sys_sysinfo +117 common ipc sys_s390_ipc +118 common fsync sys_fsync +119 common sigreturn sys_sigreturn +120 common clone sys_clone +121 common setdomainname sys_setdomainname +122 common uname sys_newuname +124 common adjtimex sys_adjtimex +125 common mprotect sys_mprotect +126 common sigprocmask sys_sigprocmask +127 common create_module sys_ni_syscall +128 common init_module sys_init_module +129 common delete_module sys_delete_module +130 common get_kernel_syms sys_ni_syscall +131 common quotactl sys_quotactl +132 common getpgid sys_getpgid +133 common fchdir sys_fchdir +134 common bdflush sys_ni_syscall +135 common sysfs sys_sysfs +136 common personality sys_s390_personality +137 common afs_syscall sys_ni_syscall +141 common getdents sys_getdents +142 common select sys_select +143 common flock sys_flock +144 common msync sys_msync +145 common readv sys_readv +146 common writev sys_writev +147 common getsid sys_getsid +148 common fdatasync sys_fdatasync +149 common _sysctl sys_ni_syscall +150 common mlock sys_mlock +151 common munlock sys_munlock +152 common mlockall sys_mlockall +153 common munlockall sys_munlockall +154 common sched_setparam sys_sched_setparam +155 common sched_getparam sys_sched_getparam +156 common sched_setscheduler sys_sched_setscheduler +157 common sched_getscheduler sys_sched_getscheduler +158 common sched_yield sys_sched_yield +159 common sched_get_priority_max sys_sched_get_priority_max +160 common sched_get_priority_min sys_sched_get_priority_min +161 common sched_rr_get_interval sys_sched_rr_get_interval +162 common nanosleep sys_nanosleep +163 common mremap sys_mremap +167 common query_module sys_ni_syscall +168 common poll sys_poll +169 common nfsservctl sys_ni_syscall +172 common prctl sys_prctl +173 common rt_sigreturn sys_rt_sigreturn +174 common rt_sigaction sys_rt_sigaction +175 common rt_sigprocmask sys_rt_sigprocmask +176 common rt_sigpending sys_rt_sigpending +177 common rt_sigtimedwait sys_rt_sigtimedwait +178 common rt_sigqueueinfo sys_rt_sigqueueinfo +179 common rt_sigsuspend sys_rt_sigsuspend +180 common pread64 sys_pread64 +181 common pwrite64 sys_pwrite64 +183 common getcwd sys_getcwd +184 common capget sys_capget +185 common capset sys_capset +186 common sigaltstack sys_sigaltstack +187 common sendfile sys_sendfile64 +188 common getpmsg sys_ni_syscall +189 common putpmsg sys_ni_syscall +190 common vfork sys_vfork +191 common getrlimit sys_getrlimit +198 common lchown sys_lchown +199 common getuid sys_getuid +200 common getgid sys_getgid +201 common geteuid sys_geteuid +202 common getegid sys_getegid +203 common setreuid sys_setreuid +204 common setregid sys_setregid +205 common getgroups sys_getgroups +206 common setgroups sys_setgroups +207 common fchown sys_fchown +208 common setresuid sys_setresuid +209 common getresuid sys_getresuid +210 common setresgid sys_setresgid +211 common getresgid sys_getresgid +212 common chown sys_chown +213 common setuid sys_setuid +214 common setgid sys_setgid +215 common setfsuid sys_setfsuid +216 common setfsgid sys_setfsgid +217 common pivot_root sys_pivot_root +218 common mincore sys_mincore +219 common madvise sys_madvise +220 common getdents64 sys_getdents64 +222 common readahead sys_readahead +224 common setxattr sys_setxattr +225 common lsetxattr sys_lsetxattr +226 common fsetxattr sys_fsetxattr +227 common getxattr sys_getxattr +228 common lgetxattr sys_lgetxattr +229 common fgetxattr sys_fgetxattr +230 common listxattr sys_listxattr +231 common llistxattr sys_llistxattr +232 common flistxattr sys_flistxattr +233 common removexattr sys_removexattr +234 common lremovexattr sys_lremovexattr +235 common fremovexattr sys_fremovexattr +236 common gettid sys_gettid +237 common tkill sys_tkill +238 common futex sys_futex +239 common sched_setaffinity sys_sched_setaffinity +240 common sched_getaffinity sys_sched_getaffinity +241 common tgkill sys_tgkill +243 common io_setup sys_io_setup +244 common io_destroy sys_io_destroy +245 common io_getevents sys_io_getevents +246 common io_submit sys_io_submit +247 common io_cancel sys_io_cancel +248 common exit_group sys_exit_group +249 common epoll_create sys_epoll_create +250 common epoll_ctl sys_epoll_ctl +251 common epoll_wait sys_epoll_wait +252 common set_tid_address sys_set_tid_address +253 common fadvise64 sys_fadvise64_64 +254 common timer_create sys_timer_create +255 common timer_settime sys_timer_settime +256 common timer_gettime sys_timer_gettime +257 common timer_getoverrun sys_timer_getoverrun +258 common timer_delete sys_timer_delete +259 common clock_settime sys_clock_settime +260 common clock_gettime sys_clock_gettime +261 common clock_getres sys_clock_getres +262 common clock_nanosleep sys_clock_nanosleep +265 common statfs64 sys_statfs64 +266 common fstatfs64 sys_fstatfs64 +267 common remap_file_pages sys_remap_file_pages +268 common mbind sys_mbind +269 common get_mempolicy sys_get_mempolicy +270 common set_mempolicy sys_set_mempolicy +271 common mq_open sys_mq_open +272 common mq_unlink sys_mq_unlink +273 common mq_timedsend sys_mq_timedsend +274 common mq_timedreceive sys_mq_timedreceive +275 common mq_notify sys_mq_notify +276 common mq_getsetattr sys_mq_getsetattr +277 common kexec_load sys_kexec_load +278 common add_key sys_add_key +279 common request_key sys_request_key +280 common keyctl sys_keyctl +281 common waitid sys_waitid +282 common ioprio_set sys_ioprio_set +283 common ioprio_get sys_ioprio_get +284 common inotify_init sys_inotify_init +285 common inotify_add_watch sys_inotify_add_watch +286 common inotify_rm_watch sys_inotify_rm_watch +287 common migrate_pages sys_migrate_pages +288 common openat sys_openat +289 common mkdirat sys_mkdirat +290 common mknodat sys_mknodat +291 common fchownat sys_fchownat +292 common futimesat sys_futimesat +293 common newfstatat sys_newfstatat +294 common unlinkat sys_unlinkat +295 common renameat sys_renameat +296 common linkat sys_linkat +297 common symlinkat sys_symlinkat +298 common readlinkat sys_readlinkat +299 common fchmodat sys_fchmodat +300 common faccessat sys_faccessat +301 common pselect6 sys_pselect6 +302 common ppoll sys_ppoll +303 common unshare sys_unshare +304 common set_robust_list sys_set_robust_list +305 common get_robust_list sys_get_robust_list +306 common splice sys_splice +307 common sync_file_range sys_sync_file_range +308 common tee sys_tee +309 common vmsplice sys_vmsplice +310 common move_pages sys_move_pages +311 common getcpu sys_getcpu +312 common epoll_pwait sys_epoll_pwait +313 common utimes sys_utimes +314 common fallocate sys_fallocate +315 common utimensat sys_utimensat +316 common signalfd sys_signalfd +317 common timerfd sys_ni_syscall +318 common eventfd sys_eventfd +319 common timerfd_create sys_timerfd_create +320 common timerfd_settime sys_timerfd_settime +321 common timerfd_gettime sys_timerfd_gettime +322 common signalfd4 sys_signalfd4 +323 common eventfd2 sys_eventfd2 +324 common inotify_init1 sys_inotify_init1 +325 common pipe2 sys_pipe2 +326 common dup3 sys_dup3 +327 common epoll_create1 sys_epoll_create1 +328 common preadv sys_preadv +329 common pwritev sys_pwritev +330 common rt_tgsigqueueinfo sys_rt_tgsigqueueinfo +331 common perf_event_open sys_perf_event_open +332 common fanotify_init sys_fanotify_init +333 common fanotify_mark sys_fanotify_mark +334 common prlimit64 sys_prlimit64 +335 common name_to_handle_at sys_name_to_handle_at +336 common open_by_handle_at sys_open_by_handle_at +337 common clock_adjtime sys_clock_adjtime +338 common syncfs sys_syncfs +339 common setns sys_setns +340 common process_vm_readv sys_process_vm_readv +341 common process_vm_writev sys_process_vm_writev +342 common s390_runtime_instr sys_s390_runtime_instr +343 common kcmp sys_kcmp +344 common finit_module sys_finit_module +345 common sched_setattr sys_sched_setattr +346 common sched_getattr sys_sched_getattr +347 common renameat2 sys_renameat2 +348 common seccomp sys_seccomp +349 common getrandom sys_getrandom +350 common memfd_create sys_memfd_create +351 common bpf sys_bpf +352 common s390_pci_mmio_write sys_s390_pci_mmio_write +353 common s390_pci_mmio_read sys_s390_pci_mmio_read +354 common execveat sys_execveat +355 common userfaultfd sys_userfaultfd +356 common membarrier sys_membarrier +357 common recvmmsg sys_recvmmsg +358 common sendmmsg sys_sendmmsg +359 common socket sys_socket +360 common socketpair sys_socketpair +361 common bind sys_bind +362 common connect sys_connect +363 common listen sys_listen +364 common accept4 sys_accept4 +365 common getsockopt sys_getsockopt +366 common setsockopt sys_setsockopt +367 common getsockname sys_getsockname +368 common getpeername sys_getpeername +369 common sendto sys_sendto +370 common sendmsg sys_sendmsg +371 common recvfrom sys_recvfrom +372 common recvmsg sys_recvmsg +373 common shutdown sys_shutdown +374 common mlock2 sys_mlock2 +375 common copy_file_range sys_copy_file_range +376 common preadv2 sys_preadv2 +377 common pwritev2 sys_pwritev2 +378 common s390_guarded_storage sys_s390_guarded_storage +379 common statx sys_statx +380 common s390_sthyi sys_s390_sthyi +381 common kexec_file_load sys_kexec_file_load +382 common io_pgetevents sys_io_pgetevents +383 common rseq sys_rseq +384 common pkey_mprotect sys_pkey_mprotect +385 common pkey_alloc sys_pkey_alloc +386 common pkey_free sys_pkey_free # room for arch specific syscalls -392 64 semtimedop sys_semtimedop - -393 common semget sys_semget sys_semget -394 common semctl sys_semctl compat_sys_semctl -395 common shmget sys_shmget sys_shmget -396 common shmctl sys_shmctl compat_sys_shmctl -397 common shmat sys_shmat compat_sys_shmat -398 common shmdt sys_shmdt sys_shmdt -399 common msgget sys_msgget sys_msgget -400 common msgsnd sys_msgsnd compat_sys_msgsnd -401 common msgrcv sys_msgrcv compat_sys_msgrcv -402 common msgctl sys_msgctl compat_sys_msgctl -403 32 clock_gettime64 - sys_clock_gettime -404 32 clock_settime64 - sys_clock_settime -405 32 clock_adjtime64 - sys_clock_adjtime -406 32 clock_getres_time64 - sys_clock_getres -407 32 clock_nanosleep_time64 - sys_clock_nanosleep -408 32 timer_gettime64 - sys_timer_gettime -409 32 timer_settime64 - sys_timer_settime -410 32 timerfd_gettime64 - sys_timerfd_gettime -411 32 timerfd_settime64 - sys_timerfd_settime -412 32 utimensat_time64 - sys_utimensat -413 32 pselect6_time64 - compat_sys_pselect6_time64 -414 32 ppoll_time64 - compat_sys_ppoll_time64 -416 32 io_pgetevents_time64 - compat_sys_io_pgetevents_time64 -417 32 recvmmsg_time64 - compat_sys_recvmmsg_time64 -418 32 mq_timedsend_time64 - sys_mq_timedsend -419 32 mq_timedreceive_time64 - sys_mq_timedreceive -420 32 semtimedop_time64 - sys_semtimedop -421 32 rt_sigtimedwait_time64 - compat_sys_rt_sigtimedwait_time64 -422 32 futex_time64 - sys_futex -423 32 sched_rr_get_interval_time64 - sys_sched_rr_get_interval -424 common pidfd_send_signal sys_pidfd_send_signal sys_pidfd_send_signal -425 common io_uring_setup sys_io_uring_setup sys_io_uring_setup -426 common io_uring_enter sys_io_uring_enter sys_io_uring_enter -427 common io_uring_register sys_io_uring_register sys_io_uring_register -428 common open_tree sys_open_tree sys_open_tree -429 common move_mount sys_move_mount sys_move_mount -430 common fsopen sys_fsopen sys_fsopen -431 common fsconfig sys_fsconfig sys_fsconfig -432 common fsmount sys_fsmount sys_fsmount -433 common fspick sys_fspick sys_fspick -434 common pidfd_open sys_pidfd_open sys_pidfd_open -435 common clone3 sys_clone3 sys_clone3 -436 common close_range sys_close_range sys_close_range -437 common openat2 sys_openat2 sys_openat2 -438 common pidfd_getfd sys_pidfd_getfd sys_pidfd_getfd -439 common faccessat2 sys_faccessat2 sys_faccessat2 -440 common process_madvise sys_process_madvise sys_process_madvise -441 common epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2 -442 common mount_setattr sys_mount_setattr sys_mount_setattr -443 common quotactl_fd sys_quotactl_fd sys_quotactl_fd -444 common landlock_create_ruleset sys_landlock_create_ruleset sys_landlock_create_ruleset -445 common landlock_add_rule sys_landlock_add_rule sys_landlock_add_rule -446 common landlock_restrict_self sys_landlock_restrict_self sys_landlock_restrict_self -447 common memfd_secret sys_memfd_secret sys_memfd_secret -448 common process_mrelease sys_process_mrelease sys_process_mrelease -449 common futex_waitv sys_futex_waitv sys_futex_waitv -450 common set_mempolicy_home_node sys_set_mempolicy_home_node sys_set_mempolicy_home_node -451 common cachestat sys_cachestat sys_cachestat -452 common fchmodat2 sys_fchmodat2 sys_fchmodat2 -453 common map_shadow_stack sys_map_shadow_stack sys_map_shadow_stack -454 common futex_wake sys_futex_wake sys_futex_wake -455 common futex_wait sys_futex_wait sys_futex_wait -456 common futex_requeue sys_futex_requeue sys_futex_requeue -457 common statmount sys_statmount sys_statmount -458 common listmount sys_listmount sys_listmount -459 common lsm_get_self_attr sys_lsm_get_self_attr sys_lsm_get_self_attr -460 common lsm_set_self_attr sys_lsm_set_self_attr sys_lsm_set_self_attr -461 common lsm_list_modules sys_lsm_list_modules sys_lsm_list_modules -462 common mseal sys_mseal sys_mseal -463 common setxattrat sys_setxattrat sys_setxattrat -464 common getxattrat sys_getxattrat sys_getxattrat -465 common listxattrat sys_listxattrat sys_listxattrat -466 common removexattrat sys_removexattrat sys_removexattrat -467 common open_tree_attr sys_open_tree_attr sys_open_tree_attr -468 common file_getattr sys_file_getattr sys_file_getattr -469 common file_setattr sys_file_setattr sys_file_setattr +392 common semtimedop sys_semtimedop +393 common semget sys_semget +394 common semctl sys_semctl +395 common shmget sys_shmget +396 common shmctl sys_shmctl +397 common shmat sys_shmat +398 common shmdt sys_shmdt +399 common msgget sys_msgget +400 common msgsnd sys_msgsnd +401 common msgrcv sys_msgrcv +402 common msgctl sys_msgctl +424 common pidfd_send_signal sys_pidfd_send_signal +425 common io_uring_setup sys_io_uring_setup +426 common io_uring_enter sys_io_uring_enter +427 common io_uring_register sys_io_uring_register +428 common open_tree sys_open_tree +429 common move_mount sys_move_mount +430 common fsopen sys_fsopen +431 common fsconfig sys_fsconfig +432 common fsmount sys_fsmount +433 common fspick sys_fspick +434 common pidfd_open sys_pidfd_open +435 common clone3 sys_clone3 +436 common close_range sys_close_range +437 common openat2 sys_openat2 +438 common pidfd_getfd sys_pidfd_getfd +439 common faccessat2 sys_faccessat2 +440 common process_madvise sys_process_madvise +441 common epoll_pwait2 sys_epoll_pwait2 +442 common mount_setattr sys_mount_setattr +443 common quotactl_fd sys_quotactl_fd +444 common landlock_create_ruleset sys_landlock_create_ruleset +445 common landlock_add_rule sys_landlock_add_rule +446 common landlock_restrict_self sys_landlock_restrict_self +447 common memfd_secret sys_memfd_secret +448 common process_mrelease sys_process_mrelease +449 common futex_waitv sys_futex_waitv +450 common set_mempolicy_home_node sys_set_mempolicy_home_node +451 common cachestat sys_cachestat +452 common fchmodat2 sys_fchmodat2 +453 common map_shadow_stack sys_map_shadow_stack +454 common futex_wake sys_futex_wake +455 common futex_wait sys_futex_wait +456 common futex_requeue sys_futex_requeue +457 common statmount sys_statmount +458 common listmount sys_listmount +459 common lsm_get_self_attr sys_lsm_get_self_attr +460 common lsm_set_self_attr sys_lsm_set_self_attr +461 common lsm_list_modules sys_lsm_list_modules +462 common mseal sys_mseal +463 common setxattrat sys_setxattrat +464 common getxattrat sys_getxattrat +465 common listxattrat sys_listxattrat +466 common removexattrat sys_removexattrat +467 common open_tree_attr sys_open_tree_attr +468 common file_getattr sys_file_getattr +469 common file_setattr sys_file_setattr diff --git a/arch/s390/kernel/syscalls/syscalltbl b/arch/s390/kernel/syscalls/syscalltbl deleted file mode 100755 index fbac1732f874..000000000000 --- a/arch/s390/kernel/syscalls/syscalltbl +++ /dev/null @@ -1,232 +0,0 @@ -#!/bin/sh -# SPDX-License-Identifier: GPL-2.0 -# -# Generate system call table and header files -# -# Copyright IBM Corp. 2018 -# Author(s): Hendrik Brueckner - -# -# File path to the system call table definition. -# You can set the path with the -i option. If omitted, -# system call table definitions are read from standard input. -# -SYSCALL_TBL="" - - -create_syscall_table_entries() -{ - local nr abi name entry64 entry32 _ignore - local temp=$(mktemp ${TMPDIR:-/tmp}/syscalltbl-common.XXXXXXXXX) - - ( - # - # Initialize with 0 to create an NI_SYSCALL for 0 - # - local prev_nr=0 prev_32=sys_ni_syscall prev_64=sys_ni_syscall - while read nr abi name entry64 entry32 _ignore; do - test x$entry32 = x- && entry32=sys_ni_syscall - test x$entry64 = x- && entry64=sys_ni_syscall - - if test $prev_nr -eq $nr; then - # - # Same syscall but different ABI, just update - # the respective entry point - # - case $abi in - 32) - prev_32=$entry32 - ;; - 64) - prev_64=$entry64 - ;; - esac - continue; - else - printf "%d\t%s\t%s\n" $prev_nr $prev_64 $prev_32 - fi - - prev_nr=$nr - prev_64=$entry64 - prev_32=$entry32 - done - printf "%d\t%s\t%s\n" $prev_nr $prev_64 $prev_32 - ) >> $temp - - # - # Check for duplicate syscall numbers - # - if ! cat $temp |cut -f1 |uniq -d 2>&1; then - echo "Error: generated system call table contains duplicate entries: $temp" >&2 - exit 1 - fi - - # - # Generate syscall table - # - prev_nr=0 - while read nr entry64 entry32; do - while test $prev_nr -lt $((nr - 1)); do - printf "NI_SYSCALL\n" - prev_nr=$((prev_nr + 1)) - done - if test x$entry64 = xsys_ni_syscall && - test x$entry32 = xsys_ni_syscall; then - printf "NI_SYSCALL\n" - else - printf "SYSCALL(%s,%s)\n" $entry64 $entry32 - fi - prev_nr=$nr - done < $temp - rm $temp -} - -generate_syscall_table() -{ - cat <<-EoHEADER - /* SPDX-License-Identifier: GPL-2.0 */ - /* - * Definitions for sys_call_table, each line represents an - * entry in the table in the form - * SYSCALL(64 bit syscall, 31 bit emulated syscall) - * - * This file is meant to be included from entry.S. - */ - - #define NI_SYSCALL SYSCALL(sys_ni_syscall,sys_ni_syscall) - -EoHEADER - grep -Ev '^(#|[[:blank:]]*$)' $SYSCALL_TBL \ - |sort -k1 -n \ - |create_syscall_table_entries -} - -create_header_defines() -{ - local nr abi name _ignore - - while read nr abi name _ignore; do - printf "#define __NR_%s %d\n" $name $nr - done -} - -normalize_fileguard() -{ - local fileguard="$1" - - echo "$1" |tr '[[:lower:]]' '[[:upper:]]' \ - |sed -e 's/[^A-Z0-9_]/_/g' -e 's/__/_/g' -} - -generate_syscall_header() -{ - local abis=$(echo "($1)" | tr ',' '|') - local filename="$2" - local fileguard suffix - - if test "$filename"; then - fileguard=$(normalize_fileguard "__UAPI_ASM_S390_$2") - else - case "$abis" in - *64*) suffix=64 ;; - *32*) suffix=32 ;; - esac - fileguard=$(normalize_fileguard "__UAPI_ASM_S390_SYSCALLS_$suffix") - fi - - cat <<-EoHEADER - /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef ${fileguard} - #define ${fileguard} - -EoHEADER - - grep -E "^[[:digit:]]+[[:space:]]+${abis}" $SYSCALL_TBL \ - |sort -k1 -n \ - |create_header_defines - - cat <<-EoFOOTER - - #endif /* ${fileguard} */ -EoFOOTER -} - -__max_syscall_nr() -{ - local abis=$(echo "($1)" | tr ',' '|') - - grep -E "^[[:digit:]]+[[:space:]]+${abis}" $SYSCALL_TBL \ - |sed -ne 's/^\([[:digit:]]*\)[[:space:]].*/\1/p' \ - |sort -n \ - |tail -1 -} - - -generate_syscall_nr() -{ - local abis="$1" - local max_syscall_nr num_syscalls - - max_syscall_nr=$(__max_syscall_nr "$abis") - num_syscalls=$((max_syscall_nr + 1)) - - cat <<-EoHEADER - /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ - #ifndef __ASM_S390_SYSCALLS_NR - #define __ASM_S390_SYSCALLS_NR - - #define NR_syscalls ${num_syscalls} - - #endif /* __ASM_S390_SYSCALLS_NR */ -EoHEADER -} - - -# -# Parse command line arguments -# -do_syscall_header="" -do_syscall_table="" -do_syscall_nr="" -output_file="" -abi_list="common,64" -filename="" -while getopts ":HNSXi:a:f:" arg; do - case $arg in - a) - abi_list="$OPTARG" - ;; - i) - SYSCALL_TBL="$OPTARG" - ;; - f) - filename=${OPTARG##*/} - ;; - H) - do_syscall_header=1 - ;; - N) - do_syscall_nr=1 - ;; - S) - do_syscall_table=1 - ;; - X) - set -x - ;; - :) - echo "Missing argument for -$OPTARG" >&2 - exit 1 - ;; - \?) - echo "Invalid option specified" >&2 - exit 1 - ;; - esac -done - -test "$do_syscall_header" && generate_syscall_header "$abi_list" "$filename" -test "$do_syscall_table" && generate_syscall_table -test "$do_syscall_nr" && generate_syscall_nr "$abi_list" - -exit 0 From 2a2153a2bac7d9388b661a18d49707a8d885b231 Mon Sep 17 00:00:00 2001 From: Peter Oberparleiter Date: Fri, 14 Nov 2025 15:04:20 +0100 Subject: [PATCH 78/92] s390/debug: Update description of resize operation With commit 1204777867e8 ("s390/debug: keep debug data on resize") the behavior of a debug area resize operation was changed. Update the associated documentation to reflect this change. Fixes: 1204777867e8 ("s390/debug: keep debug data on resize") Reported-by: Heiko Carstens Signed-off-by: Peter Oberparleiter Signed-off-by: Heiko Carstens --- Documentation/arch/s390/s390dbf.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Documentation/arch/s390/s390dbf.rst b/Documentation/arch/s390/s390dbf.rst index af8bdc3629e7..aad6d88974fe 100644 --- a/Documentation/arch/s390/s390dbf.rst +++ b/Documentation/arch/s390/s390dbf.rst @@ -243,9 +243,8 @@ Examples: Changing the size of debug areas ------------------------------------ -It is possible the change the size of debug areas through piping -the number of pages to the debugfs file "pages". The resize request will -also flush the debug areas. +To resize a debug area, write the desired page count to the "pages" file. +Existing data is preserved if it fits; otherwise, oldest entries are dropped. Example: From 6917f434fda346323d1269780286e9ae915bdb5e Mon Sep 17 00:00:00 2001 From: Harald Freudenberger Date: Wed, 19 Nov 2025 16:27:35 +0100 Subject: [PATCH 79/92] s390/ap: Use all-bits-one apmask/aqmask for vfio in_use() checks For the in_use() check of an updated apmask the host's aqmask was provided to the vfio function. Similar on an update of the aqmask the host's apmask was provided to the vfio in_use() function. This led to false results on the check for apmask or aqmask updates. For example with only one APQN when exactly this card is tried to be re-assigned back to the host, the in_use() check did not complain. The correct behavior is achieved with providing a full mask for aqmask when an adapter is to be checked and similar a full mask for aqmask when a domain is to be checked for usage. Signed-off-by: Harald Freudenberger Reviewed-by: Holger Dengler Signed-off-by: Heiko Carstens --- drivers/s390/crypto/ap_bus.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 82f4ac97fe97..cea7399456c6 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -1452,6 +1452,7 @@ static int __verify_card_reservations(struct device_driver *drv, void *data) int rc = 0; struct ap_driver *ap_drv = to_ap_drv(drv); unsigned long *newapm = (unsigned long *)data; + unsigned long aqm_any[BITS_TO_LONGS(AP_DOMAINS)]; /* * increase the driver's module refcounter to be sure it is not @@ -1461,7 +1462,8 @@ static int __verify_card_reservations(struct device_driver *drv, void *data) return 0; if (ap_drv->in_use) { - rc = ap_drv->in_use(newapm, ap_perms.aqm); + bitmap_fill(aqm_any, AP_DOMAINS); + rc = ap_drv->in_use(newapm, aqm_any); if (rc) rc = -EBUSY; } @@ -1544,6 +1546,7 @@ static int __verify_queue_reservations(struct device_driver *drv, void *data) int rc = 0; struct ap_driver *ap_drv = to_ap_drv(drv); unsigned long *newaqm = (unsigned long *)data; + unsigned long apm_any[BITS_TO_LONGS(AP_DEVICES)]; /* * increase the driver's module refcounter to be sure it is not @@ -1553,7 +1556,8 @@ static int __verify_queue_reservations(struct device_driver *drv, void *data) return 0; if (ap_drv->in_use) { - rc = ap_drv->in_use(ap_perms.apm, newaqm); + bitmap_fill(apm_any, AP_DEVICES); + rc = ap_drv->in_use(apm_any, newaqm); if (rc) rc = -EBUSY; } From d38a87d7c0643db61e7a3bfc3ebeea2dc2568f7e Mon Sep 17 00:00:00 2001 From: Harald Freudenberger Date: Wed, 19 Nov 2025 16:27:36 +0100 Subject: [PATCH 80/92] s390/ap: Support driver_override for AP queue devices Add a new sysfs attribute driver_override the AP queue's directory. Writing in a string overrides the default driver determination and the drivers are matched against this string instead. This overrules the driver binding determined by the apmask/aqmask bitmask fields. According to the common understanding of how the driver_override behavior shall work, there is no further checking done. Neither about the string which is given as override driver nor if this device is currently in use by an mdev device. Another patch may limit this behavior to refuse a mixed usage of the driver_override and apmask/aqmask feature. As there exists some tooling for this kind of driver_override (see package driverctl) the AP bus behavior for re-binding should be compatible to this. The steps for a driver_override are: 1) unbind the current driver from the device. For example echo "17.0005" > /sys/devices/ap/card17/17.0005/driver/unbind 2) set the new driver for this device in the sysfs driver_override attribute. For example echo "vfio_ap" > /sys//devices/ap/card17/17.0005/driver_override 3) trigger a bus reprobe of this device. For example echo "17.0005" > /sys/bus/ap/drivers_probe With the driverctl package this is more comfortable and the settings get persisted: driverctl -b ap set-override 17.0005 vfio_ap and unset with driverctl -b ap unset-override 17.0005 Signed-off-by: Harald Freudenberger Reviewed-by: Holger Dengler Signed-off-by: Heiko Carstens --- drivers/s390/crypto/ap_bus.c | 100 ++++++++++++++++++++++++--------- drivers/s390/crypto/ap_bus.h | 1 + drivers/s390/crypto/ap_queue.c | 36 ++++++++++++ 3 files changed, 110 insertions(+), 27 deletions(-) diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index cea7399456c6..2dbfd8886038 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -853,20 +853,38 @@ static int __ap_revise_reserved(struct device *dev, void *dummy) int rc, card, queue, devres, drvres; if (is_queue_dev(dev)) { - card = AP_QID_CARD(to_ap_queue(dev)->qid); - queue = AP_QID_QUEUE(to_ap_queue(dev)->qid); - mutex_lock(&ap_perms_mutex); - devres = test_bit_inv(card, ap_perms.apm) && - test_bit_inv(queue, ap_perms.aqm); - mutex_unlock(&ap_perms_mutex); - drvres = to_ap_drv(dev->driver)->flags - & AP_DRIVER_FLAG_DEFAULT; - if (!!devres != !!drvres) { - pr_debug("reprobing queue=%02x.%04x\n", card, queue); - rc = device_reprobe(dev); - if (rc) - AP_DBF_WARN("%s reprobing queue=%02x.%04x failed\n", - __func__, card, queue); + struct ap_driver *ap_drv = to_ap_drv(dev->driver); + struct ap_queue *aq = to_ap_queue(dev); + struct ap_device *ap_dev = &aq->ap_dev; + + card = AP_QID_CARD(aq->qid); + queue = AP_QID_QUEUE(aq->qid); + + if (ap_dev->driver_override) { + if (strcmp(ap_dev->driver_override, + ap_drv->driver.name)) { + pr_debug("reprobing queue=%02x.%04x\n", card, queue); + rc = device_reprobe(dev); + if (rc) { + AP_DBF_WARN("%s reprobing queue=%02x.%04x failed\n", + __func__, card, queue); + } + } + } else { + mutex_lock(&ap_perms_mutex); + devres = test_bit_inv(card, ap_perms.apm) && + test_bit_inv(queue, ap_perms.aqm); + mutex_unlock(&ap_perms_mutex); + drvres = to_ap_drv(dev->driver)->flags + & AP_DRIVER_FLAG_DEFAULT; + if (!!devres != !!drvres) { + pr_debug("reprobing queue=%02x.%04x\n", card, queue); + rc = device_reprobe(dev); + if (rc) { + AP_DBF_WARN("%s reprobing queue=%02x.%04x failed\n", + __func__, card, queue); + } + } } } @@ -891,15 +909,30 @@ static void ap_bus_revise_bindings(void) */ int ap_owned_by_def_drv(int card, int queue) { + struct ap_queue *aq; int rc = 0; if (card < 0 || card >= AP_DEVICES || queue < 0 || queue >= AP_DOMAINS) return -EINVAL; + aq = ap_get_qdev(AP_MKQID(card, queue)); + if (aq) { + const struct device_driver *drv = aq->ap_dev.device.driver; + const struct ap_driver *ap_drv = to_ap_drv(drv); + bool override = !!aq->ap_dev.driver_override; + + if (override && drv && ap_drv->flags & AP_DRIVER_FLAG_DEFAULT) + rc = 1; + put_device(&aq->ap_dev.device); + if (override) + goto out; + } + if (test_bit_inv(card, ap_perms.apm) && test_bit_inv(queue, ap_perms.aqm)) rc = 1; +out: return rc; } EXPORT_SYMBOL(ap_owned_by_def_drv); @@ -922,12 +955,10 @@ int ap_apqn_in_matrix_owned_by_def_drv(unsigned long *apm, int card, queue, rc = 0; for (card = 0; !rc && card < AP_DEVICES; card++) - if (test_bit_inv(card, apm) && - test_bit_inv(card, ap_perms.apm)) + if (test_bit_inv(card, apm)) for (queue = 0; !rc && queue < AP_DOMAINS; queue++) - if (test_bit_inv(queue, aqm) && - test_bit_inv(queue, ap_perms.aqm)) - rc = 1; + if (test_bit_inv(queue, aqm)) + rc = ap_owned_by_def_drv(card, queue); return rc; } @@ -951,13 +982,19 @@ static int ap_device_probe(struct device *dev) */ card = AP_QID_CARD(to_ap_queue(dev)->qid); queue = AP_QID_QUEUE(to_ap_queue(dev)->qid); - mutex_lock(&ap_perms_mutex); - devres = test_bit_inv(card, ap_perms.apm) && - test_bit_inv(queue, ap_perms.aqm); - mutex_unlock(&ap_perms_mutex); - drvres = ap_drv->flags & AP_DRIVER_FLAG_DEFAULT; - if (!!devres != !!drvres) - goto out; + if (ap_dev->driver_override) { + if (strcmp(ap_dev->driver_override, + ap_drv->driver.name)) + goto out; + } else { + mutex_lock(&ap_perms_mutex); + devres = test_bit_inv(card, ap_perms.apm) && + test_bit_inv(queue, ap_perms.aqm); + mutex_unlock(&ap_perms_mutex); + drvres = ap_drv->flags & AP_DRIVER_FLAG_DEFAULT; + if (!!devres != !!drvres) + goto out; + } } /* @@ -983,8 +1020,17 @@ static int ap_device_probe(struct device *dev) } out: - if (rc) + if (rc) { put_device(dev); + } else { + if (is_queue_dev(dev)) { + pr_debug("queue=%02x.%04x new driver=%s\n", + card, queue, ap_drv->driver.name); + } else { + pr_debug("card=%02x new driver=%s\n", + to_ap_card(dev)->id, ap_drv->driver.name); + } + } return rc; } diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h index 4b7ffa840563..9d54a6c5d50a 100644 --- a/drivers/s390/crypto/ap_bus.h +++ b/drivers/s390/crypto/ap_bus.h @@ -166,6 +166,7 @@ void ap_driver_unregister(struct ap_driver *); struct ap_device { struct device device; int device_type; /* AP device type. */ + const char *driver_override; }; #define to_ap_dev(x) container_of((x), struct ap_device, device) diff --git a/drivers/s390/crypto/ap_queue.c b/drivers/s390/crypto/ap_queue.c index 579e421d134c..f05ff54f4c4b 100644 --- a/drivers/s390/crypto/ap_queue.c +++ b/drivers/s390/crypto/ap_queue.c @@ -731,6 +731,41 @@ static ssize_t ap_functions_show(struct device *dev, static DEVICE_ATTR_RO(ap_functions); +static ssize_t driver_override_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct ap_queue *aq = to_ap_queue(dev); + struct ap_device *ap_dev = &aq->ap_dev; + int rc; + + device_lock(dev); + if (ap_dev->driver_override) + rc = sysfs_emit(buf, "%s\n", ap_dev->driver_override); + else + rc = sysfs_emit(buf, "\n"); + device_unlock(dev); + + return rc; +} + +static ssize_t driver_override_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct ap_queue *aq = to_ap_queue(dev); + struct ap_device *ap_dev = &aq->ap_dev; + int rc; + + rc = driver_set_override(dev, &ap_dev->driver_override, buf, count); + if (rc) + return rc; + + return count; +} + +static DEVICE_ATTR_RW(driver_override); + #ifdef CONFIG_AP_DEBUG static ssize_t states_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -843,6 +878,7 @@ static struct attribute *ap_queue_dev_attrs[] = { &dev_attr_config.attr, &dev_attr_chkstop.attr, &dev_attr_ap_functions.attr, + &dev_attr_driver_override.attr, #ifdef CONFIG_AP_DEBUG &dev_attr_states.attr, &dev_attr_last_err_rc.attr, From 8babcc2b6a75d1eced723a78cb67b3ff6abac8b0 Mon Sep 17 00:00:00 2001 From: Harald Freudenberger Date: Wed, 19 Nov 2025 16:27:37 +0100 Subject: [PATCH 81/92] s390/ap: Rename mutex ap_perms_mutex to ap_attr_mutex The mutex ap_perms_mutex was already used not only for protection of the struct ap_perms ap_perms variable but also for an consistent update of the AP bus sysfs attributes apmask and aqmask. So rename this mutex to ap_attr_mutex which better reflects the current use. This is also a preparation for an upcoming patch which will use this mutex to lock updates on a new sysfs attribute. Signed-off-by: Harald Freudenberger Reviewed-by: Holger Dengler Signed-off-by: Heiko Carstens --- drivers/s390/crypto/ap_bus.c | 40 +++++++++++++++------------- drivers/s390/crypto/ap_bus.h | 2 +- drivers/s390/crypto/vfio_ap_ops.c | 14 +++++----- drivers/s390/crypto/zcrypt_api.c | 44 +++++++++++++++---------------- 4 files changed, 52 insertions(+), 48 deletions(-) diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 2dbfd8886038..3781b970fe61 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -86,8 +86,12 @@ DEFINE_SPINLOCK(ap_queues_lock); /* Default permissions (ioctl, card and domain masking) */ struct ap_perms ap_perms; EXPORT_SYMBOL(ap_perms); -DEFINE_MUTEX(ap_perms_mutex); -EXPORT_SYMBOL(ap_perms_mutex); +/* + * Mutex for consistent read and write of the ap_perms struct + * and the ap bus sysfs attributes apmask and aqmask. + */ +DEFINE_MUTEX(ap_attr_mutex); +EXPORT_SYMBOL(ap_attr_mutex); /* # of bindings complete since init */ static atomic64_t ap_bindings_complete_count = ATOMIC64_INIT(0); @@ -871,10 +875,10 @@ static int __ap_revise_reserved(struct device *dev, void *dummy) } } } else { - mutex_lock(&ap_perms_mutex); + mutex_lock(&ap_attr_mutex); devres = test_bit_inv(card, ap_perms.apm) && test_bit_inv(queue, ap_perms.aqm); - mutex_unlock(&ap_perms_mutex); + mutex_unlock(&ap_attr_mutex); drvres = to_ap_drv(dev->driver)->flags & AP_DRIVER_FLAG_DEFAULT; if (!!devres != !!drvres) { @@ -902,7 +906,7 @@ static void ap_bus_revise_bindings(void) * @card: the APID of the adapter card to check * @queue: the APQI of the queue to check * - * Note: the ap_perms_mutex must be locked by the caller of this function. + * Note: the ap_attr_mutex must be locked by the caller of this function. * * Return: an int specifying whether the AP adapter is reserved for the host (1) * or not (0). @@ -944,7 +948,7 @@ EXPORT_SYMBOL(ap_owned_by_def_drv); * @apm: a bitmap specifying a set of APIDs comprising the APQNs to check * @aqm: a bitmap specifying a set of APQIs comprising the APQNs to check * - * Note: the ap_perms_mutex must be locked by the caller of this function. + * Note: the ap_attr_mutex must be locked by the caller of this function. * * Return: an int specifying whether each APQN is reserved for the host (1) or * not (0) @@ -987,10 +991,10 @@ static int ap_device_probe(struct device *dev) ap_drv->driver.name)) goto out; } else { - mutex_lock(&ap_perms_mutex); + mutex_lock(&ap_attr_mutex); devres = test_bit_inv(card, ap_perms.apm) && test_bit_inv(queue, ap_perms.aqm); - mutex_unlock(&ap_perms_mutex); + mutex_unlock(&ap_attr_mutex); drvres = ap_drv->flags & AP_DRIVER_FLAG_DEFAULT; if (!!devres != !!drvres) goto out; @@ -1483,12 +1487,12 @@ static ssize_t apmask_show(const struct bus_type *bus, char *buf) { int rc; - if (mutex_lock_interruptible(&ap_perms_mutex)) + if (mutex_lock_interruptible(&ap_attr_mutex)) return -ERESTARTSYS; rc = sysfs_emit(buf, "0x%016lx%016lx%016lx%016lx\n", ap_perms.apm[0], ap_perms.apm[1], ap_perms.apm[2], ap_perms.apm[3]); - mutex_unlock(&ap_perms_mutex); + mutex_unlock(&ap_attr_mutex); return rc; } @@ -1547,7 +1551,7 @@ static ssize_t apmask_store(const struct bus_type *bus, const char *buf, int rc, changes = 0; DECLARE_BITMAP(newapm, AP_DEVICES); - if (mutex_lock_interruptible(&ap_perms_mutex)) + if (mutex_lock_interruptible(&ap_attr_mutex)) return -ERESTARTSYS; rc = ap_parse_bitmap_str(buf, ap_perms.apm, AP_DEVICES, newapm); @@ -1559,7 +1563,7 @@ static ssize_t apmask_store(const struct bus_type *bus, const char *buf, rc = apmask_commit(newapm); done: - mutex_unlock(&ap_perms_mutex); + mutex_unlock(&ap_attr_mutex); if (rc) return rc; @@ -1577,12 +1581,12 @@ static ssize_t aqmask_show(const struct bus_type *bus, char *buf) { int rc; - if (mutex_lock_interruptible(&ap_perms_mutex)) + if (mutex_lock_interruptible(&ap_attr_mutex)) return -ERESTARTSYS; rc = sysfs_emit(buf, "0x%016lx%016lx%016lx%016lx\n", ap_perms.aqm[0], ap_perms.aqm[1], ap_perms.aqm[2], ap_perms.aqm[3]); - mutex_unlock(&ap_perms_mutex); + mutex_unlock(&ap_attr_mutex); return rc; } @@ -1641,7 +1645,7 @@ static ssize_t aqmask_store(const struct bus_type *bus, const char *buf, int rc, changes = 0; DECLARE_BITMAP(newaqm, AP_DOMAINS); - if (mutex_lock_interruptible(&ap_perms_mutex)) + if (mutex_lock_interruptible(&ap_attr_mutex)) return -ERESTARTSYS; rc = ap_parse_bitmap_str(buf, ap_perms.aqm, AP_DOMAINS, newaqm); @@ -1653,7 +1657,7 @@ static ssize_t aqmask_store(const struct bus_type *bus, const char *buf, rc = aqmask_commit(newaqm); done: - mutex_unlock(&ap_perms_mutex); + mutex_unlock(&ap_attr_mutex); if (rc) return rc; @@ -2524,14 +2528,14 @@ static void __init ap_perms_init(void) if (apm_str) { memset(&ap_perms.apm, 0, sizeof(ap_perms.apm)); ap_parse_mask_str(apm_str, ap_perms.apm, AP_DEVICES, - &ap_perms_mutex); + &ap_attr_mutex); } /* aqm kernel parameter string */ if (aqm_str) { memset(&ap_perms.aqm, 0, sizeof(ap_perms.aqm)); ap_parse_mask_str(aqm_str, ap_perms.aqm, AP_DOMAINS, - &ap_perms_mutex); + &ap_attr_mutex); } } diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h index 9d54a6c5d50a..2b8804fc68b4 100644 --- a/drivers/s390/crypto/ap_bus.h +++ b/drivers/s390/crypto/ap_bus.h @@ -281,7 +281,7 @@ struct ap_perms { }; extern struct ap_perms ap_perms; -extern struct mutex ap_perms_mutex; +extern struct mutex ap_attr_mutex; /* * Get ap_queue device for this qid. diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c index eb5ff49f6fe7..48da32ad0493 100644 --- a/drivers/s390/crypto/vfio_ap_ops.c +++ b/drivers/s390/crypto/vfio_ap_ops.c @@ -968,7 +968,7 @@ static int vfio_ap_mdev_verify_no_sharing(struct ap_matrix_mdev *assignee, * * Return: One of the following values: * o the error returned from the ap_apqn_in_matrix_owned_by_def_drv() function, - * most likely -EBUSY indicating the ap_perms_mutex lock is already held. + * most likely -EBUSY indicating the ap_attr_mutex lock is already held. * o EADDRNOTAVAIL if an APQN assigned to @matrix_mdev is reserved for the * zcrypt default driver. * o EADDRINUSE if an APQN assigned to @matrix_mdev is assigned to another mdev @@ -1079,7 +1079,7 @@ static ssize_t assign_adapter_store(struct device *dev, DECLARE_BITMAP(apm_filtered, AP_DEVICES); struct ap_matrix_mdev *matrix_mdev = dev_get_drvdata(dev); - mutex_lock(&ap_perms_mutex); + mutex_lock(&ap_attr_mutex); get_update_locks_for_mdev(matrix_mdev); ret = kstrtoul(buf, 0, &apid); @@ -1114,7 +1114,7 @@ static ssize_t assign_adapter_store(struct device *dev, ret = count; done: release_update_locks_for_mdev(matrix_mdev); - mutex_unlock(&ap_perms_mutex); + mutex_unlock(&ap_attr_mutex); return ret; } @@ -1303,7 +1303,7 @@ static ssize_t assign_domain_store(struct device *dev, DECLARE_BITMAP(apm_filtered, AP_DEVICES); struct ap_matrix_mdev *matrix_mdev = dev_get_drvdata(dev); - mutex_lock(&ap_perms_mutex); + mutex_lock(&ap_attr_mutex); get_update_locks_for_mdev(matrix_mdev); ret = kstrtoul(buf, 0, &apqi); @@ -1338,7 +1338,7 @@ static ssize_t assign_domain_store(struct device *dev, ret = count; done: release_update_locks_for_mdev(matrix_mdev); - mutex_unlock(&ap_perms_mutex); + mutex_unlock(&ap_attr_mutex); return ret; } @@ -1718,7 +1718,7 @@ static ssize_t ap_config_store(struct device *dev, struct device_attribute *attr return -ENOMEM; rest = newbuf; - mutex_lock(&ap_perms_mutex); + mutex_lock(&ap_attr_mutex); get_update_locks_for_mdev(matrix_mdev); /* Save old state */ @@ -1779,7 +1779,7 @@ static ssize_t ap_config_store(struct device *dev, struct device_attribute *attr } out: release_update_locks_for_mdev(matrix_mdev); - mutex_unlock(&ap_perms_mutex); + mutex_unlock(&ap_attr_mutex); kfree(newbuf); return rc; } diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c index 351934f818de..de93a953d380 100644 --- a/drivers/s390/crypto/zcrypt_api.c +++ b/drivers/s390/crypto/zcrypt_api.c @@ -162,7 +162,7 @@ static ssize_t ioctlmask_show(struct device *dev, struct zcdn_device *zcdndev = to_zcdn_dev(dev); int i, n; - if (mutex_lock_interruptible(&ap_perms_mutex)) + if (mutex_lock_interruptible(&ap_attr_mutex)) return -ERESTARTSYS; n = sysfs_emit(buf, "0x"); @@ -170,7 +170,7 @@ static ssize_t ioctlmask_show(struct device *dev, n += sysfs_emit_at(buf, n, "%016lx", zcdndev->perms.ioctlm[i]); n += sysfs_emit_at(buf, n, "\n"); - mutex_unlock(&ap_perms_mutex); + mutex_unlock(&ap_attr_mutex); return n; } @@ -183,7 +183,7 @@ static ssize_t ioctlmask_store(struct device *dev, struct zcdn_device *zcdndev = to_zcdn_dev(dev); rc = ap_parse_mask_str(buf, zcdndev->perms.ioctlm, - AP_IOCTLS, &ap_perms_mutex); + AP_IOCTLS, &ap_attr_mutex); if (rc) return rc; @@ -199,7 +199,7 @@ static ssize_t apmask_show(struct device *dev, struct zcdn_device *zcdndev = to_zcdn_dev(dev); int i, n; - if (mutex_lock_interruptible(&ap_perms_mutex)) + if (mutex_lock_interruptible(&ap_attr_mutex)) return -ERESTARTSYS; n = sysfs_emit(buf, "0x"); @@ -207,7 +207,7 @@ static ssize_t apmask_show(struct device *dev, n += sysfs_emit_at(buf, n, "%016lx", zcdndev->perms.apm[i]); n += sysfs_emit_at(buf, n, "\n"); - mutex_unlock(&ap_perms_mutex); + mutex_unlock(&ap_attr_mutex); return n; } @@ -220,7 +220,7 @@ static ssize_t apmask_store(struct device *dev, struct zcdn_device *zcdndev = to_zcdn_dev(dev); rc = ap_parse_mask_str(buf, zcdndev->perms.apm, - AP_DEVICES, &ap_perms_mutex); + AP_DEVICES, &ap_attr_mutex); if (rc) return rc; @@ -236,7 +236,7 @@ static ssize_t aqmask_show(struct device *dev, struct zcdn_device *zcdndev = to_zcdn_dev(dev); int i, n; - if (mutex_lock_interruptible(&ap_perms_mutex)) + if (mutex_lock_interruptible(&ap_attr_mutex)) return -ERESTARTSYS; n = sysfs_emit(buf, "0x"); @@ -244,7 +244,7 @@ static ssize_t aqmask_show(struct device *dev, n += sysfs_emit_at(buf, n, "%016lx", zcdndev->perms.aqm[i]); n += sysfs_emit_at(buf, n, "\n"); - mutex_unlock(&ap_perms_mutex); + mutex_unlock(&ap_attr_mutex); return n; } @@ -257,7 +257,7 @@ static ssize_t aqmask_store(struct device *dev, struct zcdn_device *zcdndev = to_zcdn_dev(dev); rc = ap_parse_mask_str(buf, zcdndev->perms.aqm, - AP_DOMAINS, &ap_perms_mutex); + AP_DOMAINS, &ap_attr_mutex); if (rc) return rc; @@ -273,7 +273,7 @@ static ssize_t admask_show(struct device *dev, struct zcdn_device *zcdndev = to_zcdn_dev(dev); int i, n; - if (mutex_lock_interruptible(&ap_perms_mutex)) + if (mutex_lock_interruptible(&ap_attr_mutex)) return -ERESTARTSYS; n = sysfs_emit(buf, "0x"); @@ -281,7 +281,7 @@ static ssize_t admask_show(struct device *dev, n += sysfs_emit_at(buf, n, "%016lx", zcdndev->perms.adm[i]); n += sysfs_emit_at(buf, n, "\n"); - mutex_unlock(&ap_perms_mutex); + mutex_unlock(&ap_attr_mutex); return n; } @@ -294,7 +294,7 @@ static ssize_t admask_store(struct device *dev, struct zcdn_device *zcdndev = to_zcdn_dev(dev); rc = ap_parse_mask_str(buf, zcdndev->perms.adm, - AP_DOMAINS, &ap_perms_mutex); + AP_DOMAINS, &ap_attr_mutex); if (rc) return rc; @@ -370,7 +370,7 @@ static int zcdn_create(const char *name) int i, rc = 0; struct zcdn_device *zcdndev; - if (mutex_lock_interruptible(&ap_perms_mutex)) + if (mutex_lock_interruptible(&ap_attr_mutex)) return -ERESTARTSYS; /* check if device node with this name already exists */ @@ -425,7 +425,7 @@ static int zcdn_create(const char *name) __func__, MAJOR(devt), MINOR(devt)); unlockout: - mutex_unlock(&ap_perms_mutex); + mutex_unlock(&ap_attr_mutex); return rc; } @@ -434,7 +434,7 @@ static int zcdn_destroy(const char *name) int rc = 0; struct zcdn_device *zcdndev; - if (mutex_lock_interruptible(&ap_perms_mutex)) + if (mutex_lock_interruptible(&ap_attr_mutex)) return -ERESTARTSYS; /* try to find this zcdn device */ @@ -452,7 +452,7 @@ static int zcdn_destroy(const char *name) device_unregister(&zcdndev->device); unlockout: - mutex_unlock(&ap_perms_mutex); + mutex_unlock(&ap_attr_mutex); return rc; } @@ -462,7 +462,7 @@ static void zcdn_destroy_all(void) dev_t devt; struct zcdn_device *zcdndev; - mutex_lock(&ap_perms_mutex); + mutex_lock(&ap_attr_mutex); for (i = 0; i < ZCRYPT_MAX_MINOR_NODES; i++) { devt = MKDEV(MAJOR(zcrypt_devt), MINOR(zcrypt_devt) + i); zcdndev = find_zcdndev_by_devt(devt); @@ -471,7 +471,7 @@ static void zcdn_destroy_all(void) device_unregister(&zcdndev->device); } } - mutex_unlock(&ap_perms_mutex); + mutex_unlock(&ap_attr_mutex); } /* @@ -508,11 +508,11 @@ static int zcrypt_open(struct inode *inode, struct file *filp) if (filp->f_inode->i_cdev == &zcrypt_cdev) { struct zcdn_device *zcdndev; - if (mutex_lock_interruptible(&ap_perms_mutex)) + if (mutex_lock_interruptible(&ap_attr_mutex)) return -ERESTARTSYS; zcdndev = find_zcdndev_by_devt(filp->f_inode->i_rdev); /* find returns a reference, no get_device() needed */ - mutex_unlock(&ap_perms_mutex); + mutex_unlock(&ap_attr_mutex); if (zcdndev) perms = &zcdndev->perms; } @@ -532,9 +532,9 @@ static int zcrypt_release(struct inode *inode, struct file *filp) if (filp->f_inode->i_cdev == &zcrypt_cdev) { struct zcdn_device *zcdndev; - mutex_lock(&ap_perms_mutex); + mutex_lock(&ap_attr_mutex); zcdndev = find_zcdndev_by_devt(filp->f_inode->i_rdev); - mutex_unlock(&ap_perms_mutex); + mutex_unlock(&ap_attr_mutex); if (zcdndev) { /* 2 puts here: one for find, one for open */ put_device(&zcdndev->device); From 46030379f13c3f07c699dcaf034a50f023f77925 Mon Sep 17 00:00:00 2001 From: Harald Freudenberger Date: Wed, 19 Nov 2025 16:27:38 +0100 Subject: [PATCH 82/92] s390/ap: Restrict driver_override versus apmask and aqmask use Introduce a restriction for the driver_override feature versus apmask and aqmask: - driver_override is only allowed when the apmask and aqmask values both are default (=0xffff..ffff). - apmask and aqmask modifications are only allowed when there is no driver_override on any AP device active. So in the end the user is restricted to choose to either use apmask/apmask to divide the AP devices into host owned and vfio owned or use the driver_override feature but not mix these two approaches. Signed-off-by: Harald Freudenberger Reviewed-by: Holger Dengler Signed-off-by: Heiko Carstens --- drivers/s390/crypto/ap_bus.c | 37 +++++++++++++++++++++++++++++++--- drivers/s390/crypto/ap_bus.h | 2 ++ drivers/s390/crypto/ap_queue.c | 23 ++++++++++++++++++--- 3 files changed, 56 insertions(+), 6 deletions(-) diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 3781b970fe61..e4bd4f79aaa3 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -86,8 +86,13 @@ DEFINE_SPINLOCK(ap_queues_lock); /* Default permissions (ioctl, card and domain masking) */ struct ap_perms ap_perms; EXPORT_SYMBOL(ap_perms); +/* true if apmask and/or aqmask are NOT default */ +bool ap_apmask_aqmask_in_use; +/* counter for how many driver_overrides are currently active */ +int ap_driver_override_ctr; /* - * Mutex for consistent read and write of the ap_perms struct + * Mutex for consistent read and write of the ap_perms struct, + * ap_apmask_aqmask_in_use, ap_driver_override_ctr * and the ap bus sysfs attributes apmask and aqmask. */ DEFINE_MUTEX(ap_attr_mutex); @@ -1542,18 +1547,31 @@ static int apmask_commit(unsigned long *newapm) memcpy(ap_perms.apm, newapm, APMASKSIZE); + /* + * Update ap_apmask_aqmask_in_use. Note that the + * ap_attr_mutex has to be obtained here. + */ + ap_apmask_aqmask_in_use = + bitmap_full(ap_perms.apm, AP_DEVICES) && + bitmap_full(ap_perms.aqm, AP_DOMAINS) ? + false : true; + return 0; } static ssize_t apmask_store(const struct bus_type *bus, const char *buf, size_t count) { - int rc, changes = 0; DECLARE_BITMAP(newapm, AP_DEVICES); + int rc = -EINVAL, changes = 0; if (mutex_lock_interruptible(&ap_attr_mutex)) return -ERESTARTSYS; + /* Do not allow apmask/aqmask if driver override is active */ + if (ap_driver_override_ctr) + goto done; + rc = ap_parse_bitmap_str(buf, ap_perms.apm, AP_DEVICES, newapm); if (rc) goto done; @@ -1636,18 +1654,31 @@ static int aqmask_commit(unsigned long *newaqm) memcpy(ap_perms.aqm, newaqm, AQMASKSIZE); + /* + * Update ap_apmask_aqmask_in_use. Note that the + * ap_attr_mutex has to be obtained here. + */ + ap_apmask_aqmask_in_use = + bitmap_full(ap_perms.apm, AP_DEVICES) && + bitmap_full(ap_perms.aqm, AP_DOMAINS) ? + false : true; + return 0; } static ssize_t aqmask_store(const struct bus_type *bus, const char *buf, size_t count) { - int rc, changes = 0; DECLARE_BITMAP(newaqm, AP_DOMAINS); + int rc = -EINVAL, changes = 0; if (mutex_lock_interruptible(&ap_attr_mutex)) return -ERESTARTSYS; + /* Do not allow apmask/aqmask if driver override is active */ + if (ap_driver_override_ctr) + goto done; + rc = ap_parse_bitmap_str(buf, ap_perms.aqm, AP_DOMAINS, newaqm); if (rc) goto done; diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h index 2b8804fc68b4..51e08f27bd75 100644 --- a/drivers/s390/crypto/ap_bus.h +++ b/drivers/s390/crypto/ap_bus.h @@ -281,6 +281,8 @@ struct ap_perms { }; extern struct ap_perms ap_perms; +extern bool ap_apmask_aqmask_in_use; +extern int ap_driver_override_ctr; extern struct mutex ap_attr_mutex; /* diff --git a/drivers/s390/crypto/ap_queue.c b/drivers/s390/crypto/ap_queue.c index f05ff54f4c4b..4fe443d30f9b 100644 --- a/drivers/s390/crypto/ap_queue.c +++ b/drivers/s390/crypto/ap_queue.c @@ -755,13 +755,30 @@ static ssize_t driver_override_store(struct device *dev, { struct ap_queue *aq = to_ap_queue(dev); struct ap_device *ap_dev = &aq->ap_dev; - int rc; + int rc = -EINVAL; + bool old_value; + if (mutex_lock_interruptible(&ap_attr_mutex)) + return -ERESTARTSYS; + + /* Do not allow driver override if apmask/aqmask is in use */ + if (ap_apmask_aqmask_in_use) + goto out; + + old_value = ap_dev->driver_override ? true : false; rc = driver_set_override(dev, &ap_dev->driver_override, buf, count); if (rc) - return rc; + goto out; + if (old_value && !ap_dev->driver_override) + --ap_driver_override_ctr; + else if (!old_value && ap_dev->driver_override) + ++ap_driver_override_ctr; - return count; + rc = count; + +out: + mutex_unlock(&ap_attr_mutex); + return rc; } static DEVICE_ATTR_RW(driver_override); From e950d1f84d3c16e86dd1b6066c3ac3958099fa79 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 19 Nov 2025 15:37:56 +0100 Subject: [PATCH 83/92] s390/percpu: Get rid of ARCH_MODULE_NEEDS_WEAK_PER_CPU Since the rework of the kernel virtual address space [1] the module area and the kernel image are within the same 4GB area. Therefore there is no need for the weak per cpu workaround for modules anymore. Remove it. [1] commit c98d2ecae08f ("s390/mm: Uncouple physical vs virtual address spaces") Acked-by: Alexander Gordeev Signed-off-by: Heiko Carstens --- arch/s390/Kconfig | 1 - arch/s390/include/asm/percpu.h | 8 -------- include/linux/percpu-defs.h | 2 +- 3 files changed, 1 insertion(+), 10 deletions(-) diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 9914db771e45..cb143bf782f8 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -140,7 +140,6 @@ config S390 select ARCH_INLINE_WRITE_UNLOCK_IRQ select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE select ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE - select ARCH_MODULE_NEEDS_WEAK_PER_CPU select ARCH_STACKWALK select ARCH_SUPPORTS_ATOMIC_RMW select ARCH_SUPPORTS_DEBUG_PAGEALLOC diff --git a/arch/s390/include/asm/percpu.h b/arch/s390/include/asm/percpu.h index 965886dfe954..5899f57f17d1 100644 --- a/arch/s390/include/asm/percpu.h +++ b/arch/s390/include/asm/percpu.h @@ -12,14 +12,6 @@ */ #define __my_cpu_offset get_lowcore()->percpu_offset -/* - * For 64 bit module code, the module may be more than 4G above the - * per cpu area, use weak definitions to force the compiler to - * generate external references. - * Therefore, we have enabled CONFIG_ARCH_MODULE_NEEDS_WEAK_PER_CPU - * in the Kconfig. - */ - /* * We use a compare-and-swap loop since that uses less cpu cycles than * disabling and enabling interrupts like the generic variant would do. diff --git a/include/linux/percpu-defs.h b/include/linux/percpu-defs.h index 12d90360f6db..43c854a273c3 100644 --- a/include/linux/percpu-defs.h +++ b/include/linux/percpu-defs.h @@ -52,7 +52,7 @@ __section(".discard") __attribute__((unused)) /* - * s390 and alpha modules require percpu variables to be defined as + * alpha modules require percpu variables to be defined as * weak to force the compiler to generate GOT based external * references for them. This is necessary because percpu sections * will be located outside of the usually addressable area. From c3d17464f0262c9e3c156d4c6306e32cf530fa47 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 20 Nov 2025 16:30:53 +0100 Subject: [PATCH 84/92] s390: Remove KMSG_COMPONENT macro The KMSG_COMPONENT macro is a leftover of the s390 specific "kernel message catalog" which never made it upstream. Remove the macro in order to get rid of a pointless indirection. Replace all users with the string it defines. In almost all cases this leads to a simple replacement like this: - #define KMSG_COMPONENT "appldata" - #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt + #define pr_fmt(fmt) "appldata: " fmt Except for some special cases this is just mechanical/scripted work. Acked-by: Thomas Richter Signed-off-by: Heiko Carstens --- arch/s390/appldata/appldata_base.c | 3 +-- arch/s390/appldata/appldata_os.c | 3 +-- arch/s390/crypto/aes_s390.c | 3 +-- arch/s390/crypto/hmac_s390.c | 3 +-- arch/s390/crypto/paes_s390.c | 3 +-- arch/s390/crypto/phmac_s390.c | 3 +-- arch/s390/crypto/prng.c | 3 +-- arch/s390/hypfs/hypfs_diag.c | 3 +-- arch/s390/hypfs/hypfs_diag_fs.c | 3 +-- arch/s390/hypfs/inode.c | 3 +-- arch/s390/kernel/cpacf.c | 3 +-- arch/s390/kernel/cpcmd.c | 3 +-- arch/s390/kernel/debug.c | 3 +-- arch/s390/kernel/early.c | 3 +-- arch/s390/kernel/hiperdispatch.c | 3 +-- arch/s390/kernel/os_info.c | 3 +-- arch/s390/kernel/perf_cpum_cf.c | 5 ++--- arch/s390/kernel/perf_cpum_sf.c | 5 ++--- arch/s390/kernel/perf_event.c | 3 +-- arch/s390/kernel/perf_pai.c | 7 +++---- arch/s390/kernel/processor.c | 3 +-- arch/s390/kernel/setup.c | 3 +-- arch/s390/kernel/smp.c | 3 +-- arch/s390/kernel/time.c | 3 +-- arch/s390/kernel/topology.c | 3 +-- arch/s390/kernel/uv.c | 3 +-- arch/s390/kvm/interrupt.c | 3 +-- arch/s390/kvm/kvm-s390.c | 3 +-- arch/s390/mm/extmem.c | 3 +-- arch/s390/mm/hugetlbpage.c | 3 +-- arch/s390/net/bpf_jit_comp.c | 3 +-- arch/s390/pci/pci.c | 3 +-- arch/s390/pci/pci_bus.c | 3 +-- arch/s390/pci/pci_clp.c | 3 +-- arch/s390/pci/pci_debug.c | 3 +-- arch/s390/pci/pci_event.c | 3 +-- arch/s390/pci/pci_iov.c | 3 +-- arch/s390/pci/pci_irq.c | 3 +-- arch/s390/pci/pci_report.c | 3 +-- arch/s390/pci/pci_sysfs.c | 3 +-- drivers/char/hw_random/s390-trng.c | 3 +-- drivers/pci/hotplug/s390_pci_hpc.c | 3 +-- drivers/s390/block/dasd_fba.c | 1 - drivers/s390/block/dcssblk.c | 3 +-- drivers/s390/block/scm_blk.c | 3 +-- drivers/s390/block/scm_drv.c | 3 +-- drivers/s390/char/diag_ftp.c | 3 +-- drivers/s390/char/hmcdrv_cache.c | 3 +-- drivers/s390/char/hmcdrv_dev.c | 3 +-- drivers/s390/char/hmcdrv_ftp.c | 3 +-- drivers/s390/char/hmcdrv_mod.c | 3 +-- drivers/s390/char/monreader.c | 3 +-- drivers/s390/char/monwriter.c | 3 +-- drivers/s390/char/sclp_ap.c | 3 +-- drivers/s390/char/sclp_cmd.c | 3 +-- drivers/s390/char/sclp_config.c | 3 +-- drivers/s390/char/sclp_cpi_sys.c | 3 +-- drivers/s390/char/sclp_early.c | 3 +-- drivers/s390/char/sclp_ftp.c | 3 +-- drivers/s390/char/sclp_mem.c | 3 +-- drivers/s390/char/sclp_ocf.c | 3 +-- drivers/s390/char/sclp_pci.c | 3 +-- drivers/s390/char/sclp_sd.c | 3 +-- drivers/s390/char/sclp_sdias.c | 3 +-- drivers/s390/char/tape_34xx.c | 3 +-- drivers/s390/char/tape_3590.c | 3 +-- drivers/s390/char/tape_char.c | 3 +-- drivers/s390/char/tape_class.c | 3 +-- drivers/s390/char/tape_core.c | 3 +-- drivers/s390/char/tape_proc.c | 3 +-- drivers/s390/char/tape_std.c | 3 +-- drivers/s390/char/vmlogrdr.c | 3 +-- drivers/s390/char/vmur.c | 3 +-- drivers/s390/char/zcore.c | 3 +-- drivers/s390/cio/blacklist.c | 3 +-- drivers/s390/cio/ccwreq.c | 3 +-- drivers/s390/cio/chsc.c | 3 +-- drivers/s390/cio/cio.c | 3 +-- drivers/s390/cio/cio_inject.c | 3 +-- drivers/s390/cio/cmf.c | 3 +-- drivers/s390/cio/css.c | 3 +-- drivers/s390/cio/device.c | 3 +-- drivers/s390/crypto/ap_bus.c | 3 +-- drivers/s390/crypto/ap_card.c | 3 +-- drivers/s390/crypto/ap_queue.c | 3 +-- drivers/s390/crypto/pkey_api.c | 3 +-- drivers/s390/crypto/pkey_base.c | 3 +-- drivers/s390/crypto/pkey_cca.c | 3 +-- drivers/s390/crypto/pkey_ep11.c | 3 +-- drivers/s390/crypto/pkey_pckmo.c | 3 +-- drivers/s390/crypto/pkey_sysfs.c | 3 +-- drivers/s390/crypto/pkey_uv.c | 3 +-- drivers/s390/crypto/zcrypt_api.c | 3 +-- drivers/s390/crypto/zcrypt_ccamisc.c | 3 +-- drivers/s390/crypto/zcrypt_ep11misc.c | 3 +-- drivers/s390/crypto/zcrypt_msgtype50.c | 3 +-- drivers/s390/crypto/zcrypt_msgtype6.c | 3 +-- drivers/s390/net/ctcm_fsms.c | 3 +-- drivers/s390/net/ctcm_main.c | 3 +-- drivers/s390/net/ctcm_mpc.c | 3 +-- drivers/s390/net/ctcm_sysfs.c | 3 +-- drivers/s390/net/ism_drv.c | 3 +-- drivers/s390/net/qeth_core_main.c | 3 +-- drivers/s390/net/qeth_core_sys.c | 3 +-- drivers/s390/net/qeth_ethtool.c | 3 +-- drivers/s390/net/qeth_l2_main.c | 3 +-- drivers/s390/net/qeth_l3_main.c | 3 +-- drivers/s390/net/smsgiucv_app.c | 5 ++--- drivers/s390/scsi/zfcp_aux.c | 3 +-- drivers/s390/scsi/zfcp_ccw.c | 3 +-- drivers/s390/scsi/zfcp_dbf.c | 3 +-- drivers/s390/scsi/zfcp_erp.c | 3 +-- drivers/s390/scsi/zfcp_fc.c | 3 +-- drivers/s390/scsi/zfcp_fsf.c | 3 +-- drivers/s390/scsi/zfcp_qdio.c | 3 +-- drivers/s390/scsi/zfcp_scsi.c | 3 +-- drivers/s390/scsi/zfcp_sysfs.c | 3 +-- 117 files changed, 121 insertions(+), 238 deletions(-) diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c index ad2b0baa527c..feb43db63f30 100644 --- a/arch/s390/appldata/appldata_base.c +++ b/arch/s390/appldata/appldata_base.c @@ -9,8 +9,7 @@ * Author: Gerald Schaefer */ -#define KMSG_COMPONENT "appldata" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "appldata: " fmt #include #include diff --git a/arch/s390/appldata/appldata_os.c b/arch/s390/appldata/appldata_os.c index a363d30ce739..137d4e7e1e9a 100644 --- a/arch/s390/appldata/appldata_os.c +++ b/arch/s390/appldata/appldata_os.c @@ -8,8 +8,7 @@ * Author: Gerald Schaefer */ -#define KMSG_COMPONENT "appldata" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "appldata: " fmt #include #include diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c index 5d36f4020dfa..d0a295435680 100644 --- a/arch/s390/crypto/aes_s390.c +++ b/arch/s390/crypto/aes_s390.c @@ -14,8 +14,7 @@ * Derived from "crypto/aes_generic.c" */ -#define KMSG_COMPONENT "aes_s390" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "aes_s390: " fmt #include #include diff --git a/arch/s390/crypto/hmac_s390.c b/arch/s390/crypto/hmac_s390.c index 58444da9b004..f8cd09f341d4 100644 --- a/arch/s390/crypto/hmac_s390.c +++ b/arch/s390/crypto/hmac_s390.c @@ -5,8 +5,7 @@ * s390 specific HMAC support. */ -#define KMSG_COMPONENT "hmac_s390" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "hmac_s390: " fmt #include #include diff --git a/arch/s390/crypto/paes_s390.c b/arch/s390/crypto/paes_s390.c index a624a43a2b54..64aef7eb2030 100644 --- a/arch/s390/crypto/paes_s390.c +++ b/arch/s390/crypto/paes_s390.c @@ -10,8 +10,7 @@ * Harald Freudenberger */ -#define KMSG_COMPONENT "paes_s390" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "paes_s390: " fmt #include #include diff --git a/arch/s390/crypto/phmac_s390.c b/arch/s390/crypto/phmac_s390.c index 7ecfdc4fba2d..918e07867eba 100644 --- a/arch/s390/crypto/phmac_s390.c +++ b/arch/s390/crypto/phmac_s390.c @@ -5,8 +5,7 @@ * s390 specific HMAC support for protected keys. */ -#define KMSG_COMPONENT "phmac_s390" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "phmac_s390: " fmt #include #include diff --git a/arch/s390/crypto/prng.c b/arch/s390/crypto/prng.c index 2becd77df741..84e3d3c6ba09 100644 --- a/arch/s390/crypto/prng.c +++ b/arch/s390/crypto/prng.c @@ -6,8 +6,7 @@ * Driver for the s390 pseudo random number generator */ -#define KMSG_COMPONENT "prng" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "prng: " fmt #include #include diff --git a/arch/s390/hypfs/hypfs_diag.c b/arch/s390/hypfs/hypfs_diag.c index c8af67d20994..08777f57bd24 100644 --- a/arch/s390/hypfs/hypfs_diag.c +++ b/arch/s390/hypfs/hypfs_diag.c @@ -7,8 +7,7 @@ * Author(s): Michael Holzheu */ -#define KMSG_COMPONENT "hypfs" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "hypfs: " fmt #include #include diff --git a/arch/s390/hypfs/hypfs_diag_fs.c b/arch/s390/hypfs/hypfs_diag_fs.c index ede951dc0085..013da4ff9802 100644 --- a/arch/s390/hypfs/hypfs_diag_fs.c +++ b/arch/s390/hypfs/hypfs_diag_fs.c @@ -7,8 +7,7 @@ * Author(s): Michael Holzheu */ -#define KMSG_COMPONENT "hypfs" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "hypfs: " fmt #include #include diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c index 96409573c75d..ee5cfa8f71a0 100644 --- a/arch/s390/hypfs/inode.c +++ b/arch/s390/hypfs/inode.c @@ -6,8 +6,7 @@ * Author(s): Michael Holzheu */ -#define KMSG_COMPONENT "hypfs" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "hypfs: " fmt #include #include diff --git a/arch/s390/kernel/cpacf.c b/arch/s390/kernel/cpacf.c index 3bebc47beeab..9d85b4bc7036 100644 --- a/arch/s390/kernel/cpacf.c +++ b/arch/s390/kernel/cpacf.c @@ -3,8 +3,7 @@ * Copyright IBM Corp. 2024 */ -#define KMSG_COMPONENT "cpacf" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "cpacf: " fmt #include #include diff --git a/arch/s390/kernel/cpcmd.c b/arch/s390/kernel/cpcmd.c index 2f4174b961de..ab611764642a 100644 --- a/arch/s390/kernel/cpcmd.c +++ b/arch/s390/kernel/cpcmd.c @@ -6,8 +6,7 @@ * Christian Borntraeger (cborntra@de.ibm.com), */ -#define KMSG_COMPONENT "cpcmd" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "cpcmd: " fmt #include #include diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c index 6a26f202441d..71cdb6845dd7 100644 --- a/arch/s390/kernel/debug.c +++ b/arch/s390/kernel/debug.c @@ -10,8 +10,7 @@ * Bugreports to: */ -#define KMSG_COMPONENT "s390dbf" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "s390dbf: " fmt #include #include diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index f4cab46a3e66..b27239c03d79 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c @@ -4,8 +4,7 @@ * Author(s): Hongjie Yang , */ -#define KMSG_COMPONENT "setup" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "setup: " fmt #include #include diff --git a/arch/s390/kernel/hiperdispatch.c b/arch/s390/kernel/hiperdispatch.c index 7ad134cc9ad3..217206522266 100644 --- a/arch/s390/kernel/hiperdispatch.c +++ b/arch/s390/kernel/hiperdispatch.c @@ -3,8 +3,7 @@ * Copyright IBM Corp. 2024 */ -#define KMSG_COMPONENT "hd" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "hd: " fmt /* * Hiperdispatch: diff --git a/arch/s390/kernel/os_info.c b/arch/s390/kernel/os_info.c index c2a468986212..94fa44776d0c 100644 --- a/arch/s390/kernel/os_info.c +++ b/arch/s390/kernel/os_info.c @@ -6,8 +6,7 @@ * Author(s): Michael Holzheu */ -#define KMSG_COMPONENT "os_info" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "os_info: " fmt #include #include diff --git a/arch/s390/kernel/perf_cpum_cf.c b/arch/s390/kernel/perf_cpum_cf.c index b7fa9712ee1e..408ab93112bf 100644 --- a/arch/s390/kernel/perf_cpum_cf.c +++ b/arch/s390/kernel/perf_cpum_cf.c @@ -6,8 +6,7 @@ * Author(s): Hendrik Brueckner * Thomas Richter */ -#define KMSG_COMPONENT "cpum_cf" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "cpum_cf: " fmt #include #include @@ -1206,7 +1205,7 @@ static int __init cpumf_pmu_init(void) } /* Setup s390dbf facility */ - cf_dbg = debug_register(KMSG_COMPONENT, 2, 1, 128); + cf_dbg = debug_register("cpum_cf", 2, 1, 128); if (!cf_dbg) { pr_err("Registration of s390dbf(cpum_cf) failed\n"); rc = -ENOMEM; diff --git a/arch/s390/kernel/perf_cpum_sf.c b/arch/s390/kernel/perf_cpum_sf.c index bf816b134fb1..459af23a47a5 100644 --- a/arch/s390/kernel/perf_cpum_sf.c +++ b/arch/s390/kernel/perf_cpum_sf.c @@ -5,8 +5,7 @@ * Copyright IBM Corp. 2013, 2018 * Author(s): Hendrik Brueckner */ -#define KMSG_COMPONENT "cpum_sf" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "cpum_sf: " fmt #include #include @@ -2070,7 +2069,7 @@ static int __init init_cpum_sampling_pmu(void) CPUMF_EVENT_PTR(SF, SF_CYCLES_BASIC_DIAG); } - sfdbg = debug_register(KMSG_COMPONENT, 2, 1, 80); + sfdbg = debug_register("cpum_sf", 2, 1, 80); if (!sfdbg) { pr_err("Registering for s390dbf failed\n"); return -ENOMEM; diff --git a/arch/s390/kernel/perf_event.c b/arch/s390/kernel/perf_event.c index 2de1574d95b2..606750bae508 100644 --- a/arch/s390/kernel/perf_event.c +++ b/arch/s390/kernel/perf_event.c @@ -5,8 +5,7 @@ * Copyright IBM Corp. 2012, 2013 * Author(s): Hendrik Brueckner */ -#define KMSG_COMPONENT "perf" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "perf: " fmt #include #include diff --git a/arch/s390/kernel/perf_pai.c b/arch/s390/kernel/perf_pai.c index c79864628582..810f5b6c5e01 100644 --- a/arch/s390/kernel/perf_pai.c +++ b/arch/s390/kernel/perf_pai.c @@ -5,8 +5,7 @@ * Copyright IBM Corp. 2026 * Author(s): Thomas Richter */ -#define KMSG_COMPONENT "pai" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "pai: " fmt #include #include @@ -1212,9 +1211,9 @@ static int __init paipmu_setup(void) static int __init pai_init(void) { /* Setup s390dbf facility */ - paidbg = debug_register(KMSG_COMPONENT, 32, 256, 128); + paidbg = debug_register("pai", 32, 256, 128); if (!paidbg) { - pr_err("Registration of s390dbf " KMSG_COMPONENT " failed\n"); + pr_err("Registration of s390dbf pai failed\n"); return -ENOMEM; } debug_register_view(paidbg, &debug_sprintf_view); diff --git a/arch/s390/kernel/processor.c b/arch/s390/kernel/processor.c index 11f70c1e2797..e33a3eccda56 100644 --- a/arch/s390/kernel/processor.c +++ b/arch/s390/kernel/processor.c @@ -4,8 +4,7 @@ * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) */ -#define KMSG_COMPONENT "cpu" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "cpu: " fmt #include #include diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 3c50246dc8c5..1edb2281e7b0 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -13,8 +13,7 @@ * This file handles the architecture-dependent parts of initialization */ -#define KMSG_COMPONENT "setup" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "setup: " fmt #include #include diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index b0da25159f06..25240be74c21 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -15,8 +15,7 @@ * operates on physical cpu numbers needs to go into smp.c. */ -#define KMSG_COMPONENT "cpu" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "cpu: " fmt #include #include diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index 63517b85f4c9..bd0df61d1907 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -12,8 +12,7 @@ * Copyright (C) 1991, 1992, 1995 Linus Torvalds */ -#define KMSG_COMPONENT "time" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "time: " fmt #include #include diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c index 1594c80e9bc4..1913a5566ac2 100644 --- a/arch/s390/kernel/topology.c +++ b/arch/s390/kernel/topology.c @@ -3,8 +3,7 @@ * Copyright IBM Corp. 2007, 2011 */ -#define KMSG_COMPONENT "cpu" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "cpu: " fmt #include #include diff --git a/arch/s390/kernel/uv.c b/arch/s390/kernel/uv.c index 5d17609bcfe1..ed46950be86f 100644 --- a/arch/s390/kernel/uv.c +++ b/arch/s390/kernel/uv.c @@ -4,8 +4,7 @@ * * Copyright IBM Corp. 2019, 2024 */ -#define KMSG_COMPONENT "prot_virt" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "prot_virt: " fmt #include #include diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index c62a868cf2b6..f55574af98cc 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c @@ -7,8 +7,7 @@ * Author(s): Carsten Otte */ -#define KMSG_COMPONENT "kvm-s390" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "kvm-s390: " fmt #include #include diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 16ba04062854..ff3a185f156c 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -10,8 +10,7 @@ * Jason J. Herne */ -#define KMSG_COMPONENT "kvm-s390" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "kvm-s390: " fmt #include #include diff --git a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c index b6464a322eb1..6cc33c705de2 100644 --- a/arch/s390/mm/extmem.c +++ b/arch/s390/mm/extmem.c @@ -7,8 +7,7 @@ * Copyright IBM Corp. 2002, 2004 */ -#define KMSG_COMPONENT "extmem" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "extmem: " fmt #include #include diff --git a/arch/s390/mm/hugetlbpage.c b/arch/s390/mm/hugetlbpage.c index 72e8fa136af5..d42e61c7594e 100644 --- a/arch/s390/mm/hugetlbpage.c +++ b/arch/s390/mm/hugetlbpage.c @@ -6,8 +6,7 @@ * Author(s): Gerald Schaefer */ -#define KMSG_COMPONENT "hugetlb" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "hugetlb: " fmt #include #include diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c index cf461d76e9da..3238c178bed8 100644 --- a/arch/s390/net/bpf_jit_comp.c +++ b/arch/s390/net/bpf_jit_comp.c @@ -15,8 +15,7 @@ * Michael Holzheu */ -#define KMSG_COMPONENT "bpf_jit" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "bpf_jit: " fmt #include #include diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index c82c577db2bc..93d2c9c780fc 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c @@ -16,8 +16,7 @@ * Thomas Klein */ -#define KMSG_COMPONENT "zpci" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "zpci: " fmt #include #include diff --git a/arch/s390/pci/pci_bus.c b/arch/s390/pci/pci_bus.c index be8c697fea0c..72adc8f6e94f 100644 --- a/arch/s390/pci/pci_bus.c +++ b/arch/s390/pci/pci_bus.c @@ -7,8 +7,7 @@ * */ -#define KMSG_COMPONENT "zpci" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "zpci: " fmt #include #include diff --git a/arch/s390/pci/pci_clp.c b/arch/s390/pci/pci_clp.c index 02b73d4b6c7e..177aa0214547 100644 --- a/arch/s390/pci/pci_clp.c +++ b/arch/s390/pci/pci_clp.c @@ -6,8 +6,7 @@ * Jan Glauber */ -#define KMSG_COMPONENT "zpci" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "zpci: " fmt #include #include diff --git a/arch/s390/pci/pci_debug.c b/arch/s390/pci/pci_debug.c index 38014206c16b..c7ed7bf254b5 100644 --- a/arch/s390/pci/pci_debug.c +++ b/arch/s390/pci/pci_debug.c @@ -6,8 +6,7 @@ * Jan Glauber */ -#define KMSG_COMPONENT "zpci" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "zpci: " fmt #include #include diff --git a/arch/s390/pci/pci_event.c b/arch/s390/pci/pci_event.c index b95376041501..864cfe22ebeb 100644 --- a/arch/s390/pci/pci_event.c +++ b/arch/s390/pci/pci_event.c @@ -6,8 +6,7 @@ * Jan Glauber */ -#define KMSG_COMPONENT "zpci" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "zpci: " fmt #include #include diff --git a/arch/s390/pci/pci_iov.c b/arch/s390/pci/pci_iov.c index 191e56a623f6..13050ce5c3e9 100644 --- a/arch/s390/pci/pci_iov.c +++ b/arch/s390/pci/pci_iov.c @@ -7,8 +7,7 @@ * */ -#define KMSG_COMPONENT "zpci" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "zpci: " fmt #include #include diff --git a/arch/s390/pci/pci_irq.c b/arch/s390/pci/pci_irq.c index 84482a921332..6afea2fa0c1a 100644 --- a/arch/s390/pci/pci_irq.c +++ b/arch/s390/pci/pci_irq.c @@ -1,6 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 -#define KMSG_COMPONENT "zpci" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "zpci: " fmt #include #include diff --git a/arch/s390/pci/pci_report.c b/arch/s390/pci/pci_report.c index 1b494e5ecc4d..7030f7052926 100644 --- a/arch/s390/pci/pci_report.c +++ b/arch/s390/pci/pci_report.c @@ -7,8 +7,7 @@ * */ -#define KMSG_COMPONENT "zpci" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "zpci: " fmt #include #include diff --git a/arch/s390/pci/pci_sysfs.c b/arch/s390/pci/pci_sysfs.c index 12060870e2aa..c2444a23e26c 100644 --- a/arch/s390/pci/pci_sysfs.c +++ b/arch/s390/pci/pci_sysfs.c @@ -6,8 +6,7 @@ * Jan Glauber */ -#define KMSG_COMPONENT "zpci" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "zpci: " fmt #include #include diff --git a/drivers/char/hw_random/s390-trng.c b/drivers/char/hw_random/s390-trng.c index d27e32e9bfee..3024d5e9fd61 100644 --- a/drivers/char/hw_random/s390-trng.c +++ b/drivers/char/hw_random/s390-trng.c @@ -9,8 +9,7 @@ * Author(s): Harald Freudenberger */ -#define KMSG_COMPONENT "trng" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "trng: " fmt #include #include diff --git a/drivers/pci/hotplug/s390_pci_hpc.c b/drivers/pci/hotplug/s390_pci_hpc.c index d9996516f49e..a55967082ef6 100644 --- a/drivers/pci/hotplug/s390_pci_hpc.c +++ b/drivers/pci/hotplug/s390_pci_hpc.c @@ -8,8 +8,7 @@ * Jan Glauber */ -#define KMSG_COMPONENT "zpci" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "zpci: " fmt #include #include diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c index a2216795591d..c2a87201c153 100644 --- a/drivers/s390/block/dasd_fba.c +++ b/drivers/s390/block/dasd_fba.c @@ -5,7 +5,6 @@ * Copyright IBM Corp. 1999, 2009 */ -#define KMSG_COMPONENT "dasd-fba" #include #include diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c index 57d691ed0a63..38e1df8f8a82 100644 --- a/drivers/s390/block/dcssblk.c +++ b/drivers/s390/block/dcssblk.c @@ -5,8 +5,7 @@ * Authors: Carsten Otte, Stefan Weinhuber, Gerald Schaefer */ -#define KMSG_COMPONENT "dcssblk" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "dcssblk: " fmt #include #include diff --git a/drivers/s390/block/scm_blk.c b/drivers/s390/block/scm_blk.c index 91bbe9d2e5ac..04e84f45dcc9 100644 --- a/drivers/s390/block/scm_blk.c +++ b/drivers/s390/block/scm_blk.c @@ -6,8 +6,7 @@ * Author(s): Sebastian Ott */ -#define KMSG_COMPONENT "scm_block" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "scm_block: " fmt #include #include diff --git a/drivers/s390/block/scm_drv.c b/drivers/s390/block/scm_drv.c index 69a845eb8b1f..6cffbbe83f89 100644 --- a/drivers/s390/block/scm_drv.c +++ b/drivers/s390/block/scm_drv.c @@ -6,8 +6,7 @@ * Author(s): Sebastian Ott */ -#define KMSG_COMPONENT "scm_block" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "scm_block: " fmt #include #include diff --git a/drivers/s390/char/diag_ftp.c b/drivers/s390/char/diag_ftp.c index f41b39c9d267..a1e110c96f74 100644 --- a/drivers/s390/char/diag_ftp.c +++ b/drivers/s390/char/diag_ftp.c @@ -7,8 +7,7 @@ * */ -#define KMSG_COMPONENT "hmcdrv" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "hmcdrv: " fmt #include #include diff --git a/drivers/s390/char/hmcdrv_cache.c b/drivers/s390/char/hmcdrv_cache.c index 43df27ceec11..85fb689594ca 100644 --- a/drivers/s390/char/hmcdrv_cache.c +++ b/drivers/s390/char/hmcdrv_cache.c @@ -7,8 +7,7 @@ * */ -#define KMSG_COMPONENT "hmcdrv" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "hmcdrv: " fmt #include #include diff --git a/drivers/s390/char/hmcdrv_dev.c b/drivers/s390/char/hmcdrv_dev.c index b26fcf6849f2..04b938c5357f 100644 --- a/drivers/s390/char/hmcdrv_dev.c +++ b/drivers/s390/char/hmcdrv_dev.c @@ -14,8 +14,7 @@ * end read() the response. */ -#define KMSG_COMPONENT "hmcdrv" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "hmcdrv: " fmt #include #include diff --git a/drivers/s390/char/hmcdrv_ftp.c b/drivers/s390/char/hmcdrv_ftp.c index 4e3c7ec6749b..3312b2ac00a9 100644 --- a/drivers/s390/char/hmcdrv_ftp.c +++ b/drivers/s390/char/hmcdrv_ftp.c @@ -6,8 +6,7 @@ * Author(s): Ralf Hoppe (rhoppe@de.ibm.com) */ -#define KMSG_COMPONENT "hmcdrv" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "hmcdrv: " fmt #include #include diff --git a/drivers/s390/char/hmcdrv_mod.c b/drivers/s390/char/hmcdrv_mod.c index 1447d0887225..b1cc5ba9fed8 100644 --- a/drivers/s390/char/hmcdrv_mod.c +++ b/drivers/s390/char/hmcdrv_mod.c @@ -6,8 +6,7 @@ * Author(s): Ralf Hoppe (rhoppe@de.ibm.com) */ -#define KMSG_COMPONENT "hmcdrv" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "hmcdrv: " fmt #include #include diff --git a/drivers/s390/char/monreader.c b/drivers/s390/char/monreader.c index 2d9886651d9b..3d84f84b4cbd 100644 --- a/drivers/s390/char/monreader.c +++ b/drivers/s390/char/monreader.c @@ -7,8 +7,7 @@ * Author: Gerald Schaefer */ -#define KMSG_COMPONENT "monreader" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "monreader: " fmt #include #include diff --git a/drivers/s390/char/monwriter.c b/drivers/s390/char/monwriter.c index 0fab1f025a94..cf2e51061422 100644 --- a/drivers/s390/char/monwriter.c +++ b/drivers/s390/char/monwriter.c @@ -7,8 +7,7 @@ * Author(s): Melissa Howland */ -#define KMSG_COMPONENT "monwriter" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "monwriter: " fmt #include #include diff --git a/drivers/s390/char/sclp_ap.c b/drivers/s390/char/sclp_ap.c index 0dd1ca712795..18bb018b4e0c 100644 --- a/drivers/s390/char/sclp_ap.c +++ b/drivers/s390/char/sclp_ap.c @@ -4,8 +4,7 @@ * * Copyright IBM Corp. 2020 */ -#define KMSG_COMPONENT "sclp_cmd" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "sclp_cmd: " fmt #include #include diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c index 3480198eac02..be4730936f5c 100644 --- a/drivers/s390/char/sclp_cmd.c +++ b/drivers/s390/char/sclp_cmd.c @@ -5,8 +5,7 @@ * Author(s): Peter Oberparleiter */ -#define KMSG_COMPONENT "sclp_cmd" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "sclp_cmd: " fmt #include #include diff --git a/drivers/s390/char/sclp_config.c b/drivers/s390/char/sclp_config.c index 356d26a09af0..9cfbe3fc3dca 100644 --- a/drivers/s390/char/sclp_config.c +++ b/drivers/s390/char/sclp_config.c @@ -3,8 +3,7 @@ * Copyright IBM Corp. 2007 */ -#define KMSG_COMPONENT "sclp_config" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "sclp_config: " fmt #include #include diff --git a/drivers/s390/char/sclp_cpi_sys.c b/drivers/s390/char/sclp_cpi_sys.c index d8f91aab11e8..8e1636bcf8b5 100644 --- a/drivers/s390/char/sclp_cpi_sys.c +++ b/drivers/s390/char/sclp_cpi_sys.c @@ -7,8 +7,7 @@ * Michael Ernst */ -#define KMSG_COMPONENT "sclp_cpi" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "sclp_cpi: " fmt #include #include diff --git a/drivers/s390/char/sclp_early.c b/drivers/s390/char/sclp_early.c index bd5e5ba50c0a..6bf501ad8ff0 100644 --- a/drivers/s390/char/sclp_early.c +++ b/drivers/s390/char/sclp_early.c @@ -5,8 +5,7 @@ * Copyright IBM Corp. 2013 */ -#define KMSG_COMPONENT "sclp_early" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "sclp_early: " fmt #include #include diff --git a/drivers/s390/char/sclp_ftp.c b/drivers/s390/char/sclp_ftp.c index d27e2cbfbccb..2a1c4b2cafc8 100644 --- a/drivers/s390/char/sclp_ftp.c +++ b/drivers/s390/char/sclp_ftp.c @@ -7,8 +7,7 @@ * */ -#define KMSG_COMPONENT "hmcdrv" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "hmcdrv: " fmt #include #include diff --git a/drivers/s390/char/sclp_mem.c b/drivers/s390/char/sclp_mem.c index bc515a24b3f2..676c085b4f8a 100644 --- a/drivers/s390/char/sclp_mem.c +++ b/drivers/s390/char/sclp_mem.c @@ -5,8 +5,7 @@ * Copyright IBM Corp. 2025 */ -#define KMSG_COMPONENT "sclp_mem" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "sclp_mem: " fmt #include #include diff --git a/drivers/s390/char/sclp_ocf.c b/drivers/s390/char/sclp_ocf.c index ae2479b804d8..35f3a4a08b12 100644 --- a/drivers/s390/char/sclp_ocf.c +++ b/drivers/s390/char/sclp_ocf.c @@ -6,8 +6,7 @@ * Author(s): Martin Schwidefsky */ -#define KMSG_COMPONENT "sclp_ocf" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "sclp_ocf: " fmt #include #include diff --git a/drivers/s390/char/sclp_pci.c b/drivers/s390/char/sclp_pci.c index 56400886f7fc..899063e64aef 100644 --- a/drivers/s390/char/sclp_pci.c +++ b/drivers/s390/char/sclp_pci.c @@ -4,8 +4,7 @@ * * Copyright IBM Corp. 2016 */ -#define KMSG_COMPONENT "sclp_cmd" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "sclp_cmd: " fmt #include #include diff --git a/drivers/s390/char/sclp_sd.c b/drivers/s390/char/sclp_sd.c index 129b89fe40a3..bb1bce70ec00 100644 --- a/drivers/s390/char/sclp_sd.c +++ b/drivers/s390/char/sclp_sd.c @@ -5,8 +5,7 @@ * Copyright IBM Corp. 2017 */ -#define KMSG_COMPONENT "sclp_sd" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "sclp_sd: " fmt #include #include diff --git a/drivers/s390/char/sclp_sdias.c b/drivers/s390/char/sclp_sdias.c index e915a343fcf5..ab8f1b758a1a 100644 --- a/drivers/s390/char/sclp_sdias.c +++ b/drivers/s390/char/sclp_sdias.c @@ -6,8 +6,7 @@ * Author(s): Michael Holzheu */ -#define KMSG_COMPONENT "sclp_sdias" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "sclp_sdias: " fmt #include #include diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c index 9d0fb4b867c4..a13e0ac1a4e2 100644 --- a/drivers/s390/char/tape_34xx.c +++ b/drivers/s390/char/tape_34xx.c @@ -8,8 +8,7 @@ * Martin Schwidefsky */ -#define KMSG_COMPONENT "tape_34xx" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "tape_34xx: " fmt #include #include diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c index 5b25f5415e4c..0d80f43b175d 100644 --- a/drivers/s390/char/tape_3590.c +++ b/drivers/s390/char/tape_3590.c @@ -8,8 +8,7 @@ * Martin Schwidefsky */ -#define KMSG_COMPONENT "tape_3590" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "tape_3590: " fmt #include #include diff --git a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c index 4f175474335e..c5d3c303c15c 100644 --- a/drivers/s390/char/tape_char.c +++ b/drivers/s390/char/tape_char.c @@ -10,8 +10,7 @@ * Martin Schwidefsky */ -#define KMSG_COMPONENT "tape" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "tape: " fmt #include #include diff --git a/drivers/s390/char/tape_class.c b/drivers/s390/char/tape_class.c index fb18adfb95b5..6fa7b7824856 100644 --- a/drivers/s390/char/tape_class.c +++ b/drivers/s390/char/tape_class.c @@ -8,8 +8,7 @@ * Based on simple class device code by Greg K-H */ -#define KMSG_COMPONENT "tape" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "tape: " fmt #include #include diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c index ab1a2dc7d711..0250076a7d9f 100644 --- a/drivers/s390/char/tape_core.c +++ b/drivers/s390/char/tape_core.c @@ -11,8 +11,7 @@ * Stefan Bader */ -#define KMSG_COMPONENT "tape" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "tape: " fmt #include #include diff --git a/drivers/s390/char/tape_proc.c b/drivers/s390/char/tape_proc.c index 2238d9df6c47..a1e5fab12af2 100644 --- a/drivers/s390/char/tape_proc.c +++ b/drivers/s390/char/tape_proc.c @@ -11,8 +11,7 @@ * PROCFS Functions */ -#define KMSG_COMPONENT "tape" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "tape: " fmt #include #include diff --git a/drivers/s390/char/tape_std.c b/drivers/s390/char/tape_std.c index 4e1c52313fbc..43a5586685ff 100644 --- a/drivers/s390/char/tape_std.c +++ b/drivers/s390/char/tape_std.c @@ -11,8 +11,7 @@ * Stefan Bader */ -#define KMSG_COMPONENT "tape" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "tape: " fmt #include #include diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c index e284eea331d7..383e7e2bd69f 100644 --- a/drivers/s390/char/vmlogrdr.c +++ b/drivers/s390/char/vmlogrdr.c @@ -11,8 +11,7 @@ * */ -#define KMSG_COMPONENT "vmlogrdr" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "vmlogrdr: " fmt #include #include diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c index 0fd918769a4b..e3e0e9f36527 100644 --- a/drivers/s390/char/vmur.c +++ b/drivers/s390/char/vmur.c @@ -9,8 +9,7 @@ * Frank Munzert */ -#define KMSG_COMPONENT "vmur" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "vmur: " fmt #include #include diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c index 33cebb91b933..b26b5fca6ce8 100644 --- a/drivers/s390/char/zcore.c +++ b/drivers/s390/char/zcore.c @@ -9,8 +9,7 @@ * Author(s): Michael Holzheu */ -#define KMSG_COMPONENT "zdump" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "zdump: " fmt #include #include diff --git a/drivers/s390/cio/blacklist.c b/drivers/s390/cio/blacklist.c index 93695d535380..738d5e2d5304 100644 --- a/drivers/s390/cio/blacklist.c +++ b/drivers/s390/cio/blacklist.c @@ -8,8 +8,7 @@ * Arnd Bergmann (arndb@de.ibm.com) */ -#define KMSG_COMPONENT "cio" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "cio: " fmt #include #include diff --git a/drivers/s390/cio/ccwreq.c b/drivers/s390/cio/ccwreq.c index 73582a0a2622..763f477cc431 100644 --- a/drivers/s390/cio/ccwreq.c +++ b/drivers/s390/cio/ccwreq.c @@ -6,8 +6,7 @@ * Author(s): Peter Oberparleiter */ -#define KMSG_COMPONENT "cio" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "cio: " fmt #include #include diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index edebb0d06ab7..fbb58edd6274 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c @@ -8,8 +8,7 @@ * Arnd Bergmann (arndb@de.ibm.com) */ -#define KMSG_COMPONENT "cio" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "cio: " fmt #include #include diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 6bcc8e58e5f9..70dc8cc76594 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -9,8 +9,7 @@ * Martin Schwidefsky (schwidefsky@de.ibm.com) */ -#define KMSG_COMPONENT "cio" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "cio: " fmt #include #include diff --git a/drivers/s390/cio/cio_inject.c b/drivers/s390/cio/cio_inject.c index a2e771ebae8e..0e18cb921ef6 100644 --- a/drivers/s390/cio/cio_inject.c +++ b/drivers/s390/cio/cio_inject.c @@ -6,8 +6,7 @@ * Author(s): Vineeth Vijayan */ -#define KMSG_COMPONENT "cio" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "cio: " fmt #include #include diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c index b7048f2b036e..7d035e4937ce 100644 --- a/drivers/s390/cio/cmf.c +++ b/drivers/s390/cio/cmf.c @@ -10,8 +10,7 @@ * original idea from Natarajan Krishnaswami */ -#define KMSG_COMPONENT "cio" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "cio: " fmt #include #include diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index be78a57f9bfd..4c85df7a548e 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -8,8 +8,7 @@ * Cornelia Huck (cornelia.huck@de.ibm.com) */ -#define KMSG_COMPONENT "cio" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "cio: " fmt #include #include diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 4b2dae6eb376..602f36102c7c 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -8,8 +8,7 @@ * Martin Schwidefsky (schwidefsky@de.ibm.com) */ -#define KMSG_COMPONENT "cio" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "cio: " fmt #include #include diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index e4bd4f79aaa3..a445494fd2be 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -11,8 +11,7 @@ * Adjunct processor bus. */ -#define KMSG_COMPONENT "ap" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "ap: " fmt #include #include diff --git a/drivers/s390/crypto/ap_card.c b/drivers/s390/crypto/ap_card.c index ce953cbbd564..8102c8134c49 100644 --- a/drivers/s390/crypto/ap_card.c +++ b/drivers/s390/crypto/ap_card.c @@ -6,8 +6,7 @@ * Adjunct processor bus, card related code. */ -#define KMSG_COMPONENT "ap" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "ap: " fmt #include #include diff --git a/drivers/s390/crypto/ap_queue.c b/drivers/s390/crypto/ap_queue.c index 4fe443d30f9b..4a32c1e19a1e 100644 --- a/drivers/s390/crypto/ap_queue.c +++ b/drivers/s390/crypto/ap_queue.c @@ -6,8 +6,7 @@ * Adjunct processor bus, queue related code. */ -#define KMSG_COMPONENT "ap" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "ap: " fmt #include #include diff --git a/drivers/s390/crypto/pkey_api.c b/drivers/s390/crypto/pkey_api.c index 01549003a903..ad1cd699f53b 100644 --- a/drivers/s390/crypto/pkey_api.c +++ b/drivers/s390/crypto/pkey_api.c @@ -7,8 +7,7 @@ * Author(s): Harald Freudenberger */ -#define KMSG_COMPONENT "pkey" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "pkey: " fmt #include #include diff --git a/drivers/s390/crypto/pkey_base.c b/drivers/s390/crypto/pkey_base.c index b15741461a63..d60cd987c16d 100644 --- a/drivers/s390/crypto/pkey_base.c +++ b/drivers/s390/crypto/pkey_base.c @@ -5,8 +5,7 @@ * Copyright IBM Corp. 2024 */ -#define KMSG_COMPONENT "pkey" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "pkey: " fmt #include #include diff --git a/drivers/s390/crypto/pkey_cca.c b/drivers/s390/crypto/pkey_cca.c index 6c7897a93f27..d4550d8d8eea 100644 --- a/drivers/s390/crypto/pkey_cca.c +++ b/drivers/s390/crypto/pkey_cca.c @@ -5,8 +5,7 @@ * Copyright IBM Corp. 2024 */ -#define KMSG_COMPONENT "pkey" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "pkey: " fmt #include #include diff --git a/drivers/s390/crypto/pkey_ep11.c b/drivers/s390/crypto/pkey_ep11.c index 6b23adc560c8..654eed20d0d9 100644 --- a/drivers/s390/crypto/pkey_ep11.c +++ b/drivers/s390/crypto/pkey_ep11.c @@ -5,8 +5,7 @@ * Copyright IBM Corp. 2024 */ -#define KMSG_COMPONENT "pkey" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "pkey: " fmt #include #include diff --git a/drivers/s390/crypto/pkey_pckmo.c b/drivers/s390/crypto/pkey_pckmo.c index 7eca9f1340bd..793326c4c59a 100644 --- a/drivers/s390/crypto/pkey_pckmo.c +++ b/drivers/s390/crypto/pkey_pckmo.c @@ -5,8 +5,7 @@ * Copyright IBM Corp. 2024 */ -#define KMSG_COMPONENT "pkey" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "pkey: " fmt #include #include diff --git a/drivers/s390/crypto/pkey_sysfs.c b/drivers/s390/crypto/pkey_sysfs.c index 792c0fce88fa..b6b0a46cb8a8 100644 --- a/drivers/s390/crypto/pkey_sysfs.c +++ b/drivers/s390/crypto/pkey_sysfs.c @@ -5,8 +5,7 @@ * Copyright IBM Corp. 2024 */ -#define KMSG_COMPONENT "pkey" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "pkey: " fmt #include diff --git a/drivers/s390/crypto/pkey_uv.c b/drivers/s390/crypto/pkey_uv.c index e5c6e01acaf3..6cd3c49384b5 100644 --- a/drivers/s390/crypto/pkey_uv.c +++ b/drivers/s390/crypto/pkey_uv.c @@ -5,8 +5,7 @@ * Copyright IBM Corp. 2024 */ -#define KMSG_COMPONENT "pkey" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "pkey: " fmt #include #include diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c index de93a953d380..7a3b99f065f2 100644 --- a/drivers/s390/crypto/zcrypt_api.c +++ b/drivers/s390/crypto/zcrypt_api.c @@ -12,8 +12,7 @@ * Multiple device nodes: Harald Freudenberger */ -#define KMSG_COMPONENT "zcrypt" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "zcrypt: " fmt #include #include diff --git a/drivers/s390/crypto/zcrypt_ccamisc.c b/drivers/s390/crypto/zcrypt_ccamisc.c index a96e25614303..573bad1d6d86 100644 --- a/drivers/s390/crypto/zcrypt_ccamisc.c +++ b/drivers/s390/crypto/zcrypt_ccamisc.c @@ -7,8 +7,7 @@ * Collection of CCA misc functions used by zcrypt and pkey */ -#define KMSG_COMPONENT "zcrypt" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "zcrypt: " fmt #include #include diff --git a/drivers/s390/crypto/zcrypt_ep11misc.c b/drivers/s390/crypto/zcrypt_ep11misc.c index e92e2fd8ce5d..3dda9589f2b9 100644 --- a/drivers/s390/crypto/zcrypt_ep11misc.c +++ b/drivers/s390/crypto/zcrypt_ep11misc.c @@ -6,8 +6,7 @@ * Collection of EP11 misc functions used by zcrypt and pkey */ -#define KMSG_COMPONENT "zcrypt" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "zcrypt: " fmt #include #include diff --git a/drivers/s390/crypto/zcrypt_msgtype50.c b/drivers/s390/crypto/zcrypt_msgtype50.c index fc0a2a053dc2..d6fc2d8e7fad 100644 --- a/drivers/s390/crypto/zcrypt_msgtype50.c +++ b/drivers/s390/crypto/zcrypt_msgtype50.c @@ -10,8 +10,7 @@ * MSGTYPE restruct: Holger Dengler */ -#define KMSG_COMPONENT "zcrypt" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "zcrypt: " fmt #include #include diff --git a/drivers/s390/crypto/zcrypt_msgtype6.c b/drivers/s390/crypto/zcrypt_msgtype6.c index 9cefbb30960f..a0dcab5dc4f2 100644 --- a/drivers/s390/crypto/zcrypt_msgtype6.c +++ b/drivers/s390/crypto/zcrypt_msgtype6.c @@ -10,8 +10,7 @@ * MSGTYPE restruct: Holger Dengler */ -#define KMSG_COMPONENT "zcrypt" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "zcrypt: " fmt #include #include diff --git a/drivers/s390/net/ctcm_fsms.c b/drivers/s390/net/ctcm_fsms.c index 9678c6a2cda7..e221687a9858 100644 --- a/drivers/s390/net/ctcm_fsms.c +++ b/drivers/s390/net/ctcm_fsms.c @@ -12,8 +12,7 @@ #undef DEBUGDATA #undef DEBUGCCW -#define KMSG_COMPONENT "ctcm" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "ctcm: " fmt #include #include diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c index b93c2eb45916..3d7ccf2366a0 100644 --- a/drivers/s390/net/ctcm_main.c +++ b/drivers/s390/net/ctcm_main.c @@ -20,8 +20,7 @@ #undef DEBUGDATA #undef DEBUGCCW -#define KMSG_COMPONENT "ctcm" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "ctcm: " fmt #include #include diff --git a/drivers/s390/net/ctcm_mpc.c b/drivers/s390/net/ctcm_mpc.c index 0aeafa772fb1..7b8e6ccc04b5 100644 --- a/drivers/s390/net/ctcm_mpc.c +++ b/drivers/s390/net/ctcm_mpc.c @@ -18,8 +18,7 @@ #undef DEBUGDATA #undef DEBUGCCW -#define KMSG_COMPONENT "ctcm" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "ctcm: " fmt #include #include diff --git a/drivers/s390/net/ctcm_sysfs.c b/drivers/s390/net/ctcm_sysfs.c index 0c5d8a3eaa2e..529a1c40ae63 100644 --- a/drivers/s390/net/ctcm_sysfs.c +++ b/drivers/s390/net/ctcm_sysfs.c @@ -9,8 +9,7 @@ #undef DEBUGDATA #undef DEBUGCCW -#define KMSG_COMPONENT "ctcm" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "ctcm: " fmt #include #include diff --git a/drivers/s390/net/ism_drv.c b/drivers/s390/net/ism_drv.c index f84aa2e676e9..8b8e4f06be0f 100644 --- a/drivers/s390/net/ism_drv.c +++ b/drivers/s390/net/ism_drv.c @@ -4,8 +4,7 @@ * * Copyright IBM Corp. 2018 */ -#define KMSG_COMPONENT "ism" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "ism: " fmt #include #include diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 6d415e9d5c9f..64d45285651d 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -7,8 +7,7 @@ * Frank Blaschka */ -#define KMSG_COMPONENT "qeth" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "qeth: " fmt #include #include diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c index c0e4883be6d0..a3b16d4d16fb 100644 --- a/drivers/s390/net/qeth_core_sys.c +++ b/drivers/s390/net/qeth_core_sys.c @@ -7,8 +7,7 @@ * Frank Blaschka */ -#define KMSG_COMPONENT "qeth" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "qeth: " fmt #include #include diff --git a/drivers/s390/net/qeth_ethtool.c b/drivers/s390/net/qeth_ethtool.c index f184c58ecf24..d214a889cf4e 100644 --- a/drivers/s390/net/qeth_ethtool.c +++ b/drivers/s390/net/qeth_ethtool.c @@ -3,8 +3,7 @@ * Copyright IBM Corp. 2018 */ -#define KMSG_COMPONENT "qeth" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "qeth: " fmt #include #include "qeth_core.h" diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 2a3888283a94..7498a83b1f06 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -7,8 +7,7 @@ * Frank Blaschka */ -#define KMSG_COMPONENT "qeth" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "qeth: " fmt #include #include diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 3525be819362..027bc346232f 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -7,8 +7,7 @@ * Frank Blaschka */ -#define KMSG_COMPONENT "qeth" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "qeth: " fmt #include #include diff --git a/drivers/s390/net/smsgiucv_app.c b/drivers/s390/net/smsgiucv_app.c index 4bd4d6bfc126..7041c1dca1e8 100644 --- a/drivers/s390/net/smsgiucv_app.c +++ b/drivers/s390/net/smsgiucv_app.c @@ -10,8 +10,7 @@ * Author(s): Hendrik Brueckner * */ -#define KMSG_COMPONENT "smsgiucv_app" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "smsgiucv_app: " fmt #include #include @@ -161,7 +160,7 @@ static int __init smsgiucv_app_init(void) if (!smsgiucv_drv) return -ENODEV; - smsg_app_dev = iucv_alloc_device(NULL, smsgiucv_drv, NULL, KMSG_COMPONENT); + smsg_app_dev = iucv_alloc_device(NULL, smsgiucv_drv, NULL, "smsgiucv_app"); if (!smsg_app_dev) return -ENOMEM; diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index dc2265ebb11b..01f927ae61b5 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -28,8 +28,7 @@ * Benjamin Block */ -#define KMSG_COMPONENT "zfcp" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "zfcp: " fmt #include #include diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c index bdf2cc1ea713..67cb947048c4 100644 --- a/drivers/s390/scsi/zfcp_ccw.c +++ b/drivers/s390/scsi/zfcp_ccw.c @@ -7,8 +7,7 @@ * Copyright IBM Corp. 2002, 2010 */ -#define KMSG_COMPONENT "zfcp" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "zfcp: " fmt #include #include "zfcp_ext.h" diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c index d904625afd40..6b5561c54e2f 100644 --- a/drivers/s390/scsi/zfcp_dbf.c +++ b/drivers/s390/scsi/zfcp_dbf.c @@ -7,8 +7,7 @@ * Copyright IBM Corp. 2002, 2023 */ -#define KMSG_COMPONENT "zfcp" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "zfcp: " fmt #include #include diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index ffd994416995..ec6c0e102119 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c @@ -7,8 +7,7 @@ * Copyright IBM Corp. 2002, 2020 */ -#define KMSG_COMPONENT "zfcp" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "zfcp: " fmt #include #include diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c index 1d50f463afe7..78ca394e1195 100644 --- a/drivers/s390/scsi/zfcp_fc.c +++ b/drivers/s390/scsi/zfcp_fc.c @@ -7,8 +7,7 @@ * Copyright IBM Corp. 2008, 2017 */ -#define KMSG_COMPONENT "zfcp" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "zfcp: " fmt #include #include diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index c5bba1be88f4..9418086368c3 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -7,8 +7,7 @@ * Copyright IBM Corp. 2002, 2023 */ -#define KMSG_COMPONENT "zfcp" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "zfcp: " fmt #include #include diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c index f2410bc44ad3..e15a1eabe42d 100644 --- a/drivers/s390/scsi/zfcp_qdio.c +++ b/drivers/s390/scsi/zfcp_qdio.c @@ -7,8 +7,7 @@ * Copyright IBM Corp. 2002, 2020 */ -#define KMSG_COMPONENT "zfcp" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "zfcp: " fmt #include #include diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index b31f860af47b..141476ea21bb 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -7,8 +7,7 @@ * Copyright IBM Corp. 2002, 2020 */ -#define KMSG_COMPONENT "zfcp" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "zfcp: " fmt #include #include diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c index 90a84ae98b97..10a3840b2b6b 100644 --- a/drivers/s390/scsi/zfcp_sysfs.c +++ b/drivers/s390/scsi/zfcp_sysfs.c @@ -7,8 +7,7 @@ * Copyright IBM Corp. 2008, 2020 */ -#define KMSG_COMPONENT "zfcp" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "zfcp: " fmt #include #include "zfcp_diag.h" From 1d7764cfe33626f8487febbcb2ad2acc9bd14c2c Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 17 Nov 2025 15:09:52 +0100 Subject: [PATCH 85/92] s390/modules: Simplify module_finalize() slightly Preinitialize the return value, and break out the for loop in module_finalize() in case of an error to get rid of an ifdef. This makes it easier to add additional code, which may also depend on config options. Reviewed-by: Sven Schnelle Signed-off-by: Heiko Carstens --- arch/s390/kernel/module.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c index 91e207b50394..54d99e811a83 100644 --- a/arch/s390/kernel/module.c +++ b/arch/s390/kernel/module.c @@ -495,9 +495,7 @@ int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *s; char *secstrings, *secname; void *aseg; -#ifdef CONFIG_FUNCTION_TRACER - int ret; -#endif + int rc = 0; if (IS_ENABLED(CONFIG_EXPOLINE) && !nospec_disable && me->arch.plt_size) { @@ -529,12 +527,12 @@ int module_finalize(const Elf_Ehdr *hdr, #ifdef CONFIG_FUNCTION_TRACER if (!strcmp(FTRACE_CALLSITE_SECTION, secname)) { - ret = module_alloc_ftrace_hotpatch_trampolines(me, s); - if (ret < 0) - return ret; + rc = module_alloc_ftrace_hotpatch_trampolines(me, s); + if (rc) + break; } #endif /* CONFIG_FUNCTION_TRACER */ } - return 0; + return rc; } From f5730d44e05efb43a5cb64e5eb04e24994bbb50f Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 17 Nov 2025 15:09:53 +0100 Subject: [PATCH 86/92] s390: Add stackprotector support Stackprotector support was previously unavailable on s390 because by default compilers generate code which is not suitable for the kernel: the canary value is accessed via thread local storage, where the address of thread local storage is within access registers 0 and 1. Using those registers also for the kernel would come with a significant performance impact and more complicated kernel entry/exit code, since access registers contents would have to be exchanged on every kernel entry and exit. With the upcoming gcc 16 release new compiler options will become available which allow to generate code suitable for the kernel. [1] Compiler option -mstack-protector-guard=global instructs gcc to generate stackprotector code that refers to a global stackprotector canary value via symbol __stack_chk_guard. Access to this value is guaranteed to occur via larl and lgrl instructions. Furthermore, compiler option -mstack-protector-guard-record generates a section containing all code addresses that reference the canary value. To allow for per task canary values the instructions which load the address of __stack_chk_guard are patched so they access a lowcore field instead: a per task canary value is available within the task_struct of each task, and is written to the per-cpu lowcore location on each context switch. Also add sanity checks and debugging option to be consistent with other kernel code patching mechanisms. Full debugging output can be enabled with the following kernel command line options: debug_stackprotector bootdebug ignore_loglevel earlyprintk dyndbg="file stackprotector.c +p" Example debug output: stackprot: 0000021e402d4eda: c010005a9ae3 -> c01f00070240 where ": -> ". [1] gcc commit 0cd1f03939d5 ("s390: Support global stack protector") Reviewed-by: Sven Schnelle Signed-off-by: Heiko Carstens --- arch/s390/Kconfig | 4 + arch/s390/Makefile | 4 + arch/s390/boot/Makefile | 1 + arch/s390/boot/boot.h | 4 + arch/s390/boot/ipl_parm.c | 6 + arch/s390/boot/stackprotector.c | 6 + arch/s390/boot/startup.c | 8 + arch/s390/include/asm/arch-stackprotector.h | 25 ++++ arch/s390/include/asm/lowcore.h | 3 +- arch/s390/include/asm/stackprotector.h | 16 ++ arch/s390/kernel/Makefile | 2 +- arch/s390/kernel/asm-offsets.c | 4 + arch/s390/kernel/entry.S | 8 +- arch/s390/kernel/module.c | 9 ++ arch/s390/kernel/smp.c | 3 + arch/s390/kernel/stackprotector.c | 156 ++++++++++++++++++++ arch/s390/kernel/vdso64/Makefile | 1 + arch/s390/kernel/vmlinux.lds.S | 13 ++ 18 files changed, 269 insertions(+), 4 deletions(-) create mode 100644 arch/s390/boot/stackprotector.c create mode 100644 arch/s390/include/asm/arch-stackprotector.h create mode 100644 arch/s390/include/asm/stackprotector.h create mode 100644 arch/s390/kernel/stackprotector.c diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index cb143bf782f8..d83501f829f1 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -69,6 +69,9 @@ config CC_HAS_ASM_AOR_FORMAT_FLAGS Clang versions before 19.1.0 do not support A, O, and R inline assembly format flags. +config CC_HAS_STACKPROTECTOR_GLOBAL + def_bool $(cc-option, -mstack-protector-guard=global -mstack-protector-guard-record) + config S390 def_bool y # @@ -245,6 +248,7 @@ config S390 select HAVE_SAMPLE_FTRACE_DIRECT_MULTI select HAVE_SETUP_PER_CPU_AREA select HAVE_SOFTIRQ_ON_OWN_STACK + select HAVE_STACKPROTECTOR if CC_HAS_STACKPROTECTOR_GLOBAL select HAVE_SYSCALL_TRACEPOINTS select HAVE_VIRT_CPU_ACCOUNTING select HAVE_VIRT_CPU_ACCOUNTING_IDLE diff --git a/arch/s390/Makefile b/arch/s390/Makefile index bf53e7d1487a..f0a670dcce71 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile @@ -89,6 +89,10 @@ ifdef CONFIG_EXPOLINE aflags-y += -DCC_USING_EXPOLINE endif +ifeq ($(CONFIG_STACKPROTECTOR),y) + KBUILD_CFLAGS += -mstack-protector-guard=global -mstack-protector-guard-record +endif + ifdef CONFIG_FUNCTION_TRACER ifeq ($(call cc-option,-mfentry -mnop-mcount),) # make use of hotpatch feature if the compiler supports it diff --git a/arch/s390/boot/Makefile b/arch/s390/boot/Makefile index 02f2cf082748..490167faba7a 100644 --- a/arch/s390/boot/Makefile +++ b/arch/s390/boot/Makefile @@ -32,6 +32,7 @@ obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o obj-y += $(if $(CONFIG_KERNEL_UNCOMPRESSED),,decompressor.o) info.o obj-$(CONFIG_KERNEL_ZSTD) += clz_ctz.o obj-$(CONFIG_KMSAN) += kmsan.o +obj-$(CONFIG_STACKPROTECTOR) += stackprotector.o obj-all := $(obj-y) piggy.o syms.o targets := bzImage section_cmp.boot.data section_cmp.boot.preserved.data $(obj-y) diff --git a/arch/s390/boot/boot.h b/arch/s390/boot/boot.h index 37d5b097ede5..61a205b489fb 100644 --- a/arch/s390/boot/boot.h +++ b/arch/s390/boot/boot.h @@ -28,6 +28,10 @@ struct vmlinux_info { unsigned long invalid_pg_dir_off; unsigned long alt_instructions; unsigned long alt_instructions_end; +#ifdef CONFIG_STACKPROTECTOR + unsigned long stack_prot_start; + unsigned long stack_prot_end; +#endif #ifdef CONFIG_KASAN unsigned long kasan_early_shadow_page_off; unsigned long kasan_early_shadow_pte_off; diff --git a/arch/s390/boot/ipl_parm.c b/arch/s390/boot/ipl_parm.c index f584d7da29cb..6bc950b92be7 100644 --- a/arch/s390/boot/ipl_parm.c +++ b/arch/s390/boot/ipl_parm.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -294,6 +295,11 @@ void parse_boot_command_line(void) cmma_flag = 0; } +#ifdef CONFIG_STACKPROTECTOR + if (!strcmp(param, "debug_stackprotector")) + stack_protector_debug = 1; +#endif + #if IS_ENABLED(CONFIG_KVM) if (!strcmp(param, "prot_virt")) { rc = kstrtobool(val, &enabled); diff --git a/arch/s390/boot/stackprotector.c b/arch/s390/boot/stackprotector.c new file mode 100644 index 000000000000..68494940c12a --- /dev/null +++ b/arch/s390/boot/stackprotector.c @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 + +#define boot_fmt(fmt) "stackprot: " fmt + +#include "boot.h" +#include "../kernel/stackprotector.c" diff --git a/arch/s390/boot/startup.c b/arch/s390/boot/startup.c index 3fbd25b9498f..f77067dfc2a8 100644 --- a/arch/s390/boot/startup.c +++ b/arch/s390/boot/startup.c @@ -20,6 +20,9 @@ #include #include #include +#include +#include +#include #include "decompressor.h" #include "boot.h" #include "uv.h" @@ -477,6 +480,10 @@ static void kaslr_adjust_vmlinux_info(long offset) vmlinux.invalid_pg_dir_off += offset; vmlinux.alt_instructions += offset; vmlinux.alt_instructions_end += offset; +#ifdef CONFIG_STACKPROTECTOR + vmlinux.stack_prot_start += offset; + vmlinux.stack_prot_end += offset; +#endif #ifdef CONFIG_KASAN vmlinux.kasan_early_shadow_page_off += offset; vmlinux.kasan_early_shadow_pte_off += offset; @@ -622,6 +629,7 @@ void startup_kernel(void) __apply_alternatives((struct alt_instr *)_vmlinux_info.alt_instructions, (struct alt_instr *)_vmlinux_info.alt_instructions_end, ALT_CTX_EARLY); + stack_protector_apply_early(text_lma); /* * Save KASLR offset for early dumps, before vmcore_info is set. diff --git a/arch/s390/include/asm/arch-stackprotector.h b/arch/s390/include/asm/arch-stackprotector.h new file mode 100644 index 000000000000..953627259e91 --- /dev/null +++ b/arch/s390/include/asm/arch-stackprotector.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef _ASM_S390_ARCH_STACKPROTECTOR_H +#define _ASM_S390_ARCH_STACKPROTECTOR_H + +extern unsigned long __stack_chk_guard; +extern int stack_protector_debug; + +void __stack_protector_apply_early(unsigned long kernel_start); +int __stack_protector_apply(unsigned long *start, unsigned long *end, unsigned long kernel_start); + +static inline void stack_protector_apply_early(unsigned long kernel_start) +{ + if (IS_ENABLED(CONFIG_STACKPROTECTOR)) + __stack_protector_apply_early(kernel_start); +} + +static inline int stack_protector_apply(unsigned long *start, unsigned long *end) +{ + if (IS_ENABLED(CONFIG_STACKPROTECTOR)) + return __stack_protector_apply(start, end, 0); + return 0; +} + +#endif /* _ASM_S390_ARCH_STACKPROTECTOR_H */ diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h index d9c853db9a40..50ffe75adeb4 100644 --- a/arch/s390/include/asm/lowcore.h +++ b/arch/s390/include/asm/lowcore.h @@ -100,7 +100,8 @@ struct lowcore { /* Save areas. */ __u64 save_area[8]; /* 0x0200 */ - __u8 pad_0x0240[0x0280-0x0240]; /* 0x0240 */ + __u64 stack_canary; /* 0x0240 */ + __u8 pad_0x0248[0x0280-0x0248]; /* 0x0248 */ __u64 save_area_restart[1]; /* 0x0280 */ __u64 pcpu; /* 0x0288 */ diff --git a/arch/s390/include/asm/stackprotector.h b/arch/s390/include/asm/stackprotector.h new file mode 100644 index 000000000000..0497850103dd --- /dev/null +++ b/arch/s390/include/asm/stackprotector.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef _ASM_S390_STACKPROTECTOR_H +#define _ASM_S390_STACKPROTECTOR_H + +#include +#include +#include + +static __always_inline void boot_init_stack_canary(void) +{ + current->stack_canary = get_random_canary(); + get_lowcore()->stack_canary = current->stack_canary; +} + +#endif /* _ASM_S390_STACKPROTECTOR_H */ diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index 810000355ac5..ecaee29e724e 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile @@ -67,7 +67,7 @@ obj-$(CONFIG_KEXEC_CORE) += machine_kexec.o relocate_kernel.o obj-$(CONFIG_VMCORE_INFO) += vmcore_info.o obj-$(CONFIG_UPROBES) += uprobes.o obj-$(CONFIG_JUMP_LABEL) += jump_label.o - +obj-$(CONFIG_STACKPROTECTOR) += stackprotector.o obj-$(CONFIG_KEXEC_FILE) += machine_kexec_file.o kexec_image.o obj-$(CONFIG_KEXEC_FILE) += kexec_elf.o obj-$(CONFIG_CERT_STORE) += cert_store.o diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index a8915663e917..cfe27f6579e3 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c @@ -21,6 +21,9 @@ int main(void) OFFSET(__TASK_stack, task_struct, stack); OFFSET(__TASK_thread, task_struct, thread); OFFSET(__TASK_pid, task_struct, pid); +#ifdef CONFIG_STACKPROTECTOR + OFFSET(__TASK_stack_canary, task_struct, stack_canary); +#endif BLANK(); /* thread struct offsets */ OFFSET(__THREAD_ksp, thread_struct, ksp); @@ -139,6 +142,7 @@ int main(void) OFFSET(__LC_CURRENT_PID, lowcore, current_pid); OFFSET(__LC_LAST_BREAK, lowcore, last_break); /* software defined ABI-relevant lowcore locations 0xe00 - 0xe20 */ + OFFSET(__LC_STACK_CANARY, lowcore, stack_canary); OFFSET(__LC_DUMP_REIPL, lowcore, ipib); OFFSET(__LC_VMCORE_INFO, lowcore, vmcore_info); OFFSET(__LC_OS_INFO, lowcore, os_info); diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 1e266c0eae2c..24cc33e668ea 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -162,9 +162,13 @@ SYM_FUNC_START(__switch_to_asm) stg %r3,__LC_CURRENT(%r13) # store task struct of next stg %r15,__LC_KERNEL_STACK(%r13) # store end of kernel stack lg %r15,__THREAD_ksp(%r1,%r3) # load kernel stack of next - aghi %r3,__TASK_pid - mvc __LC_CURRENT_PID(4,%r13),0(%r3) # store pid of next + aghik %r4,%r3,__TASK_pid + mvc __LC_CURRENT_PID(4,%r13),0(%r4) # store pid of next ALTERNATIVE "nop", "lpp _LPP_OFFSET(%r13)", ALT_FACILITY(40) +#ifdef CONFIG_STACKPROTECTOR + lg %r3,__TASK_stack_canary(%r3) + stg %r3,__LC_STACK_CANARY(%r13) +#endif lmg %r6,%r15,__SF_GPRS(%r15) # load gprs of next task BR_EX %r14 SYM_FUNC_END(__switch_to_asm) diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c index 54d99e811a83..9d1f8a50f5a4 100644 --- a/arch/s390/kernel/module.c +++ b/arch/s390/kernel/module.c @@ -22,12 +22,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include #if 0 #define DEBUGP printk @@ -525,6 +527,13 @@ int module_finalize(const Elf_Ehdr *hdr, (str_has_prefix(secname, ".s390_return"))) nospec_revert(aseg, aseg + s->sh_size); + if (IS_ENABLED(CONFIG_STACKPROTECTOR) && + (str_has_prefix(secname, "__stack_protector_loc"))) { + rc = stack_protector_apply(aseg, aseg + s->sh_size); + if (rc) + break; + } + #ifdef CONFIG_FUNCTION_TRACER if (!strcmp(FTRACE_CALLSITE_SECTION, secname)) { rc = module_alloc_ftrace_hotpatch_trampolines(me, s); diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 25240be74c21..b7429f30afc1 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -280,6 +280,9 @@ static void pcpu_attach_task(int cpu, struct task_struct *tsk) lc->hardirq_timer = tsk->thread.hardirq_timer; lc->softirq_timer = tsk->thread.softirq_timer; lc->steal_timer = 0; +#ifdef CONFIG_STACKPROTECTOR + lc->stack_canary = tsk->stack_canary; +#endif } static void pcpu_start_fn(int cpu, void (*func)(void *), void *data) diff --git a/arch/s390/kernel/stackprotector.c b/arch/s390/kernel/stackprotector.c new file mode 100644 index 000000000000..d4e40483f008 --- /dev/null +++ b/arch/s390/kernel/stackprotector.c @@ -0,0 +1,156 @@ +// SPDX-License-Identifier: GPL-2.0 + +#ifndef pr_fmt +#define pr_fmt(fmt) "stackprot: " fmt +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __DECOMPRESSOR + +#define DEBUGP boot_debug +#define EMERGP boot_emerg +#define PANIC boot_panic + +#else /* __DECOMPRESSOR */ + +#define DEBUGP pr_debug +#define EMERGP pr_emerg +#define PANIC panic + +#endif /* __DECOMPRESSOR */ + +int __bootdata_preserved(stack_protector_debug); + +unsigned long __stack_chk_guard; +EXPORT_SYMBOL(__stack_chk_guard); + +struct insn_ril { + u8 opc1 : 8; + u8 r1 : 4; + u8 opc2 : 4; + u32 imm; +} __packed; + +/* + * Convert a virtual instruction address to a real instruction address. The + * decompressor needs to patch instructions within the kernel image based on + * their virtual addresses, while dynamic address translation is still + * disabled. Therefore a translation from virtual kernel image addresses to + * the corresponding physical addresses is required. + * + * After dynamic address translation is enabled and when the kernel needs to + * patch instructions such a translation is not required since the addresses + * are identical. + */ +static struct insn_ril *vaddress_to_insn(unsigned long vaddress) +{ +#ifdef __DECOMPRESSOR + return (struct insn_ril *)__kernel_pa(vaddress); +#else + return (struct insn_ril *)vaddress; +#endif +} + +static unsigned long insn_to_vaddress(struct insn_ril *insn) +{ +#ifdef __DECOMPRESSOR + return (unsigned long)__kernel_va(insn); +#else + return (unsigned long)insn; +#endif +} + +#define INSN_RIL_STRING_SIZE (sizeof(struct insn_ril) * 2 + 1) + +static void insn_ril_to_string(char *str, struct insn_ril *insn) +{ + u8 *ptr = (u8 *)insn; + int i; + + for (i = 0; i < sizeof(*insn); i++) + hex_byte_pack(&str[2 * i], ptr[i]); + str[2 * i] = 0; +} + +static void stack_protector_dump(struct insn_ril *old, struct insn_ril *new) +{ + char ostr[INSN_RIL_STRING_SIZE]; + char nstr[INSN_RIL_STRING_SIZE]; + + insn_ril_to_string(ostr, old); + insn_ril_to_string(nstr, new); + DEBUGP("%016lx: %s -> %s\n", insn_to_vaddress(old), ostr, nstr); +} + +static int stack_protector_verify(struct insn_ril *insn, unsigned long kernel_start) +{ + char istr[INSN_RIL_STRING_SIZE]; + unsigned long vaddress, offset; + + /* larl */ + if (insn->opc1 == 0xc0 && insn->opc2 == 0x0) + return 0; + /* lgrl */ + if (insn->opc1 == 0xc4 && insn->opc2 == 0x8) + return 0; + insn_ril_to_string(istr, insn); + vaddress = insn_to_vaddress(insn); + if (__is_defined(__DECOMPRESSOR)) { + offset = (unsigned long)insn - kernel_start + TEXT_OFFSET; + EMERGP("Unexpected instruction at %016lx/%016lx: %s\n", vaddress, offset, istr); + PANIC("Stackprotector error\n"); + } else { + EMERGP("Unexpected instruction at %016lx: %s\n", vaddress, istr); + } + return -EINVAL; +} + +int __stack_protector_apply(unsigned long *start, unsigned long *end, unsigned long kernel_start) +{ + unsigned long canary, *loc; + struct insn_ril *insn, new; + int rc; + + /* + * Convert LARL/LGRL instructions to LLILF so register R1 contains the + * address of the per-cpu / per-process stack canary: + * + * LARL/LGRL R1,__stack_chk_guard => LLILF R1,__lc_stack_canary + */ + canary = __LC_STACK_CANARY; + if (machine_has_relocated_lowcore()) + canary += LOWCORE_ALT_ADDRESS; + for (loc = start; loc < end; loc++) { + insn = vaddress_to_insn(*loc); + rc = stack_protector_verify(insn, kernel_start); + if (rc) + return rc; + new = *insn; + new.opc1 = 0xc0; + new.opc2 = 0xf; + new.imm = canary; + if (stack_protector_debug) + stack_protector_dump(insn, &new); + s390_kernel_write(insn, &new, sizeof(*insn)); + } + return 0; +} + +#ifdef __DECOMPRESSOR +void __stack_protector_apply_early(unsigned long kernel_start) +{ + unsigned long *start, *end; + + start = (unsigned long *)vmlinux.stack_prot_start; + end = (unsigned long *)vmlinux.stack_prot_end; + __stack_protector_apply(start, end, kernel_start); +} +#endif diff --git a/arch/s390/kernel/vdso64/Makefile b/arch/s390/kernel/vdso64/Makefile index d8f0df742809..49ad8dfc7c79 100644 --- a/arch/s390/kernel/vdso64/Makefile +++ b/arch/s390/kernel/vdso64/Makefile @@ -32,6 +32,7 @@ KBUILD_CFLAGS_64 := $(filter-out -mno-pic-data-is-text-relative,$(KBUILD_CFLAGS_ KBUILD_CFLAGS_64 := $(filter-out -munaligned-symbols,$(KBUILD_CFLAGS_64)) KBUILD_CFLAGS_64 := $(filter-out -fno-asynchronous-unwind-tables,$(KBUILD_CFLAGS_64)) KBUILD_CFLAGS_64 += -m64 -fPIC -fno-common -fno-builtin -fasynchronous-unwind-tables +KBUILD_CFLAGS_64 += -fno-stack-protector ldflags-y := -shared -soname=linux-vdso64.so.1 \ --hash-style=both --build-id=sha1 -T diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S index d74d4c52ccd0..d5b67c99a24a 100644 --- a/arch/s390/kernel/vmlinux.lds.S +++ b/arch/s390/kernel/vmlinux.lds.S @@ -150,6 +150,15 @@ SECTIONS *(.altinstr_replacement) } +#ifdef CONFIG_STACKPROTECTOR + . = ALIGN(8); + .stack_prot_table : { + __stack_prot_start = .; + KEEP(*(__stack_protector_loc)) + __stack_prot_end = .; + } +#endif + /* * Table with the patch locations to undo expolines */ @@ -257,6 +266,10 @@ SECTIONS QUAD(invalid_pg_dir) QUAD(__alt_instructions) QUAD(__alt_instructions_end) +#ifdef CONFIG_STACKPROTECTOR + QUAD(__stack_prot_start) + QUAD(__stack_prot_end) +#endif #ifdef CONFIG_KASAN QUAD(kasan_early_shadow_page) QUAD(kasan_early_shadow_pte) From 5e811b922ec91cef7b6b2647e93b0c64e626251b Mon Sep 17 00:00:00 2001 From: Jens Remus Date: Mon, 24 Nov 2025 15:12:42 +0100 Subject: [PATCH 87/92] s390/vdso: Use common STABS_DEBUG and DWARF_DEBUG macros This simplifies the vDSO linker script. The ELF_DETAILS macro was not used in addition, as done on arm64 and powerpc, as that would introduce an empty .modinfo section. Note that this rearranges the .comment section to follow after all of the debug sections. Signed-off-by: Jens Remus Reviewed-by: Heiko Carstens Signed-off-by: Heiko Carstens --- arch/s390/kernel/vdso64/vdso64.lds.S | 43 ++-------------------------- 1 file changed, 3 insertions(+), 40 deletions(-) diff --git a/arch/s390/kernel/vdso64/vdso64.lds.S b/arch/s390/kernel/vdso64/vdso64.lds.S index e4f6551ae898..7bec4de0e8e0 100644 --- a/arch/s390/kernel/vdso64/vdso64.lds.S +++ b/arch/s390/kernel/vdso64/vdso64.lds.S @@ -7,6 +7,7 @@ #include #include #include +#include #include OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390") @@ -59,47 +60,9 @@ SECTIONS _end = .; PROVIDE(end = .); - /* - * Stabs debugging sections are here too. - */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } + STABS_DEBUG + DWARF_DEBUG .comment 0 : { *(.comment) } - - /* - * DWARF debug sections. - * Symbols in the DWARF debugging sections are relative to the - * beginning of the section so we begin them at 0. - */ - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } - /* DWARF 3 */ - .debug_pubtypes 0 : { *(.debug_pubtypes) } - .debug_ranges 0 : { *(.debug_ranges) } .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) } /DISCARD/ : { From b3bdfdf1f93c38ea54b93421efc413e91e61f6b3 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 24 Nov 2025 16:04:28 +0100 Subject: [PATCH 88/92] s390: Rename head64.S to head.S All the code is 64 bit, therefore remove the superfluous suffix. Reviewed-by: Jens Remus Signed-off-by: Heiko Carstens --- arch/s390/kernel/Makefile | 2 +- arch/s390/kernel/{head64.S => head.S} | 0 arch/s390/kernel/setup.c | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename arch/s390/kernel/{head64.S => head.S} (100%) diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index ecaee29e724e..7df060b8eb4e 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile @@ -36,7 +36,7 @@ CFLAGS_stacktrace.o += -fno-optimize-sibling-calls CFLAGS_dumpstack.o += -fno-optimize-sibling-calls CFLAGS_unwind_bc.o += -fno-optimize-sibling-calls -obj-y := head64.o traps.o time.o process.o early.o setup.o idle.o vtime.o +obj-y := head.o traps.o time.o process.o early.o setup.o idle.o vtime.o obj-y += processor.o syscall.o ptrace.o signal.o cpcmd.o ebcdic.o nmi.o obj-y += debug.o irq.o ipl.o dis.o vdso.o cpufeature.o obj-y += sysinfo.o lgr.o os_info.o ctlreg.o diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head.S similarity index 100% rename from arch/s390/kernel/head64.S rename to arch/s390/kernel/head.S diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 1edb2281e7b0..c1fe0b53c5ac 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -110,7 +110,7 @@ struct exception_table_entry __amode31_ref *__stop_amode31_ex_table = _stop_amod * Because the AMODE31 sections are relocated below 2G at startup, * the content of control registers CR2, CR5 and CR15 must be updated * with new addresses after the relocation. The initial initialization of - * control registers occurs in head64.S and then gets updated again after AMODE31 + * control registers occurs in head.S and then gets updated again after AMODE31 * relocation. We must access the relevant AMODE31 tables indirectly via * pointers placed in the .amode31.refs linker section. Those pointers get * updated automatically during AMODE31 relocation and always contain a valid From c0087d807ae86cc82cc356e366d2dccf0e3bb225 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 24 Nov 2025 16:04:29 +0100 Subject: [PATCH 89/92] s390/vdso: Rename vdso64 to vdso Since compat is gone there is only a 64 bit vdso left. Remove the superfluous "64" suffix everywhere. Reviewed-by: Jens Remus Signed-off-by: Heiko Carstens --- arch/s390/Makefile | 4 +- arch/s390/include/asm/vdso-symbols.h | 4 +- arch/s390/kernel/Makefile | 2 +- arch/s390/kernel/signal.c | 6 +- arch/s390/kernel/vdso.c | 16 ++-- arch/s390/kernel/{vdso64 => vdso}/.gitignore | 2 +- arch/s390/kernel/vdso/Makefile | 80 +++++++++++++++++++ .../{vdso64 => vdso}/gen_vdso_offsets.sh | 2 +- arch/s390/kernel/{vdso64 => vdso}/getcpu.c | 0 arch/s390/kernel/{vdso64 => vdso}/note.S | 0 arch/s390/kernel/{vdso64 => vdso}/vdso.h | 6 +- .../{vdso64/vdso64.lds.S => vdso/vdso.lds.S} | 0 .../vdso64_generic.c => vdso/vdso_generic.c} | 0 .../{vdso64 => vdso}/vdso_user_wrapper.S | 0 .../vdso64_wrapper.S => vdso/vdso_wrapper.S} | 8 +- .../{vdso64 => vdso}/vgetrandom-chacha.S | 0 .../s390/kernel/{vdso64 => vdso}/vgetrandom.c | 0 arch/s390/kernel/vdso64/Makefile | 80 ------------------- 18 files changed, 104 insertions(+), 106 deletions(-) rename arch/s390/kernel/{vdso64 => vdso}/.gitignore (78%) create mode 100644 arch/s390/kernel/vdso/Makefile rename arch/s390/kernel/{vdso64 => vdso}/gen_vdso_offsets.sh (82%) rename arch/s390/kernel/{vdso64 => vdso}/getcpu.c (100%) rename arch/s390/kernel/{vdso64 => vdso}/note.S (100%) rename arch/s390/kernel/{vdso64 => vdso}/vdso.h (80%) rename arch/s390/kernel/{vdso64/vdso64.lds.S => vdso/vdso.lds.S} (100%) rename arch/s390/kernel/{vdso64/vdso64_generic.c => vdso/vdso_generic.c} (100%) rename arch/s390/kernel/{vdso64 => vdso}/vdso_user_wrapper.S (100%) rename arch/s390/kernel/{vdso64/vdso64_wrapper.S => vdso/vdso_wrapper.S} (64%) rename arch/s390/kernel/{vdso64 => vdso}/vgetrandom-chacha.S (100%) rename arch/s390/kernel/{vdso64 => vdso}/vgetrandom.c (100%) delete mode 100644 arch/s390/kernel/vdso64/Makefile diff --git a/arch/s390/Makefile b/arch/s390/Makefile index f0a670dcce71..3b8772628fde 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile @@ -151,9 +151,9 @@ ifeq ($(KBUILD_EXTMOD),) # this hack. prepare: vdso_prepare vdso_prepare: prepare0 - $(Q)$(MAKE) $(build)=arch/s390/kernel/vdso64 include/generated/vdso64-offsets.h + $(Q)$(MAKE) $(build)=arch/s390/kernel/vdso include/generated/vdso-offsets.h -vdso-install-y += arch/s390/kernel/vdso64/vdso64.so.dbg +vdso-install-y += arch/s390/kernel/vdso/vdso.so.dbg endif diff --git a/arch/s390/include/asm/vdso-symbols.h b/arch/s390/include/asm/vdso-symbols.h index 205da2c565c2..e3561e67c4e3 100644 --- a/arch/s390/include/asm/vdso-symbols.h +++ b/arch/s390/include/asm/vdso-symbols.h @@ -2,8 +2,8 @@ #ifndef __S390_VDSO_SYMBOLS_H__ #define __S390_VDSO_SYMBOLS_H__ -#include +#include -#define VDSO64_SYMBOL(tsk, name) ((tsk)->mm->context.vdso_base + (vdso64_offset_##name)) +#define VDSO_SYMBOL(tsk, name) ((tsk)->mm->context.vdso_base + (vdso_offset_##name)) #endif /* __S390_VDSO_SYMBOLS_H__ */ diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index 7df060b8eb4e..42c83d60d6fa 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile @@ -81,4 +81,4 @@ obj-$(CONFIG_PERF_EVENTS) += perf_pai.o obj-$(CONFIG_TRACEPOINTS) += trace.o # vdso -obj-y += vdso64/ +obj-y += vdso/ diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index e7775d121fa1..4874de5edea0 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c @@ -326,7 +326,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, if (ka->sa.sa_flags & SA_RESTORER) restorer = (unsigned long) ka->sa.sa_restorer; else - restorer = VDSO64_SYMBOL(current, sigreturn); + restorer = VDSO_SYMBOL(current, sigreturn); /* Set up registers for signal handler */ regs->gprs[14] = restorer; @@ -378,7 +378,7 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set, if (ksig->ka.sa.sa_flags & SA_RESTORER) restorer = (unsigned long) ksig->ka.sa.sa_restorer; else - restorer = VDSO64_SYMBOL(current, rt_sigreturn); + restorer = VDSO_SYMBOL(current, rt_sigreturn); /* Create siginfo on the signal stack */ if (copy_siginfo_to_user(&frame->info, &ksig->info)) @@ -490,7 +490,7 @@ void arch_do_signal_or_restart(struct pt_regs *regs) /* Restart with sys_restart_syscall */ regs->gprs[2] = regs->orig_gpr2; current->restart_block.arch_data = regs->psw.addr; - regs->psw.addr = VDSO64_SYMBOL(current, restart_syscall); + regs->psw.addr = VDSO_SYMBOL(current, restart_syscall); if (test_thread_flag(TIF_SINGLE_STEP)) clear_thread_flag(TIF_PER_TRAP); break; diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c index 83cc67cf21c8..a27a90a199be 100644 --- a/arch/s390/kernel/vdso.c +++ b/arch/s390/kernel/vdso.c @@ -22,7 +22,7 @@ #include #include -extern char vdso64_start[], vdso64_end[]; +extern char vdso_start[], vdso_end[]; static int vdso_mremap(const struct vm_special_mapping *sm, struct vm_area_struct *vma) @@ -31,7 +31,7 @@ static int vdso_mremap(const struct vm_special_mapping *sm, return 0; } -static struct vm_special_mapping vdso64_mapping = { +static struct vm_special_mapping vdso_mapping = { .name = "[vdso]", .mremap = vdso_mremap, }; @@ -46,7 +46,6 @@ early_initcall(vdso_getcpu_init); /* Must be called before SMP init */ static int map_vdso(unsigned long addr, unsigned long vdso_mapping_len) { unsigned long vvar_start, vdso_text_start, vdso_text_len; - struct vm_special_mapping *vdso_mapping; struct mm_struct *mm = current->mm; struct vm_area_struct *vma; int rc; @@ -55,8 +54,7 @@ static int map_vdso(unsigned long addr, unsigned long vdso_mapping_len) if (mmap_write_lock_killable(mm)) return -EINTR; - vdso_text_len = vdso64_end - vdso64_start; - vdso_mapping = &vdso64_mapping; + vdso_text_len = vdso_end - vdso_start; vvar_start = get_unmapped_area(NULL, addr, vdso_mapping_len, 0, 0); rc = vvar_start; if (IS_ERR_VALUE(vvar_start)) @@ -70,7 +68,7 @@ static int map_vdso(unsigned long addr, unsigned long vdso_mapping_len) vma = _install_special_mapping(mm, vdso_text_start, vdso_text_len, VM_READ|VM_EXEC|VM_SEALED_SYSMAP| VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC, - vdso_mapping); + &vdso_mapping); if (IS_ERR(vma)) { do_munmap(mm, vvar_start, PAGE_SIZE, NULL); rc = PTR_ERR(vma); @@ -110,7 +108,7 @@ static unsigned long vdso_addr(unsigned long start, unsigned long len) unsigned long vdso_text_size(void) { - return PAGE_ALIGN(vdso64_end - vdso64_start); + return PAGE_ALIGN(vdso_end - vdso_start); } unsigned long vdso_size(void) @@ -148,7 +146,7 @@ static void vdso_apply_alternatives(void) struct alt_instr *start, *end; const struct elf64_hdr *hdr; - hdr = (struct elf64_hdr *)vdso64_start; + hdr = (struct elf64_hdr *)vdso_start; shdr = (void *)hdr + hdr->e_shoff; alt = find_section(hdr, shdr, ".altinstructions"); if (!alt) @@ -161,7 +159,7 @@ static void vdso_apply_alternatives(void) static int __init vdso_init(void) { vdso_apply_alternatives(); - vdso64_mapping.pages = vdso_setup_pages(vdso64_start, vdso64_end); + vdso_mapping.pages = vdso_setup_pages(vdso_start, vdso_end); return 0; } arch_initcall(vdso_init); diff --git a/arch/s390/kernel/vdso64/.gitignore b/arch/s390/kernel/vdso/.gitignore similarity index 78% rename from arch/s390/kernel/vdso64/.gitignore rename to arch/s390/kernel/vdso/.gitignore index 4ec80685fecc..652e31d82582 100644 --- a/arch/s390/kernel/vdso64/.gitignore +++ b/arch/s390/kernel/vdso/.gitignore @@ -1,2 +1,2 @@ # SPDX-License-Identifier: GPL-2.0-only -vdso64.lds +vdso.lds diff --git a/arch/s390/kernel/vdso/Makefile b/arch/s390/kernel/vdso/Makefile new file mode 100644 index 000000000000..924be0a6a2df --- /dev/null +++ b/arch/s390/kernel/vdso/Makefile @@ -0,0 +1,80 @@ +# SPDX-License-Identifier: GPL-2.0 +# List of files in the vdso + +# Include the generic Makefile to check the built vdso. +include $(srctree)/lib/vdso/Makefile.include +obj-vdso = vdso_user_wrapper.o note.o vgetrandom-chacha.o +obj-cvdso = vdso_generic.o getcpu.o vgetrandom.o +VDSO_CFLAGS_REMOVE := -pg $(CC_FLAGS_FTRACE) $(CC_FLAGS_EXPOLINE) +CFLAGS_REMOVE_getcpu.o = $(VDSO_CFLAGS_REMOVE) +CFLAGS_REMOVE_vgetrandom.o = $(VDSO_CFLAGS_REMOVE) +CFLAGS_REMOVE_vdso_generic.o = $(VDSO_CFLAGS_REMOVE) + +ifneq ($(c-getrandom-y),) + CFLAGS_vgetrandom.o += -include $(c-getrandom-y) +endif + +# Build rules + +targets := $(obj-vdso) $(obj-cvdso) vdso.so vdso.so.dbg +obj-vdso := $(addprefix $(obj)/, $(obj-vdso)) +obj-cvdso := $(addprefix $(obj)/, $(obj-cvdso)) + +KBUILD_AFLAGS += -DBUILD_VDSO +KBUILD_CFLAGS += -DBUILD_VDSO -DDISABLE_BRANCH_PROFILING + +KBUILD_AFLAGS_VDSO := $(filter-out -m64,$(KBUILD_AFLAGS)) +KBUILD_AFLAGS_VDSO += -m64 + +KBUILD_CFLAGS_VDSO := $(filter-out -m64,$(KBUILD_CFLAGS)) +KBUILD_CFLAGS_VDSO := $(filter-out -mpacked-stack,$(KBUILD_CFLAGS_VDSO)) +KBUILD_CFLAGS_VDSO := $(filter-out -mno-pic-data-is-text-relative,$(KBUILD_CFLAGS_VDSO)) +KBUILD_CFLAGS_VDSO := $(filter-out -munaligned-symbols,$(KBUILD_CFLAGS_VDSO)) +KBUILD_CFLAGS_VDSO := $(filter-out -fno-asynchronous-unwind-tables,$(KBUILD_CFLAGS_VDSO)) +KBUILD_CFLAGS_VDSO += -m64 -fPIC -fno-common -fno-builtin -fasynchronous-unwind-tables +KBUILD_CFLAGS_VDSO += -fno-stack-protector +ldflags-y := -shared -soname=linux-vdso.so.1 \ + --hash-style=both --build-id=sha1 -T + +$(targets:%=$(obj)/%.dbg): KBUILD_CFLAGS = $(KBUILD_CFLAGS_VDSO) +$(targets:%=$(obj)/%.dbg): KBUILD_AFLAGS = $(KBUILD_AFLAGS_VDSO) + +obj-y += vdso_wrapper.o +targets += vdso.lds +CPPFLAGS_vdso.lds += -P -C -U$(ARCH) + +# Force dependency (incbin is bad) +$(obj)/vdso_wrapper.o : $(obj)/vdso.so + +quiet_cmd_vdso_and_check = VDSO $@ + cmd_vdso_and_check = $(cmd_ld); $(cmd_vdso_check) + +# link rule for the .so file, .lds has to be first +$(obj)/vdso.so.dbg: $(obj)/vdso.lds $(obj-vdso) $(obj-cvdso) FORCE + $(call if_changed,vdso_and_check) + +# strip rule for the .so file +$(obj)/%.so: OBJCOPYFLAGS := -S +$(obj)/%.so: $(obj)/%.so.dbg FORCE + $(call if_changed,objcopy) + +# assembly rules for the .S files +$(obj-vdso): %.o: %.S FORCE + $(call if_changed_dep,vdsoas) + +$(obj-cvdso): %.o: %.c FORCE + $(call if_changed_dep,vdsocc) + +# actual build commands +quiet_cmd_vdsoas = VDSOA $@ + cmd_vdsoas = $(CC) $(a_flags) -c -o $@ $< +quiet_cmd_vdsocc = VDSOC $@ + cmd_vdsocc = $(CC) $(c_flags) -c -o $@ $< + +# Generate VDSO offsets using helper script +gen-vdsosym := $(src)/gen_vdso_offsets.sh +quiet_cmd_vdsosym = VDSOSYM $@ + cmd_vdsosym = $(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@ + +include/generated/vdso-offsets.h: $(obj)/vdso.so.dbg FORCE + $(call if_changed,vdsosym) diff --git a/arch/s390/kernel/vdso64/gen_vdso_offsets.sh b/arch/s390/kernel/vdso/gen_vdso_offsets.sh similarity index 82% rename from arch/s390/kernel/vdso64/gen_vdso_offsets.sh rename to arch/s390/kernel/vdso/gen_vdso_offsets.sh index 37f05cb38dad..359982fb002d 100755 --- a/arch/s390/kernel/vdso64/gen_vdso_offsets.sh +++ b/arch/s390/kernel/vdso/gen_vdso_offsets.sh @@ -12,4 +12,4 @@ # LC_ALL=C -sed -n 's/\([0-9a-f]*\) . __kernel_\(.*\)/\#define vdso64_offset_\2\t0x\1/p' +sed -n 's/\([0-9a-f]*\) . __kernel_\(.*\)/\#define vdso_offset_\2\t0x\1/p' diff --git a/arch/s390/kernel/vdso64/getcpu.c b/arch/s390/kernel/vdso/getcpu.c similarity index 100% rename from arch/s390/kernel/vdso64/getcpu.c rename to arch/s390/kernel/vdso/getcpu.c diff --git a/arch/s390/kernel/vdso64/note.S b/arch/s390/kernel/vdso/note.S similarity index 100% rename from arch/s390/kernel/vdso64/note.S rename to arch/s390/kernel/vdso/note.S diff --git a/arch/s390/kernel/vdso64/vdso.h b/arch/s390/kernel/vdso/vdso.h similarity index 80% rename from arch/s390/kernel/vdso64/vdso.h rename to arch/s390/kernel/vdso/vdso.h index 9e5397e7b590..8cff033dd854 100644 --- a/arch/s390/kernel/vdso64/vdso.h +++ b/arch/s390/kernel/vdso/vdso.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __ARCH_S390_KERNEL_VDSO64_VDSO_H -#define __ARCH_S390_KERNEL_VDSO64_VDSO_H +#ifndef __ARCH_S390_KERNEL_VDSO_VDSO_H +#define __ARCH_S390_KERNEL_VDSO_VDSO_H #include @@ -12,4 +12,4 @@ int __s390_vdso_clock_gettime(clockid_t clock, struct __kernel_timespec *ts); int __s390_vdso_clock_getres(clockid_t clock, struct __kernel_timespec *ts); ssize_t __kernel_getrandom(void *buffer, size_t len, unsigned int flags, void *opaque_state, size_t opaque_len); -#endif /* __ARCH_S390_KERNEL_VDSO64_VDSO_H */ +#endif /* __ARCH_S390_KERNEL_VDSO_VDSO_H */ diff --git a/arch/s390/kernel/vdso64/vdso64.lds.S b/arch/s390/kernel/vdso/vdso.lds.S similarity index 100% rename from arch/s390/kernel/vdso64/vdso64.lds.S rename to arch/s390/kernel/vdso/vdso.lds.S diff --git a/arch/s390/kernel/vdso64/vdso64_generic.c b/arch/s390/kernel/vdso/vdso_generic.c similarity index 100% rename from arch/s390/kernel/vdso64/vdso64_generic.c rename to arch/s390/kernel/vdso/vdso_generic.c diff --git a/arch/s390/kernel/vdso64/vdso_user_wrapper.S b/arch/s390/kernel/vdso/vdso_user_wrapper.S similarity index 100% rename from arch/s390/kernel/vdso64/vdso_user_wrapper.S rename to arch/s390/kernel/vdso/vdso_user_wrapper.S diff --git a/arch/s390/kernel/vdso64/vdso64_wrapper.S b/arch/s390/kernel/vdso/vdso_wrapper.S similarity index 64% rename from arch/s390/kernel/vdso64/vdso64_wrapper.S rename to arch/s390/kernel/vdso/vdso_wrapper.S index 672184998623..f69e62a14978 100644 --- a/arch/s390/kernel/vdso64/vdso64_wrapper.S +++ b/arch/s390/kernel/vdso/vdso_wrapper.S @@ -5,11 +5,11 @@ __PAGE_ALIGNED_DATA - .globl vdso64_start, vdso64_end + .globl vdso_start, vdso_end .balign PAGE_SIZE -vdso64_start: - .incbin "arch/s390/kernel/vdso64/vdso64.so" +vdso_start: + .incbin "arch/s390/kernel/vdso/vdso.so" .balign PAGE_SIZE -vdso64_end: +vdso_end: .previous diff --git a/arch/s390/kernel/vdso64/vgetrandom-chacha.S b/arch/s390/kernel/vdso/vgetrandom-chacha.S similarity index 100% rename from arch/s390/kernel/vdso64/vgetrandom-chacha.S rename to arch/s390/kernel/vdso/vgetrandom-chacha.S diff --git a/arch/s390/kernel/vdso64/vgetrandom.c b/arch/s390/kernel/vdso/vgetrandom.c similarity index 100% rename from arch/s390/kernel/vdso64/vgetrandom.c rename to arch/s390/kernel/vdso/vgetrandom.c diff --git a/arch/s390/kernel/vdso64/Makefile b/arch/s390/kernel/vdso64/Makefile deleted file mode 100644 index 49ad8dfc7c79..000000000000 --- a/arch/s390/kernel/vdso64/Makefile +++ /dev/null @@ -1,80 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# List of files in the vdso - -# Include the generic Makefile to check the built vdso. -include $(srctree)/lib/vdso/Makefile.include -obj-vdso64 = vdso_user_wrapper.o note.o vgetrandom-chacha.o -obj-cvdso64 = vdso64_generic.o getcpu.o vgetrandom.o -VDSO_CFLAGS_REMOVE := -pg $(CC_FLAGS_FTRACE) $(CC_FLAGS_EXPOLINE) -CFLAGS_REMOVE_getcpu.o = $(VDSO_CFLAGS_REMOVE) -CFLAGS_REMOVE_vgetrandom.o = $(VDSO_CFLAGS_REMOVE) -CFLAGS_REMOVE_vdso64_generic.o = $(VDSO_CFLAGS_REMOVE) - -ifneq ($(c-getrandom-y),) - CFLAGS_vgetrandom.o += -include $(c-getrandom-y) -endif - -# Build rules - -targets := $(obj-vdso64) $(obj-cvdso64) vdso64.so vdso64.so.dbg -obj-vdso64 := $(addprefix $(obj)/, $(obj-vdso64)) -obj-cvdso64 := $(addprefix $(obj)/, $(obj-cvdso64)) - -KBUILD_AFLAGS += -DBUILD_VDSO -KBUILD_CFLAGS += -DBUILD_VDSO -DDISABLE_BRANCH_PROFILING - -KBUILD_AFLAGS_64 := $(filter-out -m64,$(KBUILD_AFLAGS)) -KBUILD_AFLAGS_64 += -m64 - -KBUILD_CFLAGS_64 := $(filter-out -m64,$(KBUILD_CFLAGS)) -KBUILD_CFLAGS_64 := $(filter-out -mpacked-stack,$(KBUILD_CFLAGS_64)) -KBUILD_CFLAGS_64 := $(filter-out -mno-pic-data-is-text-relative,$(KBUILD_CFLAGS_64)) -KBUILD_CFLAGS_64 := $(filter-out -munaligned-symbols,$(KBUILD_CFLAGS_64)) -KBUILD_CFLAGS_64 := $(filter-out -fno-asynchronous-unwind-tables,$(KBUILD_CFLAGS_64)) -KBUILD_CFLAGS_64 += -m64 -fPIC -fno-common -fno-builtin -fasynchronous-unwind-tables -KBUILD_CFLAGS_64 += -fno-stack-protector -ldflags-y := -shared -soname=linux-vdso64.so.1 \ - --hash-style=both --build-id=sha1 -T - -$(targets:%=$(obj)/%.dbg): KBUILD_CFLAGS = $(KBUILD_CFLAGS_64) -$(targets:%=$(obj)/%.dbg): KBUILD_AFLAGS = $(KBUILD_AFLAGS_64) - -obj-y += vdso64_wrapper.o -targets += vdso64.lds -CPPFLAGS_vdso64.lds += -P -C -U$(ARCH) - -# Force dependency (incbin is bad) -$(obj)/vdso64_wrapper.o : $(obj)/vdso64.so - -quiet_cmd_vdso_and_check = VDSO $@ - cmd_vdso_and_check = $(cmd_ld); $(cmd_vdso_check) - -# link rule for the .so file, .lds has to be first -$(obj)/vdso64.so.dbg: $(obj)/vdso64.lds $(obj-vdso64) $(obj-cvdso64) FORCE - $(call if_changed,vdso_and_check) - -# strip rule for the .so file -$(obj)/%.so: OBJCOPYFLAGS := -S -$(obj)/%.so: $(obj)/%.so.dbg FORCE - $(call if_changed,objcopy) - -# assembly rules for the .S files -$(obj-vdso64): %.o: %.S FORCE - $(call if_changed_dep,vdso64as) - -$(obj-cvdso64): %.o: %.c FORCE - $(call if_changed_dep,vdso64cc) - -# actual build commands -quiet_cmd_vdso64as = VDSO64A $@ - cmd_vdso64as = $(CC) $(a_flags) -c -o $@ $< -quiet_cmd_vdso64cc = VDSO64C $@ - cmd_vdso64cc = $(CC) $(c_flags) -c -o $@ $< - -# Generate VDSO offsets using helper script -gen-vdsosym := $(src)/gen_vdso_offsets.sh -quiet_cmd_vdsosym = VDSOSYM $@ - cmd_vdsosym = $(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@ - -include/generated/vdso64-offsets.h: $(obj)/vdso64.so.dbg FORCE - $(call if_changed,vdsosym) From 509c34924d5a89a73c1470e9265be86baffd1286 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 25 Nov 2025 12:36:26 +0100 Subject: [PATCH 90/92] s390/vdso: Get rid of -m64 flag handling The compiler/assembler flag -m64 is added and removed at two locations. This pointless exercise is a leftover to keep the 31 and 64 bit vdso Makefiles as symmetrical as possible. Given that the 31 bit vdso code does not exist anymore, remove the -m64 flag handling. Suggested-by: Jens Remus Reviewed-by: Jens Remus Signed-off-by: Heiko Carstens --- arch/s390/kernel/vdso/Makefile | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/arch/s390/kernel/vdso/Makefile b/arch/s390/kernel/vdso/Makefile index 924be0a6a2df..2fa12d4ac106 100644 --- a/arch/s390/kernel/vdso/Makefile +++ b/arch/s390/kernel/vdso/Makefile @@ -20,18 +20,14 @@ targets := $(obj-vdso) $(obj-cvdso) vdso.so vdso.so.dbg obj-vdso := $(addprefix $(obj)/, $(obj-vdso)) obj-cvdso := $(addprefix $(obj)/, $(obj-cvdso)) -KBUILD_AFLAGS += -DBUILD_VDSO -KBUILD_CFLAGS += -DBUILD_VDSO -DDISABLE_BRANCH_PROFILING +KBUILD_AFLAGS_VDSO := $(KBUILD_AFLAGS) -DBUILD_VDSO -KBUILD_AFLAGS_VDSO := $(filter-out -m64,$(KBUILD_AFLAGS)) -KBUILD_AFLAGS_VDSO += -m64 - -KBUILD_CFLAGS_VDSO := $(filter-out -m64,$(KBUILD_CFLAGS)) +KBUILD_CFLAGS_VDSO := $(KBUILD_CFLAGS) -DBUILD_VDSO -DDISABLE_BRANCH_PROFILING KBUILD_CFLAGS_VDSO := $(filter-out -mpacked-stack,$(KBUILD_CFLAGS_VDSO)) KBUILD_CFLAGS_VDSO := $(filter-out -mno-pic-data-is-text-relative,$(KBUILD_CFLAGS_VDSO)) KBUILD_CFLAGS_VDSO := $(filter-out -munaligned-symbols,$(KBUILD_CFLAGS_VDSO)) KBUILD_CFLAGS_VDSO := $(filter-out -fno-asynchronous-unwind-tables,$(KBUILD_CFLAGS_VDSO)) -KBUILD_CFLAGS_VDSO += -m64 -fPIC -fno-common -fno-builtin -fasynchronous-unwind-tables +KBUILD_CFLAGS_VDSO += -fPIC -fno-common -fno-builtin -fasynchronous-unwind-tables KBUILD_CFLAGS_VDSO += -fno-stack-protector ldflags-y := -shared -soname=linux-vdso.so.1 \ --hash-style=both --build-id=sha1 -T From 1c93edfd506ccaf9e9982dfdafc91cd2d444ad63 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 26 Nov 2025 11:19:10 +0100 Subject: [PATCH 91/92] s390/entry: Use lay instead of aghik Use the lay instruction instead of aghik. aghik is only available since z196, therefore compiling the kernel for z10 results in this error: arch/s390/kernel/entry.S: Assembler messages: arch/s390/kernel/entry.S:165: Error: Unrecognized opcode: `aghik' Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202511261518.nBbQN5h7-lkp@intel.com/ Fixes: f5730d44e05e ("s390: Add stackprotector support") Reviewed-by: Jan Polensky Signed-off-by: Heiko Carstens --- arch/s390/kernel/entry.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 24cc33e668ea..c360087807d8 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -162,7 +162,7 @@ SYM_FUNC_START(__switch_to_asm) stg %r3,__LC_CURRENT(%r13) # store task struct of next stg %r15,__LC_KERNEL_STACK(%r13) # store end of kernel stack lg %r15,__THREAD_ksp(%r1,%r3) # load kernel stack of next - aghik %r4,%r3,__TASK_pid + lay %r4,__TASK_pid(%r3) mvc __LC_CURRENT_PID(4,%r13),0(%r4) # store pid of next ALTERNATIVE "nop", "lpp _LPP_OFFSET(%r13)", ALT_FACILITY(40) #ifdef CONFIG_STACKPROTECTOR From 283f90b50de077970c429e5b9b2745d5e94a5a45 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 26 Nov 2025 15:43:12 +0100 Subject: [PATCH 92/92] watchdog: diag288_wdt: Remove KMSG_COMPONENT macro The KMSG_COMPONENT macro is a leftover of the s390 specific "kernel message catalog" from 2008 [1] which never made it upstream. The macro was added to s390 code to allow for an out-of-tree patch which used this to generate unique message ids. Also this out-of-tree doesn't exist anymore. Remove the macro in order to get rid of a pointless indirection. [1] https://lwn.net/Articles/292650/ Reviewed-by: Guenter Roeck Signed-off-by: Heiko Carstens --- drivers/watchdog/diag288_wdt.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/watchdog/diag288_wdt.c b/drivers/watchdog/diag288_wdt.c index 887d5a6c155b..9daed2758ae5 100644 --- a/drivers/watchdog/diag288_wdt.c +++ b/drivers/watchdog/diag288_wdt.c @@ -18,8 +18,7 @@ * */ -#define KMSG_COMPONENT "diag288_wdt" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "diag288_wdt: " fmt #include #include