Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 's390-6.18-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux

Pull s390 updates from Alexander Gordeev:

- Refactor SCLP memory hotplug code

- Introduce common boot_panic() decompressor helper macro and use it to
get rid of nearly few identical implementations

- Take into account additional key generation flags and forward it to
the ep11 implementation. With that allow users to modify the key
generation process, e.g. provide valid combinations of XCP_BLOB_*
flags

- Replace kmalloc() + copy_from_user() with memdup_user_nul() in s390
debug facility and HMC driver

- Add DAX support for DCSS memory block devices

- Make the compiler statement attribute "assume" available with a new
__assume macro

- Rework ffs() and fls() family bitops functions, including source code
improvements and generated code optimizations. Use the newly
introduced __assume macro for that

- Enable additional network features in default configurations

- Use __GFP_ACCOUNT flag for user page table allocations to add missing
kmemcg accounting

- Add WQ_PERCPU flag to explicitly request the use of the per-CPU
workqueue for 3590 tape driver

- Switch power reading to the per-CPU and the Hiperdispatch to the
default workqueue

- Add memory allocation profiling hooks to allow better profiling data
and the /proc/allocinfo output similar to other architectures

* tag 's390-6.18-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (21 commits)
s390/mm: Add memory allocation profiling hooks
s390: Replace use of system_wq with system_dfl_wq
s390/diag324: Replace use of system_wq with system_percpu_wq
s390/tape: Add WQ_PERCPU to alloc_workqueue users
s390/bitops: Switch to generic ffs() if supported by compiler
s390/bitops: Switch to generic fls(), fls64(), etc.
s390/mm: Use __GFP_ACCOUNT for user page table allocations
s390/configs: Enable additional network features
s390/bitops: Cleanup __flogr()
s390/bitops: Use __assume() for __flogr() inline assembly return value
compiler_types: Add __assume macro
s390/bitops: Limit return value range of __flogr()
s390/dcssblk: Add DAX support
s390/hmcdrv: Replace kmalloc() + copy_from_user() with memdup_user_nul()
s390/debug: Replace kmalloc() + copy_from_user() with memdup_user_nul()
s390/pkey: Forward keygenflags to ep11_unwrapkey
s390/boot: Add common boot_panic() code
s390/bitops: Optimize inlining
s390/bitops: Slightly optimize ffs() and fls64()
s390/sclp: Move memory hotplug code for better modularity
...

+611 -575
+7
arch/s390/Kconfig
··· 49 49 depends on KASAN 50 50 default 0x1C000000000000 51 51 52 + config CC_HAS_BUILTIN_FFS 53 + def_bool !(CC_IS_GCC && GCC_VERSION < 160000) 54 + help 55 + GCC versions before 16.0.0 generate library calls to ffs() 56 + for __builtin_ffs() even when __has_builtin(__builtin_ffs) 57 + is true. 58 + 52 59 config CC_ASM_FLAG_OUTPUT_BROKEN 53 60 def_bool CC_IS_GCC && GCC_VERSION < 140200 54 61 help
+8
arch/s390/boot/boot.h
··· 10 10 11 11 #include <linux/printk.h> 12 12 #include <asm/physmem_info.h> 13 + #include <asm/stacktrace.h> 13 14 14 15 struct vmlinux_info { 15 16 unsigned long entry; ··· 89 88 #define boot_notice(fmt, ...) boot_printk(KERN_NOTICE boot_fmt(fmt), ##__VA_ARGS__) 90 89 #define boot_info(fmt, ...) boot_printk(KERN_INFO boot_fmt(fmt), ##__VA_ARGS__) 91 90 #define boot_debug(fmt, ...) boot_printk(KERN_DEBUG boot_fmt(fmt), ##__VA_ARGS__) 91 + 92 + #define boot_panic(...) do { \ 93 + boot_emerg(__VA_ARGS__); \ 94 + print_stacktrace(current_frame_address()); \ 95 + boot_emerg(" -- System halted\n"); \ 96 + disabled_wait(); \ 97 + } while (0) 92 98 93 99 extern struct machine_info machine; 94 100 extern int boot_console_loglevel;
+1 -3
arch/s390/boot/decompressor.c
··· 68 68 { 69 69 if (bootdebug) 70 70 boot_rb_dump(); 71 - boot_emerg("Decompression error: %s\n", m); 72 - boot_emerg(" -- System halted\n"); 73 - disabled_wait(); 71 + boot_panic("Decompression error: %s\n", m); 74 72 } 75 73 76 74 unsigned long mem_safe_offset(void)
+1 -3
arch/s390/boot/physmem_info.c
··· 228 228 boot_emerg("Usable online memory total: %lu Reserved: %lu Free: %lu\n", 229 229 total_mem, total_reserved_mem, 230 230 total_mem > total_reserved_mem ? total_mem - total_reserved_mem : 0); 231 - print_stacktrace(current_frame_address()); 232 - boot_emerg(" -- System halted\n"); 233 - disabled_wait(); 231 + boot_panic("Oom\n"); 234 232 } 235 233 236 234 static void _physmem_reserve(enum reserved_range_type type, unsigned long addr, unsigned long size)
+3 -10
arch/s390/boot/startup.c
··· 44 44 u64 __bootdata_preserved(stfle_fac_list[16]); 45 45 struct oldmem_data __bootdata_preserved(oldmem_data); 46 46 47 - void error(char *x) 48 - { 49 - boot_emerg("%s\n", x); 50 - boot_emerg(" -- System halted\n"); 51 - disabled_wait(); 52 - } 53 - 54 47 static char sysinfo_page[PAGE_SIZE] __aligned(PAGE_SIZE); 55 48 56 49 static void detect_machine_type(void) ··· 213 220 static void copy_bootdata(void) 214 221 { 215 222 if (__boot_data_end - __boot_data_start != vmlinux.bootdata_size) 216 - error(".boot.data section size mismatch"); 223 + boot_panic(".boot.data section size mismatch\n"); 217 224 memcpy((void *)vmlinux.bootdata_off, __boot_data_start, vmlinux.bootdata_size); 218 225 if (__boot_data_preserved_end - __boot_data_preserved_start != vmlinux.bootdata_preserved_size) 219 - error(".boot.preserved.data section size mismatch"); 226 + boot_panic(".boot.preserved.data section size mismatch\n"); 220 227 memcpy((void *)vmlinux.bootdata_preserved_off, __boot_data_preserved_start, vmlinux.bootdata_preserved_size); 221 228 } 222 229 ··· 230 237 for (reloc = (int *)__vmlinux_relocs_64_start; reloc < (int *)__vmlinux_relocs_64_end; reloc++) { 231 238 loc = (long)*reloc + phys_offset; 232 239 if (loc < min_addr || loc > max_addr) 233 - error("64-bit relocation outside of kernel!\n"); 240 + boot_panic("64-bit relocation outside of kernel!\n"); 234 241 *(u64 *)loc += offset; 235 242 } 236 243 }
+6
arch/s390/configs/debug_defconfig
··· 118 118 CONFIG_PACKET_DIAG=m 119 119 CONFIG_UNIX=y 120 120 CONFIG_UNIX_DIAG=m 121 + CONFIG_TLS=m 122 + CONFIG_TLS_DEVICE=y 123 + CONFIG_TLS_TOE=y 121 124 CONFIG_XFRM_USER=m 122 125 CONFIG_NET_KEY=m 126 + CONFIG_XDP_SOCKETS=y 127 + CONFIG_XDP_SOCKETS_DIAG=m 123 128 CONFIG_SMC_DIAG=m 124 129 CONFIG_SMC_LO=y 125 130 CONFIG_INET=y ··· 547 542 CONFIG_MLX4_EN=m 548 543 CONFIG_MLX5_CORE=m 549 544 CONFIG_MLX5_CORE_EN=y 545 + CONFIG_MLX5_SF=y 550 546 # CONFIG_NET_VENDOR_META is not set 551 547 # CONFIG_NET_VENDOR_MICREL is not set 552 548 # CONFIG_NET_VENDOR_MICROCHIP is not set
+6
arch/s390/configs/defconfig
··· 109 109 CONFIG_PACKET_DIAG=m 110 110 CONFIG_UNIX=y 111 111 CONFIG_UNIX_DIAG=m 112 + CONFIG_TLS=m 113 + CONFIG_TLS_DEVICE=y 114 + CONFIG_TLS_TOE=y 112 115 CONFIG_XFRM_USER=m 113 116 CONFIG_NET_KEY=m 117 + CONFIG_XDP_SOCKETS=y 118 + CONFIG_XDP_SOCKETS_DIAG=m 114 119 CONFIG_SMC_DIAG=m 115 120 CONFIG_SMC_LO=y 116 121 CONFIG_INET=y ··· 537 532 CONFIG_MLX4_EN=m 538 533 CONFIG_MLX5_CORE=m 539 534 CONFIG_MLX5_CORE_EN=y 535 + CONFIG_MLX5_SF=y 540 536 # CONFIG_NET_VENDOR_META is not set 541 537 # CONFIG_NET_VENDOR_MICREL is not set 542 538 # CONFIG_NET_VENDOR_MICROCHIP is not set
+27 -61
arch/s390/include/asm/bitops.h
··· 122 122 return test_bit(nr ^ (BITS_PER_LONG - 1), ptr); 123 123 } 124 124 125 + #ifndef CONFIG_CC_HAS_BUILTIN_FFS 126 + 125 127 /** 126 128 * __flogr - find leftmost one 127 129 * @word - The word to search ··· 132 130 * where the most significant bit has bit number 0. 133 131 * If no bit is set this function returns 64. 134 132 */ 135 - static inline unsigned char __flogr(unsigned long word) 133 + static __always_inline __attribute_const__ unsigned long __flogr(unsigned long word) 136 134 { 137 - if (__builtin_constant_p(word)) { 138 - unsigned long bit = 0; 135 + unsigned long bit; 139 136 137 + if (__builtin_constant_p(word)) { 138 + bit = 0; 140 139 if (!word) 141 140 return 64; 142 141 if (!(word & 0xffffffff00000000UL)) { ··· 166 163 } 167 164 return bit; 168 165 } else { 169 - union register_pair rp; 166 + union register_pair rp __uninitialized; 170 167 171 168 rp.even = word; 172 - asm volatile( 173 - " flogr %[rp],%[rp]\n" 174 - : [rp] "+d" (rp.pair) : : "cc"); 175 - return rp.even; 169 + asm("flogr %[rp],%[rp]" 170 + : [rp] "+d" (rp.pair) : : "cc"); 171 + bit = rp.even; 172 + /* 173 + * The result of the flogr instruction is a value in the range 174 + * of 0..64. Let the compiler know that the AND operation can 175 + * be optimized away. 176 + */ 177 + __assume(bit <= 64); 178 + return bit & 127; 176 179 } 177 - } 178 - 179 - /** 180 - * __ffs - find first bit in word. 181 - * @word: The word to search 182 - * 183 - * Undefined if no bit exists, so code should check against 0 first. 184 - */ 185 - static inline __attribute_const__ unsigned long __ffs(unsigned long word) 186 - { 187 - return __flogr(-word & word) ^ (BITS_PER_LONG - 1); 188 180 } 189 181 190 182 /** ··· 189 191 * This is defined the same way as the libc and 190 192 * compiler builtin ffs routines (man ffs). 191 193 */ 192 - static inline __attribute_const__ int ffs(int word) 194 + static __always_inline __flatten __attribute_const__ int ffs(int word) 193 195 { 194 - unsigned long mask = 2 * BITS_PER_LONG - 1; 195 196 unsigned int val = (unsigned int)word; 196 197 197 - return (1 + (__flogr(-val & val) ^ (BITS_PER_LONG - 1))) & mask; 198 + return BITS_PER_LONG - __flogr(-val & val); 198 199 } 199 200 200 - /** 201 - * __fls - find last (most-significant) set bit in a long word 202 - * @word: the word to search 203 - * 204 - * Undefined if no set bit exists, so code should check against 0 first. 205 - */ 206 - static inline __attribute_const__ unsigned long __fls(unsigned long word) 207 - { 208 - return __flogr(word) ^ (BITS_PER_LONG - 1); 209 - } 201 + #else /* CONFIG_CC_HAS_BUILTIN_FFS */ 210 202 211 - /** 212 - * fls64 - find last set bit in a 64-bit word 213 - * @word: the word to search 214 - * 215 - * This is defined in a similar way as the libc and compiler builtin 216 - * ffsll, but returns the position of the most significant set bit. 217 - * 218 - * fls64(value) returns 0 if value is 0 or the position of the last 219 - * set bit if value is nonzero. The last (most significant) bit is 220 - * at position 64. 221 - */ 222 - static inline __attribute_const__ int fls64(unsigned long word) 223 - { 224 - unsigned long mask = 2 * BITS_PER_LONG - 1; 203 + #include <asm-generic/bitops/builtin-ffs.h> 225 204 226 - return (1 + (__flogr(word) ^ (BITS_PER_LONG - 1))) & mask; 227 - } 205 + #endif /* CONFIG_CC_HAS_BUILTIN_FFS */ 228 206 229 - /** 230 - * fls - find last (most-significant) bit set 231 - * @word: the word to search 232 - * 233 - * This is defined the same way as ffs. 234 - * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32. 235 - */ 236 - static inline __attribute_const__ int fls(unsigned int word) 237 - { 238 - return fls64(word); 239 - } 240 - 207 + #include <asm-generic/bitops/builtin-__ffs.h> 208 + #include <asm-generic/bitops/ffz.h> 209 + #include <asm-generic/bitops/builtin-__fls.h> 210 + #include <asm-generic/bitops/builtin-fls.h> 211 + #include <asm-generic/bitops/fls64.h> 241 212 #include <asm/arch_hweight.h> 242 213 #include <asm-generic/bitops/const_hweight.h> 243 - #include <asm-generic/bitops/ffz.h> 244 214 #include <asm-generic/bitops/sched.h> 245 215 #include <asm-generic/bitops/le.h> 246 216 #include <asm-generic/bitops/ext2-atomic-setbit.h>
+19 -11
arch/s390/include/asm/pgalloc.h
··· 19 19 20 20 #define CRST_ALLOC_ORDER 2 21 21 22 - unsigned long *crst_table_alloc(struct mm_struct *); 22 + unsigned long *crst_table_alloc_noprof(struct mm_struct *); 23 + #define crst_table_alloc(...) alloc_hooks(crst_table_alloc_noprof(__VA_ARGS__)) 23 24 void crst_table_free(struct mm_struct *, unsigned long *); 24 25 25 - unsigned long *page_table_alloc(struct mm_struct *); 26 - struct ptdesc *page_table_alloc_pgste(struct mm_struct *mm); 26 + unsigned long *page_table_alloc_noprof(struct mm_struct *); 27 + #define page_table_alloc(...) alloc_hooks(page_table_alloc_noprof(__VA_ARGS__)) 27 28 void page_table_free(struct mm_struct *, unsigned long *); 29 + 30 + struct ptdesc *page_table_alloc_pgste_noprof(struct mm_struct *mm); 31 + #define page_table_alloc_pgste(...) alloc_hooks(page_table_alloc_pgste_noprof(__VA_ARGS__)) 28 32 void page_table_free_pgste(struct ptdesc *ptdesc); 29 33 30 34 static inline void crst_table_init(unsigned long *crst, unsigned long entry) ··· 52 48 return addr; 53 49 } 54 50 55 - static inline p4d_t *p4d_alloc_one(struct mm_struct *mm, unsigned long address) 51 + static inline p4d_t *p4d_alloc_one_noprof(struct mm_struct *mm, unsigned long address) 56 52 { 57 - unsigned long *table = crst_table_alloc(mm); 53 + unsigned long *table = crst_table_alloc_noprof(mm); 58 54 59 55 if (!table) 60 56 return NULL; ··· 63 59 64 60 return (p4d_t *) table; 65 61 } 62 + #define p4d_alloc_one(...) alloc_hooks(p4d_alloc_one_noprof(__VA_ARGS__)) 66 63 67 64 static inline void p4d_free(struct mm_struct *mm, p4d_t *p4d) 68 65 { ··· 74 69 crst_table_free(mm, (unsigned long *) p4d); 75 70 } 76 71 77 - static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long address) 72 + static inline pud_t *pud_alloc_one_noprof(struct mm_struct *mm, unsigned long address) 78 73 { 79 - unsigned long *table = crst_table_alloc(mm); 74 + unsigned long *table = crst_table_alloc_noprof(mm); 80 75 81 76 if (!table) 82 77 return NULL; ··· 85 80 86 81 return (pud_t *) table; 87 82 } 83 + #define pud_alloc_one(...) alloc_hooks(pud_alloc_one_noprof(__VA_ARGS__)) 88 84 89 85 static inline void pud_free(struct mm_struct *mm, pud_t *pud) 90 86 { ··· 96 90 crst_table_free(mm, (unsigned long *) pud); 97 91 } 98 92 99 - static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr) 93 + static inline pmd_t *pmd_alloc_one_noprof(struct mm_struct *mm, unsigned long vmaddr) 100 94 { 101 - unsigned long *table = crst_table_alloc(mm); 95 + unsigned long *table = crst_table_alloc_noprof(mm); 102 96 103 97 if (!table) 104 98 return NULL; ··· 109 103 } 110 104 return (pmd_t *) table; 111 105 } 106 + #define pmd_alloc_one(...) alloc_hooks(pmd_alloc_one_noprof(__VA_ARGS__)) 112 107 113 108 static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) 114 109 { ··· 134 127 set_pud(pud, __pud(_REGION3_ENTRY | __pa(pmd))); 135 128 } 136 129 137 - static inline pgd_t *pgd_alloc(struct mm_struct *mm) 130 + static inline pgd_t *pgd_alloc_noprof(struct mm_struct *mm) 138 131 { 139 - unsigned long *table = crst_table_alloc(mm); 132 + unsigned long *table = crst_table_alloc_noprof(mm); 140 133 141 134 if (!table) 142 135 return NULL; ··· 144 137 145 138 return (pgd_t *) table; 146 139 } 140 + #define pgd_alloc(...) alloc_hooks(pgd_alloc_noprof(__VA_ARGS__)) 147 141 148 142 static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) 149 143 {
+3 -9
arch/s390/kernel/debug.c
··· 1416 1416 { 1417 1417 char *buffer; 1418 1418 1419 - buffer = kmalloc(user_len + 1, GFP_KERNEL); 1420 - if (!buffer) 1421 - return ERR_PTR(-ENOMEM); 1422 - if (copy_from_user(buffer, user_buf, user_len) != 0) { 1423 - kfree(buffer); 1424 - return ERR_PTR(-EFAULT); 1425 - } 1419 + buffer = memdup_user_nul(user_buf, user_len); 1420 + if (IS_ERR(buffer)) 1421 + return buffer; 1426 1422 /* got the string, now strip linefeed. */ 1427 1423 if (buffer[user_len - 1] == '\n') 1428 1424 buffer[user_len - 1] = 0; 1429 - else 1430 - buffer[user_len] = 0; 1431 1425 return buffer; 1432 1426 } 1433 1427
+2 -2
arch/s390/kernel/diag/diag324.c
··· 116 116 mutex_lock(&pibmutex); 117 117 timedout = ktime_add_ns(data->expire, PIBWORK_DELAY); 118 118 if (ktime_before(ktime_get(), timedout)) { 119 - mod_delayed_work(system_wq, &pibwork, nsecs_to_jiffies(PIBWORK_DELAY)); 119 + mod_delayed_work(system_percpu_wq, &pibwork, nsecs_to_jiffies(PIBWORK_DELAY)); 120 120 goto out; 121 121 } 122 122 vfree(data->pib); ··· 174 174 pib_update(data); 175 175 data->sequence++; 176 176 data->expire = ktime_add_ns(ktime_get(), tod_to_ns(data->pib->intv)); 177 - mod_delayed_work(system_wq, &pibwork, nsecs_to_jiffies(PIBWORK_DELAY)); 177 + mod_delayed_work(system_percpu_wq, &pibwork, nsecs_to_jiffies(PIBWORK_DELAY)); 178 178 first = false; 179 179 } 180 180 rc = data->rc;
+1 -1
arch/s390/kernel/hiperdispatch.c
··· 191 191 return 0; 192 192 if (hd_online_cores <= hd_entitled_cores) 193 193 return 0; 194 - mod_delayed_work(system_wq, &hd_capacity_work, HD_DELAY_INTERVAL * hd_delay_factor); 194 + mod_delayed_work(system_dfl_wq, &hd_capacity_work, HD_DELAY_INTERVAL * hd_delay_factor); 195 195 hd_update_capacities(); 196 196 return 1; 197 197 }
+13 -6
arch/s390/mm/pgalloc.c
··· 14 14 #include <asm/pgalloc.h> 15 15 #include <asm/tlbflush.h> 16 16 17 - unsigned long *crst_table_alloc(struct mm_struct *mm) 17 + unsigned long *crst_table_alloc_noprof(struct mm_struct *mm) 18 18 { 19 - struct ptdesc *ptdesc = pagetable_alloc(GFP_KERNEL, CRST_ALLOC_ORDER); 19 + gfp_t gfp = GFP_KERNEL_ACCOUNT; 20 + struct ptdesc *ptdesc; 20 21 unsigned long *table; 21 22 23 + if (mm == &init_mm) 24 + gfp &= ~__GFP_ACCOUNT; 25 + ptdesc = pagetable_alloc_noprof(gfp, CRST_ALLOC_ORDER); 22 26 if (!ptdesc) 23 27 return NULL; 24 28 table = ptdesc_to_virt(ptdesc); ··· 116 112 117 113 #ifdef CONFIG_PGSTE 118 114 119 - struct ptdesc *page_table_alloc_pgste(struct mm_struct *mm) 115 + struct ptdesc *page_table_alloc_pgste_noprof(struct mm_struct *mm) 120 116 { 121 117 struct ptdesc *ptdesc; 122 118 u64 *table; 123 119 124 - ptdesc = pagetable_alloc(GFP_KERNEL, 0); 120 + ptdesc = pagetable_alloc_noprof(GFP_KERNEL_ACCOUNT, 0); 125 121 if (ptdesc) { 126 122 table = (u64 *)ptdesc_to_virt(ptdesc); 127 123 __arch_set_page_dat(table, 1); ··· 138 134 139 135 #endif /* CONFIG_PGSTE */ 140 136 141 - unsigned long *page_table_alloc(struct mm_struct *mm) 137 + unsigned long *page_table_alloc_noprof(struct mm_struct *mm) 142 138 { 139 + gfp_t gfp = GFP_KERNEL_ACCOUNT; 143 140 struct ptdesc *ptdesc; 144 141 unsigned long *table; 145 142 146 - ptdesc = pagetable_alloc(GFP_KERNEL, 0); 143 + if (mm == &init_mm) 144 + gfp &= ~__GFP_ACCOUNT; 145 + ptdesc = pagetable_alloc_noprof(gfp, 0); 147 146 if (!ptdesc) 148 147 return NULL; 149 148 if (!pagetable_pte_ctor(mm, ptdesc)) {
+2 -10
drivers/s390/block/Kconfig
··· 5 5 config DCSSBLK 6 6 def_tristate m 7 7 prompt "DCSSBLK support" 8 - depends on S390 && BLOCK && (DAX || DAX=n) 8 + depends on S390 && BLOCK && ZONE_DEVICE 9 + select FS_DAX 9 10 help 10 11 Support for dcss block device 11 - 12 - config DCSSBLK_DAX 13 - def_bool y 14 - depends on DCSSBLK 15 - # requires S390 ZONE_DEVICE support 16 - depends on BROKEN 17 - prompt "DCSSBLK DAX support" 18 - help 19 - Enable DAX operation for the dcss block device 20 12 21 13 config DASD 22 14 def_tristate y
+29 -6
drivers/s390/block/dcssblk.c
··· 79 79 int num_of_segments; 80 80 struct list_head seg_list; 81 81 struct dax_device *dax_dev; 82 + struct dev_pagemap pgmap; 83 + void *pgmap_addr; 82 84 }; 83 85 84 86 struct segment_info { ··· 417 415 dax_remove_host(dev_info->gd); 418 416 kill_dax(dev_info->dax_dev); 419 417 put_dax(dev_info->dax_dev); 418 + if (dev_info->pgmap_addr) 419 + devm_memunmap_pages(&dev_info->dev, &dev_info->pgmap); 420 420 del_gendisk(dev_info->gd); 421 421 put_disk(dev_info->gd); 422 422 ··· 541 537 { 542 538 struct dax_device *dax_dev; 543 539 544 - if (!IS_ENABLED(CONFIG_DCSSBLK_DAX)) 545 - return 0; 546 - 547 540 dax_dev = alloc_dax(dev_info, &dcssblk_dax_ops); 548 541 if (IS_ERR(dax_dev)) 549 542 return PTR_ERR(dax_dev); ··· 563 562 struct dcssblk_dev_info *dev_info; 564 563 struct segment_info *seg_info, *temp; 565 564 char *local_buf; 565 + void *addr; 566 566 unsigned long seg_byte_size; 567 567 568 568 dev_info = NULL; ··· 689 687 if (rc) 690 688 goto put_dev; 691 689 692 - rc = dcssblk_setup_dax(dev_info); 693 - if (rc) 694 - goto out_dax; 690 + if (!IS_ALIGNED(dev_info->start, SUBSECTION_SIZE) || 691 + !IS_ALIGNED(dev_info->end + 1, SUBSECTION_SIZE)) { 692 + pr_info("DCSS %s is not aligned to %lu bytes, DAX support disabled\n", 693 + local_buf, SUBSECTION_SIZE); 694 + } else { 695 + dev_info->pgmap.type = MEMORY_DEVICE_FS_DAX; 696 + dev_info->pgmap.range.start = dev_info->start; 697 + dev_info->pgmap.range.end = dev_info->end; 698 + dev_info->pgmap.nr_range = 1; 699 + addr = devm_memremap_pages(&dev_info->dev, &dev_info->pgmap); 700 + if (IS_ERR(addr)) { 701 + rc = PTR_ERR(addr); 702 + goto put_dev; 703 + } 704 + dev_info->pgmap_addr = addr; 705 + rc = dcssblk_setup_dax(dev_info); 706 + if (rc) 707 + goto out_dax; 708 + pr_info("DAX support enabled for DCSS %s\n", local_buf); 709 + } 695 710 696 711 get_device(&dev_info->dev); 697 712 rc = device_add_disk(&dev_info->dev, dev_info->gd, NULL); ··· 735 716 out_dax: 736 717 kill_dax(dev_info->dax_dev); 737 718 put_dax(dev_info->dax_dev); 719 + if (dev_info->pgmap_addr) 720 + devm_memunmap_pages(&dev_info->dev, &dev_info->pgmap); 738 721 put_dev: 739 722 list_del(&dev_info->lh); 740 723 put_disk(dev_info->gd); ··· 822 801 dax_remove_host(dev_info->gd); 823 802 kill_dax(dev_info->dax_dev); 824 803 put_dax(dev_info->dax_dev); 804 + if (dev_info->pgmap_addr) 805 + devm_memunmap_pages(&dev_info->dev, &dev_info->pgmap); 825 806 del_gendisk(dev_info->gd); 826 807 put_disk(dev_info->gd); 827 808
+1
drivers/s390/char/Makefile
··· 21 21 sclp_cmd.o sclp_config.o sclp_cpi_sys.o sclp_ocf.o sclp_ctl.o \ 22 22 sclp_early.o sclp_early_core.o sclp_sd.o 23 23 24 + obj-$(CONFIG_MEMORY_HOTPLUG) += sclp_mem.o 24 25 obj-$(CONFIG_TN3270) += raw3270.o con3270.o 25 26 obj-$(CONFIG_TN3270_FS) += fs3270.o 26 27
+6 -13
drivers/s390/char/hmcdrv_dev.c
··· 244 244 size_t len, loff_t *pos) 245 245 { 246 246 ssize_t retlen; 247 + void *pdata; 247 248 248 249 pr_debug("writing file '/dev/%pD' at pos. %lld with length %zd\n", 249 250 fp, (long long) *pos, len); 250 251 251 252 if (!fp->private_data) { /* first expect a cmd write */ 252 - fp->private_data = kmalloc(len + 1, GFP_KERNEL); 253 - 254 - if (!fp->private_data) 255 - return -ENOMEM; 256 - 257 - if (!copy_from_user(fp->private_data, ubuf, len)) { 258 - ((char *)fp->private_data)[len] = '\0'; 259 - return len; 260 - } 261 - 262 - kfree(fp->private_data); 263 - fp->private_data = NULL; 264 - return -EFAULT; 253 + pdata = memdup_user_nul(ubuf, len); 254 + if (IS_ERR(pdata)) 255 + return PTR_ERR(pdata); 256 + fp->private_data = pdata; 257 + return len; 265 258 } 266 259 267 260 retlen = hmcdrv_dev_transfer((char *) fp->private_data,
+40 -438
drivers/s390/char/sclp_cmd.c
··· 8 8 #define KMSG_COMPONENT "sclp_cmd" 9 9 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 10 10 11 - #include <linux/cpufeature.h> 12 11 #include <linux/completion.h> 13 - #include <linux/init.h> 14 - #include <linux/errno.h> 15 12 #include <linux/err.h> 13 + #include <linux/errno.h> 14 + #include <linux/init.h> 16 15 #include <linux/slab.h> 17 16 #include <linux/string.h> 18 - #include <linux/mm.h> 19 - #include <linux/mmzone.h> 20 - #include <linux/memory.h> 21 - #include <linux/memory_hotplug.h> 22 - #include <linux/module.h> 23 - #include <asm/ctlreg.h> 24 17 #include <asm/chpid.h> 25 - #include <asm/setup.h> 26 - #include <asm/page.h> 18 + #include <asm/ctlreg.h> 27 19 #include <asm/sclp.h> 28 - #include <asm/numa.h> 29 - #include <asm/facility.h> 30 - #include <asm/page-states.h> 31 20 32 21 #include "sclp.h" 33 22 34 - #define SCLP_CMDW_ASSIGN_STORAGE 0x000d0001 35 - #define SCLP_CMDW_UNASSIGN_STORAGE 0x000c0001 23 + /* CPU configuration related functions */ 24 + #define SCLP_CMDW_CONFIGURE_CPU 0x00110001 25 + #define SCLP_CMDW_DECONFIGURE_CPU 0x00100001 26 + /* Channel path configuration related functions */ 27 + #define SCLP_CMDW_CONFIGURE_CHPATH 0x000f0001 28 + #define SCLP_CMDW_DECONFIGURE_CHPATH 0x000e0001 29 + #define SCLP_CMDW_READ_CHPATH_INFORMATION 0x00030001 30 + 31 + struct cpu_configure_sccb { 32 + struct sccb_header header; 33 + } __packed __aligned(8); 34 + 35 + struct chp_cfg_sccb { 36 + struct sccb_header header; 37 + u8 ccm; 38 + u8 reserved[6]; 39 + u8 cssid; 40 + } __packed; 41 + 42 + struct chp_info_sccb { 43 + struct sccb_header header; 44 + u8 recognized[SCLP_CHP_INFO_MASK_SIZE]; 45 + u8 standby[SCLP_CHP_INFO_MASK_SIZE]; 46 + u8 configured[SCLP_CHP_INFO_MASK_SIZE]; 47 + u8 ccm; 48 + u8 reserved[6]; 49 + u8 cssid; 50 + } __packed; 36 51 37 52 static void sclp_sync_callback(struct sclp_req *req, void *data) 38 53 { ··· 79 64 request->callback_data = &completion; 80 65 init_completion(&completion); 81 66 82 - /* Perform sclp request. */ 83 67 rc = sclp_add_request(request); 84 68 if (rc) 85 69 goto out; 86 70 wait_for_completion(&completion); 87 71 88 - /* Check response. */ 89 72 if (request->status != SCLP_REQ_DONE) { 90 73 pr_warn("sync request failed (cmd=0x%08x, status=0x%02x)\n", 91 74 cmd, request->status); ··· 94 81 return rc; 95 82 } 96 83 97 - /* 98 - * CPU configuration related functions. 99 - */ 100 - 101 - #define SCLP_CMDW_CONFIGURE_CPU 0x00110001 102 - #define SCLP_CMDW_DECONFIGURE_CPU 0x00100001 103 - 104 84 int _sclp_get_core_info(struct sclp_core_info *info) 105 85 { 106 - int rc; 107 - int length = test_facility(140) ? EXT_SCCB_READ_CPU : PAGE_SIZE; 108 86 struct read_cpu_info_sccb *sccb; 87 + int rc, length; 109 88 110 89 if (!SCLP_HAS_CPU_INFO) 111 90 return -EOPNOTSUPP; 112 91 92 + length = test_facility(140) ? EXT_SCCB_READ_CPU : PAGE_SIZE; 113 93 sccb = (void *)__get_free_pages(GFP_KERNEL | GFP_DMA | __GFP_ZERO, get_order(length)); 114 94 if (!sccb) 115 95 return -ENOMEM; ··· 120 114 } 121 115 sclp_fill_core_info(info, sccb); 122 116 out: 123 - free_pages((unsigned long) sccb, get_order(length)); 117 + free_pages((unsigned long)sccb, get_order(length)); 124 118 return rc; 125 119 } 126 - 127 - struct cpu_configure_sccb { 128 - struct sccb_header header; 129 - } __attribute__((packed, aligned(8))); 130 120 131 121 static int do_core_configure(sclp_cmdw_t cmd) 132 122 { ··· 132 130 if (!SCLP_HAS_CPU_RECONFIG) 133 131 return -EOPNOTSUPP; 134 132 /* 135 - * This is not going to cross a page boundary since we force 136 - * kmalloc to have a minimum alignment of 8 bytes on s390. 133 + * Use kmalloc to have a minimum alignment of 8 bytes and ensure sccb 134 + * is not going to cross a page boundary. 137 135 */ 138 136 sccb = kzalloc(sizeof(*sccb), GFP_KERNEL | GFP_DMA); 139 137 if (!sccb) ··· 167 165 return do_core_configure(SCLP_CMDW_DECONFIGURE_CPU | core << 8); 168 166 } 169 167 170 - #ifdef CONFIG_MEMORY_HOTPLUG 171 - 172 - static DEFINE_MUTEX(sclp_mem_mutex); 173 - static LIST_HEAD(sclp_mem_list); 174 - static u8 sclp_max_storage_id; 175 - static DECLARE_BITMAP(sclp_storage_ids, 256); 176 - 177 - struct memory_increment { 178 - struct list_head list; 179 - u16 rn; 180 - int standby; 181 - }; 182 - 183 - struct assign_storage_sccb { 184 - struct sccb_header header; 185 - u16 rn; 186 - } __packed; 187 - 188 - int arch_get_memory_phys_device(unsigned long start_pfn) 189 - { 190 - if (!sclp.rzm) 191 - return 0; 192 - return PFN_PHYS(start_pfn) >> ilog2(sclp.rzm); 193 - } 194 - 195 - static unsigned long long rn2addr(u16 rn) 196 - { 197 - return (unsigned long long) (rn - 1) * sclp.rzm; 198 - } 199 - 200 - static int do_assign_storage(sclp_cmdw_t cmd, u16 rn) 201 - { 202 - struct assign_storage_sccb *sccb; 203 - int rc; 204 - 205 - sccb = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA); 206 - if (!sccb) 207 - return -ENOMEM; 208 - sccb->header.length = PAGE_SIZE; 209 - sccb->rn = rn; 210 - rc = sclp_sync_request_timeout(cmd, sccb, SCLP_QUEUE_INTERVAL); 211 - if (rc) 212 - goto out; 213 - switch (sccb->header.response_code) { 214 - case 0x0020: 215 - case 0x0120: 216 - break; 217 - default: 218 - pr_warn("assign storage failed (cmd=0x%08x, response=0x%04x, rn=0x%04x)\n", 219 - cmd, sccb->header.response_code, rn); 220 - rc = -EIO; 221 - break; 222 - } 223 - out: 224 - free_page((unsigned long) sccb); 225 - return rc; 226 - } 227 - 228 - static int sclp_assign_storage(u16 rn) 229 - { 230 - unsigned long long start; 231 - int rc; 232 - 233 - rc = do_assign_storage(SCLP_CMDW_ASSIGN_STORAGE, rn); 234 - if (rc) 235 - return rc; 236 - start = rn2addr(rn); 237 - storage_key_init_range(start, start + sclp.rzm); 238 - return 0; 239 - } 240 - 241 - static int sclp_unassign_storage(u16 rn) 242 - { 243 - return do_assign_storage(SCLP_CMDW_UNASSIGN_STORAGE, rn); 244 - } 245 - 246 - struct attach_storage_sccb { 247 - struct sccb_header header; 248 - u16 :16; 249 - u16 assigned; 250 - u32 :32; 251 - u32 entries[]; 252 - } __packed; 253 - 254 - static int sclp_attach_storage(u8 id) 255 - { 256 - struct attach_storage_sccb *sccb; 257 - int rc; 258 - int i; 259 - 260 - sccb = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA); 261 - if (!sccb) 262 - return -ENOMEM; 263 - sccb->header.length = PAGE_SIZE; 264 - sccb->header.function_code = 0x40; 265 - rc = sclp_sync_request_timeout(0x00080001 | id << 8, sccb, 266 - SCLP_QUEUE_INTERVAL); 267 - if (rc) 268 - goto out; 269 - switch (sccb->header.response_code) { 270 - case 0x0020: 271 - set_bit(id, sclp_storage_ids); 272 - for (i = 0; i < sccb->assigned; i++) { 273 - if (sccb->entries[i]) 274 - sclp_unassign_storage(sccb->entries[i] >> 16); 275 - } 276 - break; 277 - default: 278 - rc = -EIO; 279 - break; 280 - } 281 - out: 282 - free_page((unsigned long) sccb); 283 - return rc; 284 - } 285 - 286 - static int sclp_mem_change_state(unsigned long start, unsigned long size, 287 - int online) 288 - { 289 - struct memory_increment *incr; 290 - unsigned long long istart; 291 - int rc = 0; 292 - 293 - list_for_each_entry(incr, &sclp_mem_list, list) { 294 - istart = rn2addr(incr->rn); 295 - if (start + size - 1 < istart) 296 - break; 297 - if (start > istart + sclp.rzm - 1) 298 - continue; 299 - if (online) 300 - rc |= sclp_assign_storage(incr->rn); 301 - else 302 - sclp_unassign_storage(incr->rn); 303 - if (rc == 0) 304 - incr->standby = online ? 0 : 1; 305 - } 306 - return rc ? -EIO : 0; 307 - } 308 - 309 - static bool contains_standby_increment(unsigned long start, unsigned long end) 310 - { 311 - struct memory_increment *incr; 312 - unsigned long istart; 313 - 314 - list_for_each_entry(incr, &sclp_mem_list, list) { 315 - istart = rn2addr(incr->rn); 316 - if (end - 1 < istart) 317 - continue; 318 - if (start > istart + sclp.rzm - 1) 319 - continue; 320 - if (incr->standby) 321 - return true; 322 - } 323 - return false; 324 - } 325 - 326 - static int sclp_mem_notifier(struct notifier_block *nb, 327 - unsigned long action, void *data) 328 - { 329 - unsigned long start, size; 330 - struct memory_notify *arg; 331 - unsigned char id; 332 - int rc = 0; 333 - 334 - arg = data; 335 - start = arg->start_pfn << PAGE_SHIFT; 336 - size = arg->nr_pages << PAGE_SHIFT; 337 - mutex_lock(&sclp_mem_mutex); 338 - for_each_clear_bit(id, sclp_storage_ids, sclp_max_storage_id + 1) 339 - sclp_attach_storage(id); 340 - switch (action) { 341 - case MEM_GOING_OFFLINE: 342 - /* 343 - * We do not allow to set memory blocks offline that contain 344 - * standby memory. This is done to simplify the "memory online" 345 - * case. 346 - */ 347 - if (contains_standby_increment(start, start + size)) 348 - rc = -EPERM; 349 - break; 350 - case MEM_PREPARE_ONLINE: 351 - /* 352 - * Access the altmap_start_pfn and altmap_nr_pages fields 353 - * within the struct memory_notify specifically when dealing 354 - * with only MEM_PREPARE_ONLINE/MEM_FINISH_OFFLINE notifiers. 355 - * 356 - * When altmap is in use, take the specified memory range 357 - * online, which includes the altmap. 358 - */ 359 - if (arg->altmap_nr_pages) { 360 - start = PFN_PHYS(arg->altmap_start_pfn); 361 - size += PFN_PHYS(arg->altmap_nr_pages); 362 - } 363 - rc = sclp_mem_change_state(start, size, 1); 364 - if (rc || !arg->altmap_nr_pages) 365 - break; 366 - /* 367 - * Set CMMA state to nodat here, since the struct page memory 368 - * at the beginning of the memory block will not go through the 369 - * buddy allocator later. 370 - */ 371 - __arch_set_page_nodat((void *)__va(start), arg->altmap_nr_pages); 372 - break; 373 - case MEM_FINISH_OFFLINE: 374 - /* 375 - * When altmap is in use, take the specified memory range 376 - * offline, which includes the altmap. 377 - */ 378 - if (arg->altmap_nr_pages) { 379 - start = PFN_PHYS(arg->altmap_start_pfn); 380 - size += PFN_PHYS(arg->altmap_nr_pages); 381 - } 382 - sclp_mem_change_state(start, size, 0); 383 - break; 384 - default: 385 - break; 386 - } 387 - mutex_unlock(&sclp_mem_mutex); 388 - return rc ? NOTIFY_BAD : NOTIFY_OK; 389 - } 390 - 391 - static struct notifier_block sclp_mem_nb = { 392 - .notifier_call = sclp_mem_notifier, 393 - }; 394 - 395 - static void __init align_to_block_size(unsigned long long *start, 396 - unsigned long long *size, 397 - unsigned long long alignment) 398 - { 399 - unsigned long long start_align, size_align; 400 - 401 - start_align = roundup(*start, alignment); 402 - size_align = rounddown(*start + *size, alignment) - start_align; 403 - 404 - pr_info("Standby memory at 0x%llx (%lluM of %lluM usable)\n", 405 - *start, size_align >> 20, *size >> 20); 406 - *start = start_align; 407 - *size = size_align; 408 - } 409 - 410 - static void __init add_memory_merged(u16 rn) 411 - { 412 - unsigned long long start, size, addr, block_size; 413 - static u16 first_rn, num; 414 - 415 - if (rn && first_rn && (first_rn + num == rn)) { 416 - num++; 417 - return; 418 - } 419 - if (!first_rn) 420 - goto skip_add; 421 - start = rn2addr(first_rn); 422 - size = (unsigned long long) num * sclp.rzm; 423 - if (start >= ident_map_size) 424 - goto skip_add; 425 - if (start + size > ident_map_size) 426 - size = ident_map_size - start; 427 - block_size = memory_block_size_bytes(); 428 - align_to_block_size(&start, &size, block_size); 429 - if (!size) 430 - goto skip_add; 431 - for (addr = start; addr < start + size; addr += block_size) 432 - add_memory(0, addr, block_size, 433 - cpu_has_edat1() ? 434 - MHP_MEMMAP_ON_MEMORY | MHP_OFFLINE_INACCESSIBLE : MHP_NONE); 435 - skip_add: 436 - first_rn = rn; 437 - num = 1; 438 - } 439 - 440 - static void __init sclp_add_standby_memory(void) 441 - { 442 - struct memory_increment *incr; 443 - 444 - list_for_each_entry(incr, &sclp_mem_list, list) 445 - if (incr->standby) 446 - add_memory_merged(incr->rn); 447 - add_memory_merged(0); 448 - } 449 - 450 - static void __init insert_increment(u16 rn, int standby, int assigned) 451 - { 452 - struct memory_increment *incr, *new_incr; 453 - struct list_head *prev; 454 - u16 last_rn; 455 - 456 - new_incr = kzalloc(sizeof(*new_incr), GFP_KERNEL); 457 - if (!new_incr) 458 - return; 459 - new_incr->rn = rn; 460 - new_incr->standby = standby; 461 - last_rn = 0; 462 - prev = &sclp_mem_list; 463 - list_for_each_entry(incr, &sclp_mem_list, list) { 464 - if (assigned && incr->rn > rn) 465 - break; 466 - if (!assigned && incr->rn - last_rn > 1) 467 - break; 468 - last_rn = incr->rn; 469 - prev = &incr->list; 470 - } 471 - if (!assigned) 472 - new_incr->rn = last_rn + 1; 473 - if (new_incr->rn > sclp.rnmax) { 474 - kfree(new_incr); 475 - return; 476 - } 477 - list_add(&new_incr->list, prev); 478 - } 479 - 480 - static int __init sclp_detect_standby_memory(void) 481 - { 482 - struct read_storage_sccb *sccb; 483 - int i, id, assigned, rc; 484 - 485 - if (oldmem_data.start) /* No standby memory in kdump mode */ 486 - return 0; 487 - if ((sclp.facilities & 0xe00000000000ULL) != 0xe00000000000ULL) 488 - return 0; 489 - rc = -ENOMEM; 490 - sccb = (void *) __get_free_page(GFP_KERNEL | GFP_DMA); 491 - if (!sccb) 492 - goto out; 493 - assigned = 0; 494 - for (id = 0; id <= sclp_max_storage_id; id++) { 495 - memset(sccb, 0, PAGE_SIZE); 496 - sccb->header.length = PAGE_SIZE; 497 - rc = sclp_sync_request(SCLP_CMDW_READ_STORAGE_INFO | id << 8, sccb); 498 - if (rc) 499 - goto out; 500 - switch (sccb->header.response_code) { 501 - case 0x0010: 502 - set_bit(id, sclp_storage_ids); 503 - for (i = 0; i < sccb->assigned; i++) { 504 - if (!sccb->entries[i]) 505 - continue; 506 - assigned++; 507 - insert_increment(sccb->entries[i] >> 16, 0, 1); 508 - } 509 - break; 510 - case 0x0310: 511 - break; 512 - case 0x0410: 513 - for (i = 0; i < sccb->assigned; i++) { 514 - if (!sccb->entries[i]) 515 - continue; 516 - assigned++; 517 - insert_increment(sccb->entries[i] >> 16, 1, 1); 518 - } 519 - break; 520 - default: 521 - rc = -EIO; 522 - break; 523 - } 524 - if (!rc) 525 - sclp_max_storage_id = sccb->max_id; 526 - } 527 - if (rc || list_empty(&sclp_mem_list)) 528 - goto out; 529 - for (i = 1; i <= sclp.rnmax - assigned; i++) 530 - insert_increment(0, 1, 0); 531 - rc = register_memory_notifier(&sclp_mem_nb); 532 - if (rc) 533 - goto out; 534 - sclp_add_standby_memory(); 535 - out: 536 - free_page((unsigned long) sccb); 537 - return rc; 538 - } 539 - __initcall(sclp_detect_standby_memory); 540 - 541 - #endif /* CONFIG_MEMORY_HOTPLUG */ 542 - 543 - /* 544 - * Channel path configuration related functions. 545 - */ 546 - 547 - #define SCLP_CMDW_CONFIGURE_CHPATH 0x000f0001 548 - #define SCLP_CMDW_DECONFIGURE_CHPATH 0x000e0001 549 - #define SCLP_CMDW_READ_CHPATH_INFORMATION 0x00030001 550 - 551 - struct chp_cfg_sccb { 552 - struct sccb_header header; 553 - u8 ccm; 554 - u8 reserved[6]; 555 - u8 cssid; 556 - } __attribute__((packed)); 557 - 558 168 static int do_chp_configure(sclp_cmdw_t cmd) 559 169 { 560 170 struct chp_cfg_sccb *sccb; ··· 174 560 175 561 if (!SCLP_HAS_CHP_RECONFIG) 176 562 return -EOPNOTSUPP; 177 - /* Prepare sccb. */ 178 - sccb = (struct chp_cfg_sccb *) get_zeroed_page(GFP_KERNEL | GFP_DMA); 563 + sccb = (struct chp_cfg_sccb *)get_zeroed_page(GFP_KERNEL | GFP_DMA); 179 564 if (!sccb) 180 565 return -ENOMEM; 181 566 sccb->header.length = sizeof(*sccb); ··· 194 581 break; 195 582 } 196 583 out: 197 - free_page((unsigned long) sccb); 584 + free_page((unsigned long)sccb); 198 585 return rc; 199 586 } 200 587 ··· 222 609 return do_chp_configure(SCLP_CMDW_DECONFIGURE_CHPATH | chpid.id << 8); 223 610 } 224 611 225 - struct chp_info_sccb { 226 - struct sccb_header header; 227 - u8 recognized[SCLP_CHP_INFO_MASK_SIZE]; 228 - u8 standby[SCLP_CHP_INFO_MASK_SIZE]; 229 - u8 configured[SCLP_CHP_INFO_MASK_SIZE]; 230 - u8 ccm; 231 - u8 reserved[6]; 232 - u8 cssid; 233 - } __attribute__((packed)); 234 - 235 612 /** 236 613 * sclp_chp_read_info - perform read channel-path information sclp command 237 614 * @info: resulting channel-path information data ··· 237 634 238 635 if (!SCLP_HAS_CHP_INFO) 239 636 return -EOPNOTSUPP; 240 - /* Prepare sccb. */ 241 - sccb = (struct chp_info_sccb *) get_zeroed_page(GFP_KERNEL | GFP_DMA); 637 + sccb = (struct chp_info_sccb *)get_zeroed_page(GFP_KERNEL | GFP_DMA); 242 638 if (!sccb) 243 639 return -ENOMEM; 244 640 sccb->header.length = sizeof(*sccb); ··· 254 652 memcpy(info->standby, sccb->standby, SCLP_CHP_INFO_MASK_SIZE); 255 653 memcpy(info->configured, sccb->configured, SCLP_CHP_INFO_MASK_SIZE); 256 654 out: 257 - free_page((unsigned long) sccb); 655 + free_page((unsigned long)sccb); 258 656 return rc; 259 657 }
+399
drivers/s390/char/sclp_mem.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Memory hotplug support via sclp 4 + * 5 + * Copyright IBM Corp. 2025 6 + */ 7 + 8 + #define KMSG_COMPONENT "sclp_mem" 9 + #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 10 + 11 + #include <linux/cpufeature.h> 12 + #include <linux/err.h> 13 + #include <linux/errno.h> 14 + #include <linux/init.h> 15 + #include <linux/memory.h> 16 + #include <linux/memory_hotplug.h> 17 + #include <linux/mm.h> 18 + #include <linux/mmzone.h> 19 + #include <linux/slab.h> 20 + #include <asm/facility.h> 21 + #include <asm/page.h> 22 + #include <asm/page-states.h> 23 + #include <asm/sclp.h> 24 + 25 + #include "sclp.h" 26 + 27 + #define SCLP_CMDW_ASSIGN_STORAGE 0x000d0001 28 + #define SCLP_CMDW_UNASSIGN_STORAGE 0x000c0001 29 + 30 + static DEFINE_MUTEX(sclp_mem_mutex); 31 + static LIST_HEAD(sclp_mem_list); 32 + static u8 sclp_max_storage_id; 33 + static DECLARE_BITMAP(sclp_storage_ids, 256); 34 + 35 + struct memory_increment { 36 + struct list_head list; 37 + u16 rn; 38 + int standby; 39 + }; 40 + 41 + struct assign_storage_sccb { 42 + struct sccb_header header; 43 + u16 rn; 44 + } __packed; 45 + 46 + struct attach_storage_sccb { 47 + struct sccb_header header; 48 + u16 :16; 49 + u16 assigned; 50 + u32 :32; 51 + u32 entries[]; 52 + } __packed; 53 + 54 + int arch_get_memory_phys_device(unsigned long start_pfn) 55 + { 56 + if (!sclp.rzm) 57 + return 0; 58 + return PFN_PHYS(start_pfn) >> ilog2(sclp.rzm); 59 + } 60 + 61 + static unsigned long rn2addr(u16 rn) 62 + { 63 + return (unsigned long)(rn - 1) * sclp.rzm; 64 + } 65 + 66 + static int do_assign_storage(sclp_cmdw_t cmd, u16 rn) 67 + { 68 + struct assign_storage_sccb *sccb; 69 + int rc; 70 + 71 + sccb = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); 72 + if (!sccb) 73 + return -ENOMEM; 74 + sccb->header.length = PAGE_SIZE; 75 + sccb->rn = rn; 76 + rc = sclp_sync_request_timeout(cmd, sccb, SCLP_QUEUE_INTERVAL); 77 + if (rc) 78 + goto out; 79 + switch (sccb->header.response_code) { 80 + case 0x0020: 81 + case 0x0120: 82 + break; 83 + default: 84 + pr_warn("assign storage failed (cmd=0x%08x, response=0x%04x, rn=0x%04x)\n", 85 + cmd, sccb->header.response_code, rn); 86 + rc = -EIO; 87 + break; 88 + } 89 + out: 90 + free_page((unsigned long)sccb); 91 + return rc; 92 + } 93 + 94 + static int sclp_assign_storage(u16 rn) 95 + { 96 + unsigned long start; 97 + int rc; 98 + 99 + rc = do_assign_storage(SCLP_CMDW_ASSIGN_STORAGE, rn); 100 + if (rc) 101 + return rc; 102 + start = rn2addr(rn); 103 + storage_key_init_range(start, start + sclp.rzm); 104 + return 0; 105 + } 106 + 107 + static int sclp_unassign_storage(u16 rn) 108 + { 109 + return do_assign_storage(SCLP_CMDW_UNASSIGN_STORAGE, rn); 110 + } 111 + 112 + static int sclp_attach_storage(u8 id) 113 + { 114 + struct attach_storage_sccb *sccb; 115 + int rc, i; 116 + 117 + sccb = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); 118 + if (!sccb) 119 + return -ENOMEM; 120 + sccb->header.length = PAGE_SIZE; 121 + sccb->header.function_code = 0x40; 122 + rc = sclp_sync_request_timeout(0x00080001 | id << 8, sccb, 123 + SCLP_QUEUE_INTERVAL); 124 + if (rc) 125 + goto out; 126 + switch (sccb->header.response_code) { 127 + case 0x0020: 128 + set_bit(id, sclp_storage_ids); 129 + for (i = 0; i < sccb->assigned; i++) { 130 + if (sccb->entries[i]) 131 + sclp_unassign_storage(sccb->entries[i] >> 16); 132 + } 133 + break; 134 + default: 135 + rc = -EIO; 136 + break; 137 + } 138 + out: 139 + free_page((unsigned long)sccb); 140 + return rc; 141 + } 142 + 143 + static int sclp_mem_change_state(unsigned long start, unsigned long size, 144 + int online) 145 + { 146 + struct memory_increment *incr; 147 + unsigned long istart; 148 + int rc = 0; 149 + 150 + list_for_each_entry(incr, &sclp_mem_list, list) { 151 + istart = rn2addr(incr->rn); 152 + if (start + size - 1 < istart) 153 + break; 154 + if (start > istart + sclp.rzm - 1) 155 + continue; 156 + if (online) 157 + rc |= sclp_assign_storage(incr->rn); 158 + else 159 + sclp_unassign_storage(incr->rn); 160 + if (rc == 0) 161 + incr->standby = online ? 0 : 1; 162 + } 163 + return rc ? -EIO : 0; 164 + } 165 + 166 + static bool contains_standby_increment(unsigned long start, unsigned long end) 167 + { 168 + struct memory_increment *incr; 169 + unsigned long istart; 170 + 171 + list_for_each_entry(incr, &sclp_mem_list, list) { 172 + istart = rn2addr(incr->rn); 173 + if (end - 1 < istart) 174 + continue; 175 + if (start > istart + sclp.rzm - 1) 176 + continue; 177 + if (incr->standby) 178 + return true; 179 + } 180 + return false; 181 + } 182 + 183 + static int sclp_mem_notifier(struct notifier_block *nb, 184 + unsigned long action, void *data) 185 + { 186 + unsigned long start, size; 187 + struct memory_notify *arg; 188 + unsigned char id; 189 + int rc = 0; 190 + 191 + arg = data; 192 + start = arg->start_pfn << PAGE_SHIFT; 193 + size = arg->nr_pages << PAGE_SHIFT; 194 + mutex_lock(&sclp_mem_mutex); 195 + for_each_clear_bit(id, sclp_storage_ids, sclp_max_storage_id + 1) 196 + sclp_attach_storage(id); 197 + switch (action) { 198 + case MEM_GOING_OFFLINE: 199 + /* 200 + * Do not allow to set memory blocks offline that contain 201 + * standby memory. This is done to simplify the "memory online" 202 + * case. 203 + */ 204 + if (contains_standby_increment(start, start + size)) 205 + rc = -EPERM; 206 + break; 207 + case MEM_PREPARE_ONLINE: 208 + /* 209 + * Access the altmap_start_pfn and altmap_nr_pages fields 210 + * within the struct memory_notify specifically when dealing 211 + * with only MEM_PREPARE_ONLINE/MEM_FINISH_OFFLINE notifiers. 212 + * 213 + * When altmap is in use, take the specified memory range 214 + * online, which includes the altmap. 215 + */ 216 + if (arg->altmap_nr_pages) { 217 + start = PFN_PHYS(arg->altmap_start_pfn); 218 + size += PFN_PHYS(arg->altmap_nr_pages); 219 + } 220 + rc = sclp_mem_change_state(start, size, 1); 221 + if (rc || !arg->altmap_nr_pages) 222 + break; 223 + /* 224 + * Set CMMA state to nodat here, since the struct page memory 225 + * at the beginning of the memory block will not go through the 226 + * buddy allocator later. 227 + */ 228 + __arch_set_page_nodat((void *)__va(start), arg->altmap_nr_pages); 229 + break; 230 + case MEM_FINISH_OFFLINE: 231 + /* 232 + * When altmap is in use, take the specified memory range 233 + * offline, which includes the altmap. 234 + */ 235 + if (arg->altmap_nr_pages) { 236 + start = PFN_PHYS(arg->altmap_start_pfn); 237 + size += PFN_PHYS(arg->altmap_nr_pages); 238 + } 239 + sclp_mem_change_state(start, size, 0); 240 + break; 241 + default: 242 + break; 243 + } 244 + mutex_unlock(&sclp_mem_mutex); 245 + return rc ? NOTIFY_BAD : NOTIFY_OK; 246 + } 247 + 248 + static struct notifier_block sclp_mem_nb = { 249 + .notifier_call = sclp_mem_notifier, 250 + }; 251 + 252 + static void __init align_to_block_size(unsigned long *start, 253 + unsigned long *size, 254 + unsigned long alignment) 255 + { 256 + unsigned long start_align, size_align; 257 + 258 + start_align = roundup(*start, alignment); 259 + size_align = rounddown(*start + *size, alignment) - start_align; 260 + 261 + pr_info("Standby memory at 0x%lx (%luM of %luM usable)\n", 262 + *start, size_align >> 20, *size >> 20); 263 + *start = start_align; 264 + *size = size_align; 265 + } 266 + 267 + static void __init add_memory_merged(u16 rn) 268 + { 269 + unsigned long start, size, addr, block_size; 270 + static u16 first_rn, num; 271 + 272 + if (rn && first_rn && (first_rn + num == rn)) { 273 + num++; 274 + return; 275 + } 276 + if (!first_rn) 277 + goto skip_add; 278 + start = rn2addr(first_rn); 279 + size = (unsigned long)num * sclp.rzm; 280 + if (start >= ident_map_size) 281 + goto skip_add; 282 + if (start + size > ident_map_size) 283 + size = ident_map_size - start; 284 + block_size = memory_block_size_bytes(); 285 + align_to_block_size(&start, &size, block_size); 286 + if (!size) 287 + goto skip_add; 288 + for (addr = start; addr < start + size; addr += block_size) { 289 + add_memory(0, addr, block_size, 290 + cpu_has_edat1() ? 291 + MHP_MEMMAP_ON_MEMORY | MHP_OFFLINE_INACCESSIBLE : MHP_NONE); 292 + } 293 + skip_add: 294 + first_rn = rn; 295 + num = 1; 296 + } 297 + 298 + static void __init sclp_add_standby_memory(void) 299 + { 300 + struct memory_increment *incr; 301 + 302 + list_for_each_entry(incr, &sclp_mem_list, list) { 303 + if (incr->standby) 304 + add_memory_merged(incr->rn); 305 + } 306 + add_memory_merged(0); 307 + } 308 + 309 + static void __init insert_increment(u16 rn, int standby, int assigned) 310 + { 311 + struct memory_increment *incr, *new_incr; 312 + struct list_head *prev; 313 + u16 last_rn; 314 + 315 + new_incr = kzalloc(sizeof(*new_incr), GFP_KERNEL); 316 + if (!new_incr) 317 + return; 318 + new_incr->rn = rn; 319 + new_incr->standby = standby; 320 + last_rn = 0; 321 + prev = &sclp_mem_list; 322 + list_for_each_entry(incr, &sclp_mem_list, list) { 323 + if (assigned && incr->rn > rn) 324 + break; 325 + if (!assigned && incr->rn - last_rn > 1) 326 + break; 327 + last_rn = incr->rn; 328 + prev = &incr->list; 329 + } 330 + if (!assigned) 331 + new_incr->rn = last_rn + 1; 332 + if (new_incr->rn > sclp.rnmax) { 333 + kfree(new_incr); 334 + return; 335 + } 336 + list_add(&new_incr->list, prev); 337 + } 338 + 339 + static int __init sclp_detect_standby_memory(void) 340 + { 341 + struct read_storage_sccb *sccb; 342 + int i, id, assigned, rc; 343 + 344 + /* No standby memory in kdump mode */ 345 + if (oldmem_data.start) 346 + return 0; 347 + if ((sclp.facilities & 0xe00000000000UL) != 0xe00000000000UL) 348 + return 0; 349 + rc = -ENOMEM; 350 + sccb = (void *)__get_free_page(GFP_KERNEL | GFP_DMA); 351 + if (!sccb) 352 + goto out; 353 + assigned = 0; 354 + for (id = 0; id <= sclp_max_storage_id; id++) { 355 + memset(sccb, 0, PAGE_SIZE); 356 + sccb->header.length = PAGE_SIZE; 357 + rc = sclp_sync_request(SCLP_CMDW_READ_STORAGE_INFO | id << 8, sccb); 358 + if (rc) 359 + goto out; 360 + switch (sccb->header.response_code) { 361 + case 0x0010: 362 + set_bit(id, sclp_storage_ids); 363 + for (i = 0; i < sccb->assigned; i++) { 364 + if (!sccb->entries[i]) 365 + continue; 366 + assigned++; 367 + insert_increment(sccb->entries[i] >> 16, 0, 1); 368 + } 369 + break; 370 + case 0x0310: 371 + break; 372 + case 0x0410: 373 + for (i = 0; i < sccb->assigned; i++) { 374 + if (!sccb->entries[i]) 375 + continue; 376 + assigned++; 377 + insert_increment(sccb->entries[i] >> 16, 1, 1); 378 + } 379 + break; 380 + default: 381 + rc = -EIO; 382 + break; 383 + } 384 + if (!rc) 385 + sclp_max_storage_id = sccb->max_id; 386 + } 387 + if (rc || list_empty(&sclp_mem_list)) 388 + goto out; 389 + for (i = 1; i <= sclp.rnmax - assigned; i++) 390 + insert_increment(0, 1, 0); 391 + rc = register_memory_notifier(&sclp_mem_nb); 392 + if (rc) 393 + goto out; 394 + sclp_add_standby_memory(); 395 + out: 396 + free_page((unsigned long)sccb); 397 + return rc; 398 + } 399 + __initcall(sclp_detect_standby_memory);
+1 -1
drivers/s390/char/tape_3590.c
··· 1671 1671 1672 1672 DBF_EVENT(3, "3590 init\n"); 1673 1673 1674 - tape_3590_wq = alloc_workqueue("tape_3590", 0, 0); 1674 + tape_3590_wq = alloc_workqueue("tape_3590", WQ_PERCPU, 0); 1675 1675 if (!tape_3590_wq) 1676 1676 return -ENOMEM; 1677 1677
+3 -1
drivers/s390/crypto/zcrypt_ep11misc.c
··· 1405 1405 /* Step 3: import the encrypted key value as a new key */ 1406 1406 rc = ep11_unwrapkey(card, domain, kek, keklen, 1407 1407 encbuf, encbuflen, 0, def_iv, 1408 - keybitsize, 0, keybuf, keybufsize, keytype, xflags); 1408 + keybitsize, keygenflags, 1409 + keybuf, keybufsize, 1410 + keytype, xflags); 1409 1411 if (rc) { 1410 1412 ZCRYPT_DBF_ERR("%s importing key value as new key failed, rc=%d\n", 1411 1413 __func__, rc);
+23
include/linux/compiler_types.h
··· 330 330 #endif 331 331 332 332 /* 333 + * The assume attribute is used to indicate that a certain condition is 334 + * assumed to be true. If this condition is violated at runtime, the behavior 335 + * is undefined. Compilers may or may not use this indication to generate 336 + * optimized code. 337 + * 338 + * Note that the clang documentation states that optimizers may react 339 + * differently to this attribute, and this may even have a negative 340 + * performance impact. Therefore this attribute should be used with care. 341 + * 342 + * Optional: only supported since gcc >= 13 343 + * Optional: only supported since clang >= 19 344 + * 345 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Statement-Attributes.html#index-assume-statement-attribute 346 + * clang: https://clang.llvm.org/docs/AttributeReference.html#id13 347 + * 348 + */ 349 + #ifdef CONFIG_CC_HAS_ASSUME 350 + # define __assume(expr) __attribute__((__assume__(expr))) 351 + #else 352 + # define __assume(expr) 353 + #endif 354 + 355 + /* 333 356 * Optional: only supported since gcc >= 15 334 357 * Optional: only supported since clang >= 18 335 358 *
+10
init/Kconfig
··· 115 115 config CC_HAS_ASM_INLINE 116 116 def_bool $(success,echo 'void foo(void) { asm inline (""); }' | $(CC) -x c - -c -o /dev/null) 117 117 118 + config CC_HAS_ASSUME 119 + bool 120 + # clang needs to be at least 19.1.0 since the meaning of the assume 121 + # attribute changed: 122 + # https://github.com/llvm/llvm-project/commit/c44fa3e8a9a44c2e9a575768a3c185354b9f6c17 123 + default y if CC_IS_CLANG && CLANG_VERSION >= 190100 124 + # supported since gcc 13.1.0 125 + # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106654 126 + default y if CC_IS_GCC && GCC_VERSION >= 130100 127 + 118 128 config CC_HAS_NO_PROFILE_FN_ATTR 119 129 def_bool $(success,echo '__attribute__((no_profile_instrument_function)) int x();' | $(CC) -x c - -c -o /dev/null -Werror) 120 130