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.14-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux

Pull s390 updates from Alexander Gordeev:

- Select config option KASAN_VMALLOC if KASAN is enabled

- Select config option VMAP_STACK unconditionally

- Implement arch_atomic_inc() / arch_atomic_dec() functions which
result in a single instruction if compiled for z196 or newer
architectures

- Make layering between atomic.h and atomic_ops.h consistent

- Comment s390 preempt_count implementation

- Remove pre MARCH_HAS_Z196_FEATURES preempt count implementation

- GCC uses the number of lines of an inline assembly to calculate
number of instructions and decide on inlining. Therefore remove
superfluous new lines from a couple of inline assemblies.

- Provide arch_atomic_*_and_test() implementations that allow the
compiler to generate slightly better code.

- Optimize __preempt_count_dec_and_test()

- Remove __bootdata annotations from declarations in header files

- Add missing include of <linux/smp.h> in abs_lowcore.h to provide
declarations for get_cpu() and put_cpu() used in the code

- Fix suboptimal kernel image base when running make kasan.config

- Remove huge_pte_none() and huge_pte_none_mostly() as are identical to
the generic variants

- Remove unused PAGE_KERNEL_EXEC, SEGMENT_KERNEL_EXEC, and
REGION3_KERNEL_EXEC defines

- Simplify noexec page protection handling and change the page, segment
and region3 protection definitions automatically if the instruction
execution-protection facility is not available

- Save one instruction and prefer EXRL instruction over EX in string,
xor_*(), amode31 and other functions

- Create /dev/diag misc device to fetch diagnose specific information
from the kernel and provide it to userspace

- Retrieve electrical power readings using DIAGNOSE 0x324 ioctl

- Make ccw_device_get_ciw() consistent and use array indices instead of
pointer arithmetic

- s390/qdio: Move memory alloc/pointer arithmetic for slib and sl into
one place

- The sysfs core now allows instances of 'struct bin_attribute' to be
moved into read-only memory. Make use of that in s390 code

- Add missing TLB range adjustment in pud_free_tlb()

- Improve topology setup by adding early polarization detection

- Fix length checks in codepage_convert() function

- The generic bitops implementation is nearly identical to the s390
one. Switch to the generic variant and decrease a bit the kernel
image size

- Provide an optimized arch_test_bit() implementation which makes use
of flag output constraint. This generates slightly better code

- Provide memory topology information obtanied with DIAGNOSE 0x310
using ioctl.

- Various other small improvements, fixes, and cleanups

Also, some changes came in through a merge of 'pci-device-recovery'
branch:

- Add PCI error recovery status mechanism

- Simplify and document debug_next_entry() logic

- Split private data allocation and freeing out of debug file open()
and close() operations

- Add debug_dump() function that gets a textual representation of a
debug info (e.g. PCI recovery hardware error logs)

- Add formatted content of pci_debug_msg_id to the PCI report

* tag 's390-6.14-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (48 commits)
s390/futex: Fix FUTEX_OP_ANDN implementation
s390/diag: Add memory topology information via diag310
s390/bitops: Provide optimized arch_test_bit()
s390/bitops: Switch to generic bitops
s390/ebcdic: Fix length decrement in codepage_convert()
s390/ebcdic: Fix length check in codepage_convert()
s390/ebcdic: Use exrl instead of ex
s390/amode31: Use exrl instead of ex
s390/stackleak: Use exrl instead of ex in __stackleak_poison()
s390/lib: Use exrl instead of ex in xor functions
s390/topology: Improve topology detection
s390/tlb: Add missing TLB range adjustment
s390/pkey: Constify 'struct bin_attribute'
s390/sclp: Constify 'struct bin_attribute'
s390/pci: Constify 'struct bin_attribute'
s390/ipl: Constify 'struct bin_attribute'
s390/crypto/cpacf: Constify 'struct bin_attribute'
s390/qdio: Move memory alloc/pointer arithmetic for slib and sl into one place
s390/cio: Use array indices instead of pointer arithmetic
s390/qdio: Rename feature flag aif_osa to aif_qdio
...

+1665 -791
+2 -26
arch/s390/Kconfig
··· 233 233 select HAVE_VIRT_CPU_ACCOUNTING_IDLE 234 234 select IOMMU_HELPER if PCI 235 235 select IOMMU_SUPPORT if PCI 236 + select KASAN_VMALLOC if KASAN 236 237 select LOCK_MM_AND_FIND_VMA 237 238 select MMU_GATHER_MERGE_VMAS 238 239 select MMU_GATHER_NO_GATHER ··· 256 255 select USER_STACKTRACE_SUPPORT 257 256 select VDSO_GETRANDOM 258 257 select VIRT_CPU_ACCOUNTING 258 + select VMAP_STACK 259 259 select ZONE_DMA 260 260 # Note: keep the above list sorted alphabetically 261 261 ··· 689 687 in bits. Supported is any size between 2^42 (4TB) and 2^53 (8PB). 690 688 Increasing the number of bits also increases the kernel image size. 691 689 By default 46 bits (64TB) are supported. 692 - 693 - config CHECK_STACK 694 - def_bool y 695 - depends on !VMAP_STACK 696 - prompt "Detect kernel stack overflow" 697 - help 698 - This option enables the compiler option -mstack-guard and 699 - -mstack-size if they are available. If the compiler supports them 700 - it will emit additional code to each function prolog to trigger 701 - an illegal operation if the kernel stack is about to overflow. 702 - 703 - Say N if you are unsure. 704 - 705 - config STACK_GUARD 706 - int "Size of the guard area (128-1024)" 707 - range 128 1024 708 - depends on CHECK_STACK 709 - default "256" 710 - help 711 - This allows you to specify the size of the guard area at the lower 712 - end of the kernel stack. If the kernel stack points into the guard 713 - area on function entry an illegal operation is triggered. The size 714 - needs to be a power of 2. Please keep in mind that the size of an 715 - interrupt frame is 184 bytes for 31 bit and 328 bytes on 64 bit. 716 - The minimum size for the stack guard should be 256 for 31 bit and 717 - 512 for 64 bit. 718 690 719 691 endmenu 720 692
-9
arch/s390/Makefile
··· 72 72 KBUILD_AFLAGS_DECOMPRESSOR += $(aflags-y) 73 73 KBUILD_CFLAGS_DECOMPRESSOR += $(cflags-y) 74 74 75 - ifneq ($(call cc-option,-mstack-size=8192 -mstack-guard=128),) 76 - CC_FLAGS_CHECK_STACK := -mstack-size=$(STACK_SIZE) 77 - ifeq ($(call cc-option,-mstack-size=8192),) 78 - CC_FLAGS_CHECK_STACK += -mstack-guard=$(CONFIG_STACK_GUARD) 79 - endif 80 - export CC_FLAGS_CHECK_STACK 81 - cflags-$(CONFIG_CHECK_STACK) += $(CC_FLAGS_CHECK_STACK) 82 - endif 83 - 84 75 ifdef CONFIG_EXPOLINE 85 76 ifdef CONFIG_EXPOLINE_EXTERN 86 77 CC_FLAGS_EXPOLINE := -mindirect-branch=thunk-extern
-1
arch/s390/boot/boot.h
··· 13 13 struct machine_info { 14 14 unsigned char has_edat1 : 1; 15 15 unsigned char has_edat2 : 1; 16 - unsigned char has_nx : 1; 17 16 }; 18 17 19 18 struct vmlinux_info {
+11 -2
arch/s390/boot/startup.c
··· 30 30 unsigned long __bootdata_preserved(MODULES_VADDR); 31 31 unsigned long __bootdata_preserved(MODULES_END); 32 32 unsigned long __bootdata_preserved(max_mappable); 33 + unsigned long __bootdata_preserved(page_noexec_mask); 34 + unsigned long __bootdata_preserved(segment_noexec_mask); 35 + unsigned long __bootdata_preserved(region_noexec_mask); 33 36 int __bootdata_preserved(relocate_lowcore); 34 37 35 38 u64 __bootdata_preserved(stfle_fac_list[16]); ··· 54 51 } 55 52 if (test_facility(78)) 56 53 machine.has_edat2 = 1; 57 - if (test_facility(130)) 58 - machine.has_nx = 1; 54 + page_noexec_mask = -1UL; 55 + segment_noexec_mask = -1UL; 56 + region_noexec_mask = -1UL; 57 + if (!test_facility(130)) { 58 + page_noexec_mask &= ~_PAGE_NOEXEC; 59 + segment_noexec_mask &= ~_SEGMENT_ENTRY_NOEXEC; 60 + region_noexec_mask &= ~_REGION_ENTRY_NOEXEC; 61 + } 59 62 } 60 63 61 64 static int cmma_test_essa(void)
+3 -17
arch/s390/boot/vmem.c
··· 63 63 pud_t pud_z = __pud(__pa(kasan_early_shadow_pmd) | _REGION3_ENTRY); 64 64 p4d_t p4d_z = __p4d(__pa(kasan_early_shadow_pud) | _REGION2_ENTRY); 65 65 unsigned long memgap_start = 0; 66 - unsigned long untracked_end; 67 66 unsigned long start, end; 68 67 int i; 69 68 70 69 pte_z = __pte(__pa(kasan_early_shadow_page) | pgprot_val(PAGE_KERNEL_RO)); 71 - if (!machine.has_nx) 72 - pte_z = clear_pte_bit(pte_z, __pgprot(_PAGE_NOEXEC)); 73 70 crst_table_init((unsigned long *)kasan_early_shadow_p4d, p4d_val(p4d_z)); 74 71 crst_table_init((unsigned long *)kasan_early_shadow_pud, pud_val(pud_z)); 75 72 crst_table_init((unsigned long *)kasan_early_shadow_pmd, pmd_val(pmd_z)); ··· 90 93 kasan_populate(kernel_start + TEXT_OFFSET, kernel_end, POPULATE_KASAN_MAP_SHADOW); 91 94 kasan_populate(0, (unsigned long)__identity_va(0), POPULATE_KASAN_ZERO_SHADOW); 92 95 kasan_populate(AMODE31_START, AMODE31_END, POPULATE_KASAN_ZERO_SHADOW); 93 - if (IS_ENABLED(CONFIG_KASAN_VMALLOC)) { 94 - untracked_end = VMALLOC_START; 95 - /* shallowly populate kasan shadow for vmalloc and modules */ 96 - kasan_populate(VMALLOC_START, MODULES_END, POPULATE_KASAN_SHALLOW); 97 - } else { 98 - untracked_end = MODULES_VADDR; 99 - } 96 + /* shallowly populate kasan shadow for vmalloc and modules */ 97 + kasan_populate(VMALLOC_START, MODULES_END, POPULATE_KASAN_SHALLOW); 100 98 /* populate kasan shadow for untracked memory */ 101 - kasan_populate((unsigned long)__identity_va(ident_map_size), untracked_end, 99 + kasan_populate((unsigned long)__identity_va(ident_map_size), VMALLOC_START, 102 100 POPULATE_KASAN_ZERO_SHADOW); 103 101 kasan_populate(kernel_end, _REGION1_SIZE, POPULATE_KASAN_ZERO_SHADOW); 104 102 } ··· 292 300 continue; 293 301 entry = __pte(_pa(addr, PAGE_SIZE, mode)); 294 302 entry = set_pte_bit(entry, PAGE_KERNEL); 295 - if (!machine.has_nx) 296 - entry = clear_pte_bit(entry, __pgprot(_PAGE_NOEXEC)); 297 303 set_pte(pte, entry); 298 304 pages++; 299 305 } ··· 316 326 if (can_large_pmd(pmd, addr, next, mode)) { 317 327 entry = __pmd(_pa(addr, _SEGMENT_SIZE, mode)); 318 328 entry = set_pmd_bit(entry, SEGMENT_KERNEL); 319 - if (!machine.has_nx) 320 - entry = clear_pmd_bit(entry, __pgprot(_SEGMENT_ENTRY_NOEXEC)); 321 329 set_pmd(pmd, entry); 322 330 pages++; 323 331 continue; ··· 347 359 if (can_large_pud(pud, addr, next, mode)) { 348 360 entry = __pud(_pa(addr, _REGION3_SIZE, mode)); 349 361 entry = set_pud_bit(entry, REGION3_KERNEL); 350 - if (!machine.has_nx) 351 - entry = clear_pud_bit(entry, __pgprot(_REGION_ENTRY_NOEXEC)); 352 362 set_pud(pud, entry); 353 363 pages++; 354 364 continue;
+1 -1
arch/s390/configs/kasan.config
··· 1 1 # Help: Enable KASan for debugging 2 2 CONFIG_KASAN=y 3 3 CONFIG_KASAN_INLINE=y 4 - CONFIG_KASAN_VMALLOC=y 4 + CONFIG_KERNEL_IMAGE_BASE=0x7FFFE0000000
+2 -2
arch/s390/include/asm/abs_lowcore.h
··· 2 2 #ifndef _ASM_S390_ABS_LOWCORE_H 3 3 #define _ASM_S390_ABS_LOWCORE_H 4 4 5 - #include <asm/sections.h> 5 + #include <linux/smp.h> 6 6 #include <asm/lowcore.h> 7 7 8 8 #define ABS_LOWCORE_MAP_SIZE (NR_CPUS * sizeof(struct lowcore)) ··· 25 25 put_cpu(); 26 26 } 27 27 28 - extern int __bootdata_preserved(relocate_lowcore); 28 + extern int relocate_lowcore; 29 29 30 30 static inline int have_relocated_lowcore(void) 31 31 {
+64 -4
arch/s390/include/asm/atomic.h
··· 17 17 18 18 static __always_inline int arch_atomic_read(const atomic_t *v) 19 19 { 20 - return __atomic_read(v); 20 + return __atomic_read(&v->counter); 21 21 } 22 22 #define arch_atomic_read arch_atomic_read 23 23 24 24 static __always_inline void arch_atomic_set(atomic_t *v, int i) 25 25 { 26 - __atomic_set(v, i); 26 + __atomic_set(&v->counter, i); 27 27 } 28 28 #define arch_atomic_set arch_atomic_set 29 29 ··· 44 44 __atomic_add(i, &v->counter); 45 45 } 46 46 #define arch_atomic_add arch_atomic_add 47 + 48 + static __always_inline void arch_atomic_inc(atomic_t *v) 49 + { 50 + __atomic_add_const(1, &v->counter); 51 + } 52 + #define arch_atomic_inc arch_atomic_inc 53 + 54 + static __always_inline void arch_atomic_dec(atomic_t *v) 55 + { 56 + __atomic_add_const(-1, &v->counter); 57 + } 58 + #define arch_atomic_dec arch_atomic_dec 59 + 60 + static __always_inline bool arch_atomic_sub_and_test(int i, atomic_t *v) 61 + { 62 + return __atomic_add_and_test_barrier(-i, &v->counter); 63 + } 64 + #define arch_atomic_sub_and_test arch_atomic_sub_and_test 65 + 66 + static __always_inline bool arch_atomic_dec_and_test(atomic_t *v) 67 + { 68 + return __atomic_add_const_and_test_barrier(-1, &v->counter); 69 + } 70 + #define arch_atomic_dec_and_test arch_atomic_dec_and_test 71 + 72 + static __always_inline bool arch_atomic_inc_and_test(atomic_t *v) 73 + { 74 + return __atomic_add_const_and_test_barrier(1, &v->counter); 75 + } 76 + #define arch_atomic_inc_and_test arch_atomic_inc_and_test 47 77 48 78 #define arch_atomic_sub(_i, _v) arch_atomic_add(-(int)(_i), _v) 49 79 #define arch_atomic_sub_return(_i, _v) arch_atomic_add_return(-(int)(_i), _v) ··· 124 94 125 95 static __always_inline s64 arch_atomic64_read(const atomic64_t *v) 126 96 { 127 - return __atomic64_read(v); 97 + return __atomic64_read((long *)&v->counter); 128 98 } 129 99 #define arch_atomic64_read arch_atomic64_read 130 100 131 101 static __always_inline void arch_atomic64_set(atomic64_t *v, s64 i) 132 102 { 133 - __atomic64_set(v, i); 103 + __atomic64_set((long *)&v->counter, i); 134 104 } 135 105 #define arch_atomic64_set arch_atomic64_set 136 106 ··· 151 121 __atomic64_add(i, (long *)&v->counter); 152 122 } 153 123 #define arch_atomic64_add arch_atomic64_add 124 + 125 + static __always_inline void arch_atomic64_inc(atomic64_t *v) 126 + { 127 + __atomic64_add_const(1, (long *)&v->counter); 128 + } 129 + #define arch_atomic64_inc arch_atomic64_inc 130 + 131 + static __always_inline void arch_atomic64_dec(atomic64_t *v) 132 + { 133 + __atomic64_add_const(-1, (long *)&v->counter); 134 + } 135 + #define arch_atomic64_dec arch_atomic64_dec 136 + 137 + static __always_inline bool arch_atomic64_sub_and_test(s64 i, atomic64_t *v) 138 + { 139 + return __atomic64_add_and_test_barrier(-i, (long *)&v->counter); 140 + } 141 + #define arch_atomic64_sub_and_test arch_atomic64_sub_and_test 142 + 143 + static __always_inline bool arch_atomic64_dec_and_test(atomic64_t *v) 144 + { 145 + return __atomic64_add_const_and_test_barrier(-1, (long *)&v->counter); 146 + } 147 + #define arch_atomic64_dec_and_test arch_atomic64_dec_and_test 148 + 149 + static __always_inline bool arch_atomic64_inc_and_test(atomic64_t *v) 150 + { 151 + return __atomic64_add_const_and_test_barrier(1, (long *)&v->counter); 152 + } 153 + #define arch_atomic64_inc_and_test arch_atomic64_inc_and_test 154 154 155 155 static __always_inline s64 arch_atomic64_xchg(atomic64_t *v, s64 new) 156 156 {
+97 -24
arch/s390/include/asm/atomic_ops.h
··· 10 10 11 11 #include <linux/limits.h> 12 12 #include <asm/march.h> 13 + #include <asm/asm.h> 13 14 14 - static __always_inline int __atomic_read(const atomic_t *v) 15 + static __always_inline int __atomic_read(const int *ptr) 15 16 { 16 - int c; 17 + int val; 17 18 18 19 asm volatile( 19 - " l %[c],%[counter]\n" 20 - : [c] "=d" (c) : [counter] "R" (v->counter)); 21 - return c; 20 + " l %[val],%[ptr]\n" 21 + : [val] "=d" (val) : [ptr] "R" (*ptr)); 22 + return val; 22 23 } 23 24 24 - static __always_inline void __atomic_set(atomic_t *v, int i) 25 + static __always_inline void __atomic_set(int *ptr, int val) 25 26 { 26 - if (__builtin_constant_p(i) && i >= S16_MIN && i <= S16_MAX) { 27 + if (__builtin_constant_p(val) && val >= S16_MIN && val <= S16_MAX) { 27 28 asm volatile( 28 - " mvhi %[counter], %[i]\n" 29 - : [counter] "=Q" (v->counter) : [i] "K" (i)); 29 + " mvhi %[ptr],%[val]\n" 30 + : [ptr] "=Q" (*ptr) : [val] "K" (val)); 30 31 } else { 31 32 asm volatile( 32 - " st %[i],%[counter]\n" 33 - : [counter] "=R" (v->counter) : [i] "d" (i)); 33 + " st %[val],%[ptr]\n" 34 + : [ptr] "=R" (*ptr) : [val] "d" (val)); 34 35 } 35 36 } 36 37 37 - static __always_inline s64 __atomic64_read(const atomic64_t *v) 38 + static __always_inline long __atomic64_read(const long *ptr) 38 39 { 39 - s64 c; 40 + long val; 40 41 41 42 asm volatile( 42 - " lg %[c],%[counter]\n" 43 - : [c] "=d" (c) : [counter] "RT" (v->counter)); 44 - return c; 43 + " lg %[val],%[ptr]\n" 44 + : [val] "=d" (val) : [ptr] "RT" (*ptr)); 45 + return val; 45 46 } 46 47 47 - static __always_inline void __atomic64_set(atomic64_t *v, s64 i) 48 + static __always_inline void __atomic64_set(long *ptr, long val) 48 49 { 49 - if (__builtin_constant_p(i) && i >= S16_MIN && i <= S16_MAX) { 50 + if (__builtin_constant_p(val) && val >= S16_MIN && val <= S16_MAX) { 50 51 asm volatile( 51 - " mvghi %[counter], %[i]\n" 52 - : [counter] "=Q" (v->counter) : [i] "K" (i)); 52 + " mvghi %[ptr],%[val]\n" 53 + : [ptr] "=Q" (*ptr) : [val] "K" (val)); 53 54 } else { 54 55 asm volatile( 55 - " stg %[i],%[counter]\n" 56 - : [counter] "=RT" (v->counter) : [i] "d" (i)); 56 + " stg %[val],%[ptr]\n" 57 + : [ptr] "=RT" (*ptr) : [val] "d" (val)); 57 58 } 58 59 } 59 60 ··· 74 73 } \ 75 74 76 75 #define __ATOMIC_OPS(op_name, op_type, op_string) \ 77 - __ATOMIC_OP(op_name, op_type, op_string, "\n") \ 76 + __ATOMIC_OP(op_name, op_type, op_string, "") \ 78 77 __ATOMIC_OP(op_name##_barrier, op_type, op_string, "bcr 14,0\n") 79 78 80 79 __ATOMIC_OPS(__atomic_add, int, "laa") ··· 100 99 } 101 100 102 101 #define __ATOMIC_CONST_OPS(op_name, op_type, op_string) \ 103 - __ATOMIC_CONST_OP(op_name, op_type, op_string, "\n") \ 102 + __ATOMIC_CONST_OP(op_name, op_type, op_string, "") \ 104 103 __ATOMIC_CONST_OP(op_name##_barrier, op_type, op_string, "bcr 14,0\n") 105 104 106 105 __ATOMIC_CONST_OPS(__atomic_add_const, int, "asi") ··· 169 168 #define __atomic64_add_const_barrier(val, ptr) __atomic64_add(val, ptr) 170 169 171 170 #endif /* MARCH_HAS_Z196_FEATURES */ 171 + 172 + #if defined(MARCH_HAS_Z196_FEATURES) && defined(__HAVE_ASM_FLAG_OUTPUTS__) 173 + 174 + #define __ATOMIC_TEST_OP(op_name, op_type, op_string, op_barrier) \ 175 + static __always_inline bool op_name(op_type val, op_type *ptr) \ 176 + { \ 177 + op_type tmp; \ 178 + int cc; \ 179 + \ 180 + asm volatile( \ 181 + op_string " %[tmp],%[val],%[ptr]\n" \ 182 + op_barrier \ 183 + : "=@cc" (cc), [tmp] "=d" (tmp), [ptr] "+QS" (*ptr) \ 184 + : [val] "d" (val) \ 185 + : "memory"); \ 186 + return (cc == 0) || (cc == 2); \ 187 + } \ 188 + 189 + #define __ATOMIC_TEST_OPS(op_name, op_type, op_string) \ 190 + __ATOMIC_TEST_OP(op_name, op_type, op_string, "") \ 191 + __ATOMIC_TEST_OP(op_name##_barrier, op_type, op_string, "bcr 14,0\n") 192 + 193 + __ATOMIC_TEST_OPS(__atomic_add_and_test, int, "laal") 194 + __ATOMIC_TEST_OPS(__atomic64_add_and_test, long, "laalg") 195 + 196 + #undef __ATOMIC_TEST_OPS 197 + #undef __ATOMIC_TEST_OP 198 + 199 + #define __ATOMIC_CONST_TEST_OP(op_name, op_type, op_string, op_barrier) \ 200 + static __always_inline bool op_name(op_type val, op_type *ptr) \ 201 + { \ 202 + int cc; \ 203 + \ 204 + asm volatile( \ 205 + op_string " %[ptr],%[val]\n" \ 206 + op_barrier \ 207 + : "=@cc" (cc), [ptr] "+QS" (*ptr) \ 208 + : [val] "i" (val) \ 209 + : "memory"); \ 210 + return (cc == 0) || (cc == 2); \ 211 + } 212 + 213 + #define __ATOMIC_CONST_TEST_OPS(op_name, op_type, op_string) \ 214 + __ATOMIC_CONST_TEST_OP(op_name, op_type, op_string, "") \ 215 + __ATOMIC_CONST_TEST_OP(op_name##_barrier, op_type, op_string, "bcr 14,0\n") 216 + 217 + __ATOMIC_CONST_TEST_OPS(__atomic_add_const_and_test, int, "alsi") 218 + __ATOMIC_CONST_TEST_OPS(__atomic64_add_const_and_test, long, "algsi") 219 + 220 + #undef __ATOMIC_CONST_TEST_OPS 221 + #undef __ATOMIC_CONST_TEST_OP 222 + 223 + #else /* defined(MARCH_HAS_Z196_FEATURES) && defined(__HAVE_ASM_FLAG_OUTPUTS__) */ 224 + 225 + #define __ATOMIC_TEST_OP(op_name, op_func, op_type) \ 226 + static __always_inline bool op_name(op_type val, op_type *ptr) \ 227 + { \ 228 + return op_func(val, ptr) == -val; \ 229 + } 230 + 231 + __ATOMIC_TEST_OP(__atomic_add_and_test, __atomic_add, int) 232 + __ATOMIC_TEST_OP(__atomic_add_and_test_barrier, __atomic_add_barrier, int) 233 + __ATOMIC_TEST_OP(__atomic_add_const_and_test, __atomic_add, int) 234 + __ATOMIC_TEST_OP(__atomic_add_const_and_test_barrier, __atomic_add_barrier, int) 235 + __ATOMIC_TEST_OP(__atomic64_add_and_test, __atomic64_add, long) 236 + __ATOMIC_TEST_OP(__atomic64_add_and_test_barrier, __atomic64_add_barrier, long) 237 + __ATOMIC_TEST_OP(__atomic64_add_const_and_test, __atomic64_add, long) 238 + __ATOMIC_TEST_OP(__atomic64_add_const_and_test_barrier, __atomic64_add_barrier, long) 239 + 240 + #undef __ATOMIC_TEST_OP 241 + 242 + #endif /* defined(MARCH_HAS_Z196_FEATURES) && defined(__HAVE_ASM_FLAG_OUTPUTS__) */ 172 243 173 244 #endif /* __ARCH_S390_ATOMIC_OPS__ */
+29 -172
arch/s390/include/asm/bitops.h
··· 36 36 #include <linux/typecheck.h> 37 37 #include <linux/compiler.h> 38 38 #include <linux/types.h> 39 - #include <asm/atomic_ops.h> 40 - #include <asm/barrier.h> 39 + #include <asm/asm.h> 41 40 42 - #define __BITOPS_WORDS(bits) (((bits) + BITS_PER_LONG - 1) / BITS_PER_LONG) 41 + #define arch___set_bit generic___set_bit 42 + #define arch___clear_bit generic___clear_bit 43 + #define arch___change_bit generic___change_bit 44 + #define arch___test_and_set_bit generic___test_and_set_bit 45 + #define arch___test_and_clear_bit generic___test_and_clear_bit 46 + #define arch___test_and_change_bit generic___test_and_change_bit 47 + #define arch_test_bit_acquire generic_test_bit_acquire 43 48 44 - static inline unsigned long * 45 - __bitops_word(unsigned long nr, const volatile unsigned long *ptr) 49 + static __always_inline bool arch_test_bit(unsigned long nr, const volatile unsigned long *ptr) 46 50 { 47 - unsigned long addr; 51 + #ifdef __HAVE_ASM_FLAG_OUTPUTS__ 52 + const volatile unsigned char *addr; 53 + unsigned long mask; 54 + int cc; 48 55 49 - addr = (unsigned long)ptr + ((nr ^ (nr & (BITS_PER_LONG - 1))) >> 3); 50 - return (unsigned long *)addr; 56 + if (__builtin_constant_p(nr)) { 57 + addr = (const volatile unsigned char *)ptr; 58 + addr += (nr ^ (BITS_PER_LONG - BITS_PER_BYTE)) / BITS_PER_BYTE; 59 + mask = 1UL << (nr & (BITS_PER_BYTE - 1)); 60 + asm volatile( 61 + " tm %[addr],%[mask]\n" 62 + : "=@cc" (cc) 63 + : [addr] "R" (*addr), [mask] "I" (mask) 64 + ); 65 + return cc == 3; 66 + } 67 + #endif 68 + return generic_test_bit(nr, ptr); 51 69 } 52 70 53 - static inline unsigned long __bitops_mask(unsigned long nr) 54 - { 55 - return 1UL << (nr & (BITS_PER_LONG - 1)); 56 - } 57 - 58 - static __always_inline void arch_set_bit(unsigned long nr, volatile unsigned long *ptr) 59 - { 60 - unsigned long *addr = __bitops_word(nr, ptr); 61 - unsigned long mask = __bitops_mask(nr); 62 - 63 - __atomic64_or(mask, (long *)addr); 64 - } 65 - 66 - static __always_inline void arch_clear_bit(unsigned long nr, volatile unsigned long *ptr) 67 - { 68 - unsigned long *addr = __bitops_word(nr, ptr); 69 - unsigned long mask = __bitops_mask(nr); 70 - 71 - __atomic64_and(~mask, (long *)addr); 72 - } 73 - 74 - static __always_inline void arch_change_bit(unsigned long nr, 75 - volatile unsigned long *ptr) 76 - { 77 - unsigned long *addr = __bitops_word(nr, ptr); 78 - unsigned long mask = __bitops_mask(nr); 79 - 80 - __atomic64_xor(mask, (long *)addr); 81 - } 82 - 83 - static inline bool arch_test_and_set_bit(unsigned long nr, 84 - volatile unsigned long *ptr) 85 - { 86 - unsigned long *addr = __bitops_word(nr, ptr); 87 - unsigned long mask = __bitops_mask(nr); 88 - unsigned long old; 89 - 90 - old = __atomic64_or_barrier(mask, (long *)addr); 91 - return old & mask; 92 - } 93 - 94 - static inline bool arch_test_and_clear_bit(unsigned long nr, 95 - volatile unsigned long *ptr) 96 - { 97 - unsigned long *addr = __bitops_word(nr, ptr); 98 - unsigned long mask = __bitops_mask(nr); 99 - unsigned long old; 100 - 101 - old = __atomic64_and_barrier(~mask, (long *)addr); 102 - return old & mask; 103 - } 104 - 105 - static inline bool arch_test_and_change_bit(unsigned long nr, 106 - volatile unsigned long *ptr) 107 - { 108 - unsigned long *addr = __bitops_word(nr, ptr); 109 - unsigned long mask = __bitops_mask(nr); 110 - unsigned long old; 111 - 112 - old = __atomic64_xor_barrier(mask, (long *)addr); 113 - return old & mask; 114 - } 115 - 116 - static __always_inline void 117 - arch___set_bit(unsigned long nr, volatile unsigned long *addr) 118 - { 119 - unsigned long *p = __bitops_word(nr, addr); 120 - unsigned long mask = __bitops_mask(nr); 121 - 122 - *p |= mask; 123 - } 124 - 125 - static __always_inline void 126 - arch___clear_bit(unsigned long nr, volatile unsigned long *addr) 127 - { 128 - unsigned long *p = __bitops_word(nr, addr); 129 - unsigned long mask = __bitops_mask(nr); 130 - 131 - *p &= ~mask; 132 - } 133 - 134 - static __always_inline void 135 - arch___change_bit(unsigned long nr, volatile unsigned long *addr) 136 - { 137 - unsigned long *p = __bitops_word(nr, addr); 138 - unsigned long mask = __bitops_mask(nr); 139 - 140 - *p ^= mask; 141 - } 142 - 143 - static __always_inline bool 144 - arch___test_and_set_bit(unsigned long nr, volatile unsigned long *addr) 145 - { 146 - unsigned long *p = __bitops_word(nr, addr); 147 - unsigned long mask = __bitops_mask(nr); 148 - unsigned long old; 149 - 150 - old = *p; 151 - *p |= mask; 152 - return old & mask; 153 - } 154 - 155 - static __always_inline bool 156 - arch___test_and_clear_bit(unsigned long nr, volatile unsigned long *addr) 157 - { 158 - unsigned long *p = __bitops_word(nr, addr); 159 - unsigned long mask = __bitops_mask(nr); 160 - unsigned long old; 161 - 162 - old = *p; 163 - *p &= ~mask; 164 - return old & mask; 165 - } 166 - 167 - static __always_inline bool 168 - arch___test_and_change_bit(unsigned long nr, volatile unsigned long *addr) 169 - { 170 - unsigned long *p = __bitops_word(nr, addr); 171 - unsigned long mask = __bitops_mask(nr); 172 - unsigned long old; 173 - 174 - old = *p; 175 - *p ^= mask; 176 - return old & mask; 177 - } 178 - 179 - #define arch_test_bit generic_test_bit 180 - #define arch_test_bit_acquire generic_test_bit_acquire 181 - 182 - static inline bool arch_test_and_set_bit_lock(unsigned long nr, 183 - volatile unsigned long *ptr) 184 - { 185 - if (arch_test_bit(nr, ptr)) 186 - return true; 187 - return arch_test_and_set_bit(nr, ptr); 188 - } 189 - 190 - static inline void arch_clear_bit_unlock(unsigned long nr, 191 - volatile unsigned long *ptr) 192 - { 193 - smp_mb__before_atomic(); 194 - arch_clear_bit(nr, ptr); 195 - } 196 - 197 - static inline void arch___clear_bit_unlock(unsigned long nr, 198 - volatile unsigned long *ptr) 199 - { 200 - smp_mb(); 201 - arch___clear_bit(nr, ptr); 202 - } 203 - 204 - static inline bool arch_xor_unlock_is_negative_byte(unsigned long mask, 205 - volatile unsigned long *ptr) 206 - { 207 - unsigned long old; 208 - 209 - old = __atomic64_xor_barrier(mask, (long *)ptr); 210 - return old & BIT(7); 211 - } 212 - #define arch_xor_unlock_is_negative_byte arch_xor_unlock_is_negative_byte 213 - 214 - #include <asm-generic/bitops/instrumented-atomic.h> 215 - #include <asm-generic/bitops/instrumented-non-atomic.h> 216 - #include <asm-generic/bitops/instrumented-lock.h> 71 + #include <asm-generic/bitops/atomic.h> 72 + #include <asm-generic/bitops/non-instrumented-non-atomic.h> 73 + #include <asm-generic/bitops/lock.h> 217 74 218 75 /* 219 76 * Functions which use MSB0 bit numbering.
+1 -1
arch/s390/include/asm/checksum.h
··· 25 25 26 26 instrument_read(buff, len); 27 27 kmsan_check_memory(buff, len); 28 - asm volatile("\n" 28 + asm volatile( 29 29 "0: cksm %[sum],%[rp]\n" 30 30 " jo 0b\n" 31 31 : [sum] "+&d" (sum), [rp] "+&d" (rp.pair) : : "cc", "memory");
+1 -1
arch/s390/include/asm/css_chars.h
··· 25 25 u64 : 2; 26 26 27 27 u64 : 3; 28 - u64 aif_osa : 1; /* bit 67 */ 28 + u64 aif_qdio : 1;/* bit 67 */ 29 29 u64 : 12; 30 30 u64 eadm_rf : 1; /* bit 80 */ 31 31 u64 : 1;
+7
arch/s390/include/asm/debug.h
··· 85 85 int area, debug_entry_t *entry, 86 86 char *out_buf, size_t out_buf_size); 87 87 88 + #define DEBUG_SPRINTF_MAX_ARGS 10 89 + int debug_sprintf_format_fn(debug_info_t *id, struct debug_view *view, 90 + char *out_buf, size_t out_buf_size, 91 + const char *inbuf); 88 92 struct debug_view { 89 93 char name[DEBUG_MAX_NAME_LEN]; 90 94 debug_prolog_proc_t *prolog_proc; ··· 117 113 debug_info_t *debug_register_mode(const char *name, int pages, int nr_areas, 118 114 int buf_size, umode_t mode, uid_t uid, 119 115 gid_t gid); 116 + 117 + ssize_t debug_dump(debug_info_t *id, struct debug_view *view, 118 + char *buf, size_t buf_size, bool reverse); 120 119 121 120 void debug_unregister(debug_info_t *id); 122 121
+2
arch/s390/include/asm/diag.h
··· 36 36 DIAG_STAT_X2FC, 37 37 DIAG_STAT_X304, 38 38 DIAG_STAT_X308, 39 + DIAG_STAT_X310, 39 40 DIAG_STAT_X318, 40 41 DIAG_STAT_X320, 42 + DIAG_STAT_X324, 41 43 DIAG_STAT_X49C, 42 44 DIAG_STAT_X500, 43 45 NR_DIAG_STAT
+8 -8
arch/s390/include/asm/ebcdic.h
··· 22 22 static inline void 23 23 codepage_convert(const __u8 *codepage, volatile char *addr, unsigned long nr) 24 24 { 25 - if (nr-- <= 0) 25 + if (!nr--) 26 26 return; 27 27 asm volatile( 28 - " bras 1,1f\n" 29 - " tr 0(1,%0),0(%2)\n" 30 - "0: tr 0(256,%0),0(%2)\n" 28 + " j 2f\n" 29 + "0: tr 0(1,%0),0(%2)\n" 30 + "1: tr 0(256,%0),0(%2)\n" 31 31 " la %0,256(%0)\n" 32 - "1: ahi %1,-256\n" 33 - " jnm 0b\n" 34 - " ex %1,0(1)" 32 + "2: aghi %1,-256\n" 33 + " jnm 1b\n" 34 + " exrl %1,0b" 35 35 : "+&a" (addr), "+&a" (nr) 36 - : "a" (codepage) : "cc", "memory", "1"); 36 + : "a" (codepage) : "cc", "memory"); 37 37 } 38 38 39 39 #define ASCEBC(addr,nr) codepage_convert(_ascebc, addr, nr)
+7 -7
arch/s390/include/asm/fpu-insn.h
··· 103 103 u32 tmp; 104 104 105 105 instrument_read(fpc, sizeof(*fpc)); 106 - asm volatile("\n" 106 + asm_inline volatile( 107 107 "0: lfpc %[fpc]\n" 108 108 "1: nopr %%r7\n" 109 109 ".pushsection .fixup, \"ax\"\n" ··· 188 188 static __always_inline void fpu_vl(u8 v1, const void *vxr) 189 189 { 190 190 instrument_read(vxr, sizeof(__vector128)); 191 - asm volatile("\n" 191 + asm volatile( 192 192 " la 1,%[vxr]\n" 193 193 " VL %[v1],0,,1\n" 194 194 : ··· 246 246 247 247 size = min(index + 1, sizeof(__vector128)); 248 248 instrument_read(vxr, size); 249 - asm volatile("\n" 249 + asm volatile( 250 250 " la 1,%[vxr]\n" 251 251 " VLL %[v1],%[index],0,1\n" 252 252 : ··· 284 284 } *_v = (void *)(_vxrs); \ 285 285 \ 286 286 instrument_read(_v, size); \ 287 - asm volatile("\n" \ 287 + asm volatile( \ 288 288 " la 1,%[vxrs]\n" \ 289 289 " VLM %[v1],%[v3],0,1\n" \ 290 290 : \ ··· 367 367 static __always_inline void fpu_vst(u8 v1, const void *vxr) 368 368 { 369 369 instrument_write(vxr, sizeof(__vector128)); 370 - asm volatile("\n" 370 + asm volatile( 371 371 " la 1,%[vxr]\n" 372 372 " VST %[v1],0,,1\n" 373 373 : [vxr] "=R" (*(__vector128 *)vxr) ··· 396 396 397 397 size = min(index + 1, sizeof(__vector128)); 398 398 instrument_write(vxr, size); 399 - asm volatile("\n" 399 + asm volatile( 400 400 " la 1,%[vxr]\n" 401 401 " VSTL %[v1],%[index],0,1\n" 402 402 : [vxr] "=R" (*(u8 *)vxr) ··· 430 430 } *_v = (void *)(_vxrs); \ 431 431 \ 432 432 instrument_write(_v, size); \ 433 - asm volatile("\n" \ 433 + asm volatile( \ 434 434 " la 1,%[vxrs]\n" \ 435 435 " VSTM %[v1],%[v3],0,1\n" \ 436 436 : [vxrs] "=R" (*_v) \
+1 -1
arch/s390/include/asm/futex.h
··· 44 44 break; 45 45 case FUTEX_OP_ANDN: 46 46 __futex_atomic_op("lr %2,%1\nnr %2,%5\n", 47 - ret, oldval, newval, uaddr, oparg); 47 + ret, oldval, newval, uaddr, ~oparg); 48 48 break; 49 49 case FUTEX_OP_XOR: 50 50 __futex_atomic_op("lr %2,%1\nxr %2,%5\n",
+7 -16
arch/s390/include/asm/hugetlb.h
··· 20 20 void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, 21 21 pte_t *ptep, pte_t pte, unsigned long sz); 22 22 void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr, 23 - pte_t *ptep, pte_t pte); 23 + pte_t *ptep, pte_t pte); 24 + 24 25 #define __HAVE_ARCH_HUGE_PTEP_GET 25 - extern pte_t huge_ptep_get(struct mm_struct *mm, unsigned long addr, pte_t *ptep); 26 + pte_t huge_ptep_get(struct mm_struct *mm, unsigned long addr, pte_t *ptep); 27 + 26 28 #define __HAVE_ARCH_HUGE_PTEP_GET_AND_CLEAR 27 - extern pte_t huge_ptep_get_and_clear(struct mm_struct *mm, 28 - unsigned long addr, pte_t *ptep); 29 + pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep); 29 30 30 31 static inline void arch_clear_hugetlb_flags(struct folio *folio) 31 32 { ··· 57 56 pte_t pte, int dirty) 58 57 { 59 58 int changed = !pte_same(huge_ptep_get(vma->vm_mm, addr, ptep), pte); 59 + 60 60 if (changed) { 61 61 huge_ptep_get_and_clear(vma->vm_mm, addr, ptep); 62 62 __set_huge_pte_at(vma->vm_mm, addr, ptep, pte); ··· 70 68 unsigned long addr, pte_t *ptep) 71 69 { 72 70 pte_t pte = huge_ptep_get_and_clear(mm, addr, ptep); 71 + 73 72 __set_huge_pte_at(mm, addr, ptep, pte_wrprotect(pte)); 74 - } 75 - 76 - #define __HAVE_ARCH_HUGE_PTE_NONE 77 - static inline int huge_pte_none(pte_t pte) 78 - { 79 - return pte_none(pte); 80 - } 81 - 82 - #define __HAVE_ARCH_HUGE_PTE_NONE_MOSTLY 83 - static inline int huge_pte_none_mostly(pte_t pte) 84 - { 85 - return huge_pte_none(pte) || is_pte_marker(pte); 86 73 } 87 74 88 75 #define __HAVE_ARCH_HUGE_PTE_MKUFFD_WP
+1 -2
arch/s390/include/asm/page-states.h
··· 7 7 #ifndef PAGE_STATES_H 8 8 #define PAGE_STATES_H 9 9 10 - #include <asm/sections.h> 11 10 #include <asm/page.h> 12 11 13 12 #define ESSA_GET_STATE 0 ··· 20 21 21 22 #define ESSA_MAX ESSA_SET_STABLE_NODAT 22 23 23 - extern int __bootdata_preserved(cmma_flag); 24 + extern int cmma_flag; 24 25 25 26 static __always_inline unsigned long essa(unsigned long paddr, unsigned char cmd) 26 27 {
+66 -60
arch/s390/include/asm/pgtable.h
··· 17 17 #include <linux/page-flags.h> 18 18 #include <linux/radix-tree.h> 19 19 #include <linux/atomic.h> 20 - #include <asm/sections.h> 21 20 #include <asm/ctlreg.h> 22 21 #include <asm/bug.h> 23 22 #include <asm/page.h> ··· 34 35 PG_DIRECT_MAP_MAX 35 36 }; 36 37 37 - extern atomic_long_t __bootdata_preserved(direct_pages_count[PG_DIRECT_MAP_MAX]); 38 + extern atomic_long_t direct_pages_count[PG_DIRECT_MAP_MAX]; 38 39 39 40 static inline void update_page_count(int level, long count) 40 41 { ··· 84 85 * happen without trampolines and in addition the placement within a 85 86 * 2GB frame is branch prediction unit friendly. 86 87 */ 87 - extern unsigned long __bootdata_preserved(VMALLOC_START); 88 - extern unsigned long __bootdata_preserved(VMALLOC_END); 88 + extern unsigned long VMALLOC_START; 89 + extern unsigned long VMALLOC_END; 89 90 #define VMALLOC_DEFAULT_SIZE ((512UL << 30) - MODULES_LEN) 90 - extern struct page *__bootdata_preserved(vmemmap); 91 - extern unsigned long __bootdata_preserved(vmemmap_size); 91 + extern struct page *vmemmap; 92 + extern unsigned long vmemmap_size; 92 93 93 - extern unsigned long __bootdata_preserved(MODULES_VADDR); 94 - extern unsigned long __bootdata_preserved(MODULES_END); 94 + extern unsigned long MODULES_VADDR; 95 + extern unsigned long MODULES_END; 95 96 #define MODULES_VADDR MODULES_VADDR 96 97 #define MODULES_END MODULES_END 97 98 #define MODULES_LEN (1UL << 31) ··· 123 124 #else 124 125 #define KASLR_LEN 0UL 125 126 #endif 127 + 128 + void setup_protection_map(void); 126 129 127 130 /* 128 131 * A 64 bit pagetable entry of S390 has following format: ··· 444 443 /* 445 444 * Page protection definitions. 446 445 */ 447 - #define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_INVALID | _PAGE_PROTECT) 448 - #define PAGE_RO __pgprot(_PAGE_PRESENT | _PAGE_READ | \ 446 + #define __PAGE_NONE (_PAGE_PRESENT | _PAGE_INVALID | _PAGE_PROTECT) 447 + #define __PAGE_RO (_PAGE_PRESENT | _PAGE_READ | \ 449 448 _PAGE_NOEXEC | _PAGE_INVALID | _PAGE_PROTECT) 450 - #define PAGE_RX __pgprot(_PAGE_PRESENT | _PAGE_READ | \ 449 + #define __PAGE_RX (_PAGE_PRESENT | _PAGE_READ | \ 451 450 _PAGE_INVALID | _PAGE_PROTECT) 452 - #define PAGE_RW __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \ 451 + #define __PAGE_RW (_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \ 453 452 _PAGE_NOEXEC | _PAGE_INVALID | _PAGE_PROTECT) 454 - #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \ 453 + #define __PAGE_RWX (_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \ 455 454 _PAGE_INVALID | _PAGE_PROTECT) 456 - 457 - #define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \ 455 + #define __PAGE_SHARED (_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \ 458 456 _PAGE_YOUNG | _PAGE_DIRTY | _PAGE_NOEXEC) 459 - #define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \ 457 + #define __PAGE_KERNEL (_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \ 460 458 _PAGE_YOUNG | _PAGE_DIRTY | _PAGE_NOEXEC) 461 - #define PAGE_KERNEL_RO __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_YOUNG | \ 459 + #define __PAGE_KERNEL_RO (_PAGE_PRESENT | _PAGE_READ | _PAGE_YOUNG | \ 462 460 _PAGE_PROTECT | _PAGE_NOEXEC) 463 - #define PAGE_KERNEL_EXEC __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \ 464 - _PAGE_YOUNG | _PAGE_DIRTY) 465 461 466 - /* 467 - * On s390 the page table entry has an invalid bit and a read-only bit. 468 - * Read permission implies execute permission and write permission 469 - * implies read permission. 470 - */ 471 - /*xwr*/ 462 + extern unsigned long page_noexec_mask; 463 + 464 + #define __pgprot_page_mask(x) __pgprot((x) & page_noexec_mask) 465 + 466 + #define PAGE_NONE __pgprot_page_mask(__PAGE_NONE) 467 + #define PAGE_RO __pgprot_page_mask(__PAGE_RO) 468 + #define PAGE_RX __pgprot_page_mask(__PAGE_RX) 469 + #define PAGE_RW __pgprot_page_mask(__PAGE_RW) 470 + #define PAGE_RWX __pgprot_page_mask(__PAGE_RWX) 471 + #define PAGE_SHARED __pgprot_page_mask(__PAGE_SHARED) 472 + #define PAGE_KERNEL __pgprot_page_mask(__PAGE_KERNEL) 473 + #define PAGE_KERNEL_RO __pgprot_page_mask(__PAGE_KERNEL_RO) 472 474 473 475 /* 474 476 * Segment entry (large page) protection definitions. 475 477 */ 476 - #define SEGMENT_NONE __pgprot(_SEGMENT_ENTRY_PRESENT | \ 478 + #define __SEGMENT_NONE (_SEGMENT_ENTRY_PRESENT | \ 477 479 _SEGMENT_ENTRY_INVALID | \ 478 480 _SEGMENT_ENTRY_PROTECT) 479 - #define SEGMENT_RO __pgprot(_SEGMENT_ENTRY_PRESENT | \ 481 + #define __SEGMENT_RO (_SEGMENT_ENTRY_PRESENT | \ 480 482 _SEGMENT_ENTRY_PROTECT | \ 481 483 _SEGMENT_ENTRY_READ | \ 482 484 _SEGMENT_ENTRY_NOEXEC) 483 - #define SEGMENT_RX __pgprot(_SEGMENT_ENTRY_PRESENT | \ 485 + #define __SEGMENT_RX (_SEGMENT_ENTRY_PRESENT | \ 484 486 _SEGMENT_ENTRY_PROTECT | \ 485 487 _SEGMENT_ENTRY_READ) 486 - #define SEGMENT_RW __pgprot(_SEGMENT_ENTRY_PRESENT | \ 488 + #define __SEGMENT_RW (_SEGMENT_ENTRY_PRESENT | \ 487 489 _SEGMENT_ENTRY_READ | \ 488 490 _SEGMENT_ENTRY_WRITE | \ 489 491 _SEGMENT_ENTRY_NOEXEC) 490 - #define SEGMENT_RWX __pgprot(_SEGMENT_ENTRY_PRESENT | \ 492 + #define __SEGMENT_RWX (_SEGMENT_ENTRY_PRESENT | \ 491 493 _SEGMENT_ENTRY_READ | \ 492 494 _SEGMENT_ENTRY_WRITE) 493 - #define SEGMENT_KERNEL __pgprot(_SEGMENT_ENTRY | \ 495 + #define __SEGMENT_KERNEL (_SEGMENT_ENTRY | \ 494 496 _SEGMENT_ENTRY_LARGE | \ 495 497 _SEGMENT_ENTRY_READ | \ 496 498 _SEGMENT_ENTRY_WRITE | \ 497 499 _SEGMENT_ENTRY_YOUNG | \ 498 500 _SEGMENT_ENTRY_DIRTY | \ 499 501 _SEGMENT_ENTRY_NOEXEC) 500 - #define SEGMENT_KERNEL_RO __pgprot(_SEGMENT_ENTRY | \ 502 + #define __SEGMENT_KERNEL_RO (_SEGMENT_ENTRY | \ 501 503 _SEGMENT_ENTRY_LARGE | \ 502 504 _SEGMENT_ENTRY_READ | \ 503 505 _SEGMENT_ENTRY_YOUNG | \ 504 506 _SEGMENT_ENTRY_PROTECT | \ 505 507 _SEGMENT_ENTRY_NOEXEC) 506 - #define SEGMENT_KERNEL_EXEC __pgprot(_SEGMENT_ENTRY | \ 507 - _SEGMENT_ENTRY_LARGE | \ 508 - _SEGMENT_ENTRY_READ | \ 509 - _SEGMENT_ENTRY_WRITE | \ 510 - _SEGMENT_ENTRY_YOUNG | \ 511 - _SEGMENT_ENTRY_DIRTY) 508 + 509 + extern unsigned long segment_noexec_mask; 510 + 511 + #define __pgprot_segment_mask(x) __pgprot((x) & segment_noexec_mask) 512 + 513 + #define SEGMENT_NONE __pgprot_segment_mask(__SEGMENT_NONE) 514 + #define SEGMENT_RO __pgprot_segment_mask(__SEGMENT_RO) 515 + #define SEGMENT_RX __pgprot_segment_mask(__SEGMENT_RX) 516 + #define SEGMENT_RW __pgprot_segment_mask(__SEGMENT_RW) 517 + #define SEGMENT_RWX __pgprot_segment_mask(__SEGMENT_RWX) 518 + #define SEGMENT_KERNEL __pgprot_segment_mask(__SEGMENT_KERNEL) 519 + #define SEGMENT_KERNEL_RO __pgprot_segment_mask(__SEGMENT_KERNEL_RO) 512 520 513 521 /* 514 522 * Region3 entry (large page) protection definitions. 515 523 */ 516 524 517 - #define REGION3_KERNEL __pgprot(_REGION_ENTRY_TYPE_R3 | \ 525 + #define __REGION3_KERNEL (_REGION_ENTRY_TYPE_R3 | \ 518 526 _REGION3_ENTRY_PRESENT | \ 519 - _REGION3_ENTRY_LARGE | \ 520 - _REGION3_ENTRY_READ | \ 521 - _REGION3_ENTRY_WRITE | \ 522 - _REGION3_ENTRY_YOUNG | \ 527 + _REGION3_ENTRY_LARGE | \ 528 + _REGION3_ENTRY_READ | \ 529 + _REGION3_ENTRY_WRITE | \ 530 + _REGION3_ENTRY_YOUNG | \ 523 531 _REGION3_ENTRY_DIRTY | \ 524 532 _REGION_ENTRY_NOEXEC) 525 - #define REGION3_KERNEL_RO __pgprot(_REGION_ENTRY_TYPE_R3 | \ 526 - _REGION3_ENTRY_PRESENT | \ 527 - _REGION3_ENTRY_LARGE | \ 528 - _REGION3_ENTRY_READ | \ 529 - _REGION3_ENTRY_YOUNG | \ 530 - _REGION_ENTRY_PROTECT | \ 531 - _REGION_ENTRY_NOEXEC) 532 - #define REGION3_KERNEL_EXEC __pgprot(_REGION_ENTRY_TYPE_R3 | \ 533 + #define __REGION3_KERNEL_RO (_REGION_ENTRY_TYPE_R3 | \ 533 534 _REGION3_ENTRY_PRESENT | \ 534 - _REGION3_ENTRY_LARGE | \ 535 - _REGION3_ENTRY_READ | \ 536 - _REGION3_ENTRY_WRITE | \ 537 - _REGION3_ENTRY_YOUNG | \ 538 - _REGION3_ENTRY_DIRTY) 535 + _REGION3_ENTRY_LARGE | \ 536 + _REGION3_ENTRY_READ | \ 537 + _REGION3_ENTRY_YOUNG | \ 538 + _REGION_ENTRY_PROTECT | \ 539 + _REGION_ENTRY_NOEXEC) 540 + 541 + extern unsigned long region_noexec_mask; 542 + 543 + #define __pgprot_region_mask(x) __pgprot((x) & region_noexec_mask) 544 + 545 + #define REGION3_KERNEL __pgprot_region_mask(__REGION3_KERNEL) 546 + #define REGION3_KERNEL_RO __pgprot_region_mask(__REGION3_KERNEL_RO) 539 547 540 548 static inline bool mm_p4d_folded(struct mm_struct *mm) 541 549 { ··· 1445 1435 pte_t __pte; 1446 1436 1447 1437 __pte = __pte(physpage | pgprot_val(pgprot)); 1448 - if (!MACHINE_HAS_NX) 1449 - __pte = clear_pte_bit(__pte, __pgprot(_PAGE_NOEXEC)); 1450 1438 return pte_mkyoung(__pte); 1451 1439 } 1452 1440 ··· 1812 1804 static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr, 1813 1805 pmd_t *pmdp, pmd_t entry) 1814 1806 { 1815 - if (!MACHINE_HAS_NX) 1816 - entry = clear_pmd_bit(entry, __pgprot(_SEGMENT_ENTRY_NOEXEC)); 1817 1807 set_pmd(pmdp, entry); 1818 1808 } 1819 1809
+28 -55
arch/s390/include/asm/preempt.h
··· 8 8 #include <asm/cmpxchg.h> 9 9 #include <asm/march.h> 10 10 11 - #ifdef MARCH_HAS_Z196_FEATURES 12 - 13 11 /* We use the MSB mostly because its available */ 14 12 #define PREEMPT_NEED_RESCHED 0x80000000 13 + 14 + /* 15 + * We use the PREEMPT_NEED_RESCHED bit as an inverted NEED_RESCHED such 16 + * that a decrement hitting 0 means we can and should reschedule. 17 + */ 15 18 #define PREEMPT_ENABLED (0 + PREEMPT_NEED_RESCHED) 16 19 20 + /* 21 + * We mask the PREEMPT_NEED_RESCHED bit so as not to confuse all current users 22 + * that think a non-zero value indicates we cannot preempt. 23 + */ 17 24 static __always_inline int preempt_count(void) 18 25 { 19 26 return READ_ONCE(get_lowcore()->preempt_count) & ~PREEMPT_NEED_RESCHED; ··· 35 28 new = (old & PREEMPT_NEED_RESCHED) | (pc & ~PREEMPT_NEED_RESCHED); 36 29 } while (!arch_try_cmpxchg(&get_lowcore()->preempt_count, &old, new)); 37 30 } 31 + 32 + /* 33 + * We fold the NEED_RESCHED bit into the preempt count such that 34 + * preempt_enable() can decrement and test for needing to reschedule with a 35 + * short instruction sequence. 36 + * 37 + * We invert the actual bit, so that when the decrement hits 0 we know we both 38 + * need to resched (the bit is cleared) and can resched (no preempt count). 39 + */ 38 40 39 41 static __always_inline void set_preempt_need_resched(void) 40 42 { ··· 80 64 __preempt_count_add(-val); 81 65 } 82 66 67 + /* 68 + * Because we keep PREEMPT_NEED_RESCHED set when we do _not_ need to reschedule 69 + * a decrement which hits zero means we have no preempt_count and should 70 + * reschedule. 71 + */ 83 72 static __always_inline bool __preempt_count_dec_and_test(void) 84 73 { 85 - return __atomic_add(-1, &get_lowcore()->preempt_count) == 1; 74 + return __atomic_add_const_and_test(-1, &get_lowcore()->preempt_count); 86 75 } 87 76 77 + /* 78 + * Returns true when we need to resched and can (barring IRQ state). 79 + */ 88 80 static __always_inline bool should_resched(int preempt_offset) 89 81 { 90 - return unlikely(READ_ONCE(get_lowcore()->preempt_count) == 91 - preempt_offset); 82 + return unlikely(READ_ONCE(get_lowcore()->preempt_count) == preempt_offset); 92 83 } 93 - 94 - #else /* MARCH_HAS_Z196_FEATURES */ 95 - 96 - #define PREEMPT_ENABLED (0) 97 - 98 - static __always_inline int preempt_count(void) 99 - { 100 - return READ_ONCE(get_lowcore()->preempt_count); 101 - } 102 - 103 - static __always_inline void preempt_count_set(int pc) 104 - { 105 - get_lowcore()->preempt_count = pc; 106 - } 107 - 108 - static __always_inline void set_preempt_need_resched(void) 109 - { 110 - } 111 - 112 - static __always_inline void clear_preempt_need_resched(void) 113 - { 114 - } 115 - 116 - static __always_inline bool test_preempt_need_resched(void) 117 - { 118 - return false; 119 - } 120 - 121 - static __always_inline void __preempt_count_add(int val) 122 - { 123 - get_lowcore()->preempt_count += val; 124 - } 125 - 126 - static __always_inline void __preempt_count_sub(int val) 127 - { 128 - get_lowcore()->preempt_count -= val; 129 - } 130 - 131 - static __always_inline bool __preempt_count_dec_and_test(void) 132 - { 133 - return !--get_lowcore()->preempt_count && tif_need_resched(); 134 - } 135 - 136 - static __always_inline bool should_resched(int preempt_offset) 137 - { 138 - return unlikely(preempt_count() == preempt_offset && 139 - tif_need_resched()); 140 - } 141 - 142 - #endif /* MARCH_HAS_Z196_FEATURES */ 143 84 144 85 #define init_task_preempt_count(p) do { } while (0) 145 86 /* Deferred to CPU bringup time */
+1 -2
arch/s390/include/asm/processor.h
··· 163 163 " la %[addr],256(%[addr])\n" 164 164 " brctg %[tmp],0b\n" 165 165 "1: stg %[poison],0(%[addr])\n" 166 - " larl %[tmp],3f\n" 167 - " ex %[count],0(%[tmp])\n" 166 + " exrl %[count],3f\n" 168 167 " j 4f\n" 169 168 "2: stg %[poison],0(%[addr])\n" 170 169 " j 4f\n"
+35
arch/s390/include/asm/sclp.h
··· 16 16 /* 24 + 16 * SCLP_MAX_CORES */ 17 17 #define EXT_SCCB_READ_CPU (3 * PAGE_SIZE) 18 18 19 + #define SCLP_ERRNOTIFY_AQ_RESET 0 20 + #define SCLP_ERRNOTIFY_AQ_REPAIR 1 21 + #define SCLP_ERRNOTIFY_AQ_INFO_LOG 2 22 + #define SCLP_ERRNOTIFY_AQ_OPTICS_DATA 3 23 + 19 24 #ifndef __ASSEMBLY__ 20 25 #include <linux/uio.h> 21 26 #include <asm/chpid.h> ··· 92 87 unsigned char has_kss : 1; 93 88 unsigned char has_diag204_bif : 1; 94 89 unsigned char has_gisaf : 1; 90 + unsigned char has_diag310 : 1; 95 91 unsigned char has_diag318 : 1; 96 92 unsigned char has_diag320 : 1; 93 + unsigned char has_diag324 : 1; 97 94 unsigned char has_sipl : 1; 98 95 unsigned char has_sipl_eckd : 1; 99 96 unsigned char has_dirq : 1; ··· 117 110 unsigned int hmfai; 118 111 }; 119 112 extern struct sclp_info sclp; 113 + 114 + struct sccb_header { 115 + u16 length; 116 + u8 function_code; 117 + u8 control_mask[3]; 118 + u16 response_code; 119 + } __packed; 120 + 121 + struct evbuf_header { 122 + u16 length; 123 + u8 type; 124 + u8 flags; 125 + u16 _reserved; 126 + } __packed; 127 + 128 + struct err_notify_evbuf { 129 + struct evbuf_header header; 130 + u8 action; 131 + u8 atype; 132 + u32 fh; 133 + u32 fid; 134 + u8 data[]; 135 + } __packed; 136 + 137 + struct err_notify_sccb { 138 + struct sccb_header header; 139 + struct err_notify_evbuf evbuf; 140 + } __packed; 120 141 121 142 struct zpci_report_error_header { 122 143 u8 version; /* Interface version byte */
+1 -1
arch/s390/include/asm/tlb.h
··· 140 140 { 141 141 if (mm_pud_folded(tlb->mm)) 142 142 return; 143 + __tlb_adjust_range(tlb, address, PAGE_SIZE); 143 144 tlb->mm->context.flush_mm = 1; 144 145 tlb->freed_tables = 1; 145 146 tlb->cleared_p4ds = 1; 146 147 tlb_remove_ptdesc(tlb, pud); 147 148 } 148 - 149 149 150 150 #endif /* _S390_TLB_H */
+32
arch/s390/include/uapi/asm/diag.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 2 + /* 3 + * Diag ioctls and its associated structures definitions. 4 + * 5 + * Copyright IBM Corp. 2024 6 + */ 7 + 8 + #ifndef __S390_UAPI_ASM_DIAG_H 9 + #define __S390_UAPI_ASM_DIAG_H 10 + 11 + #include <linux/types.h> 12 + 13 + #define DIAG_MAGIC_STR 'D' 14 + 15 + struct diag324_pib { 16 + __u64 address; 17 + __u64 sequence; 18 + }; 19 + 20 + struct diag310_memtop { 21 + __u64 address; 22 + __u64 nesting_lvl; 23 + }; 24 + 25 + /* Diag ioctl definitions */ 26 + #define DIAG324_GET_PIBBUF _IOWR(DIAG_MAGIC_STR, 0x77, struct diag324_pib) 27 + #define DIAG324_GET_PIBLEN _IOR(DIAG_MAGIC_STR, 0x78, size_t) 28 + #define DIAG310_GET_STRIDE _IOR(DIAG_MAGIC_STR, 0x79, size_t) 29 + #define DIAG310_GET_MEMTOPLEN _IOWR(DIAG_MAGIC_STR, 0x7a, size_t) 30 + #define DIAG310_GET_MEMTOPBUF _IOWR(DIAG_MAGIC_STR, 0x7b, struct diag310_memtop) 31 + 32 + #endif /* __S390_UAPI_ASM_DIAG_H */
+2 -1
arch/s390/kernel/Makefile
··· 38 38 39 39 obj-y := head64.o traps.o time.o process.o early.o setup.o idle.o vtime.o 40 40 obj-y += processor.o syscall.o ptrace.o signal.o cpcmd.o ebcdic.o nmi.o 41 - obj-y += debug.o irq.o ipl.o dis.o diag.o vdso.o cpufeature.o 41 + obj-y += debug.o irq.o ipl.o dis.o vdso.o cpufeature.o 42 42 obj-y += sysinfo.o lgr.o os_info.o ctlreg.o 43 43 obj-y += runtime_instr.o cache.o fpu.o dumpstack.o guarded_storage.o sthyi.o 44 44 obj-y += entry.o reipl.o kdebugfs.o alternative.o 45 45 obj-y += nospec-branch.o ipl_vmparm.o machine_kexec_reloc.o unwind_bc.o 46 46 obj-y += smp.o text_amode31.o stacktrace.o abs_lowcore.o facility.o uv.o wti.o 47 + obj-y += diag/ 47 48 48 49 extra-y += vmlinux.lds 49 50
+1
arch/s390/kernel/abs_lowcore.c
··· 2 2 3 3 #include <linux/pgtable.h> 4 4 #include <asm/abs_lowcore.h> 5 + #include <asm/sections.h> 5 6 6 7 unsigned long __bootdata_preserved(__abs_lowcore); 7 8 int __bootdata_preserved(relocate_lowcore);
+18 -18
arch/s390/kernel/cpacf.c
··· 14 14 #define CPACF_QUERY(name, instruction) \ 15 15 static ssize_t name##_query_raw_read(struct file *fp, \ 16 16 struct kobject *kobj, \ 17 - struct bin_attribute *attr, \ 17 + const struct bin_attribute *attr, \ 18 18 char *buf, loff_t offs, \ 19 19 size_t count) \ 20 20 { \ ··· 24 24 return -EOPNOTSUPP; \ 25 25 return memory_read_from_buffer(buf, count, &offs, &mask, sizeof(mask)); \ 26 26 } \ 27 - static BIN_ATTR_RO(name##_query_raw, sizeof(cpacf_mask_t)) 27 + static const BIN_ATTR_RO(name##_query_raw, sizeof(cpacf_mask_t)) 28 28 29 29 CPACF_QUERY(km, KM); 30 30 CPACF_QUERY(kmc, KMC); ··· 40 40 CPACF_QUERY(kma, KMA); 41 41 CPACF_QUERY(kdsa, KDSA); 42 42 43 - #define CPACF_QAI(name, instruction) \ 44 - static ssize_t name##_query_auth_info_raw_read( \ 45 - struct file *fp, struct kobject *kobj, \ 46 - struct bin_attribute *attr, char *buf, loff_t offs, \ 47 - size_t count) \ 48 - { \ 49 - cpacf_qai_t qai; \ 50 - \ 51 - if (!cpacf_qai(CPACF_##instruction, &qai)) \ 52 - return -EOPNOTSUPP; \ 53 - return memory_read_from_buffer(buf, count, &offs, &qai, \ 54 - sizeof(qai)); \ 55 - } \ 56 - static BIN_ATTR_RO(name##_query_auth_info_raw, sizeof(cpacf_qai_t)) 43 + #define CPACF_QAI(name, instruction) \ 44 + static ssize_t name##_query_auth_info_raw_read( \ 45 + struct file *fp, struct kobject *kobj, \ 46 + const struct bin_attribute *attr, char *buf, loff_t offs, \ 47 + size_t count) \ 48 + { \ 49 + cpacf_qai_t qai; \ 50 + \ 51 + if (!cpacf_qai(CPACF_##instruction, &qai)) \ 52 + return -EOPNOTSUPP; \ 53 + return memory_read_from_buffer(buf, count, &offs, &qai, \ 54 + sizeof(qai)); \ 55 + } \ 56 + static const BIN_ATTR_RO(name##_query_auth_info_raw, sizeof(cpacf_qai_t)) 57 57 58 58 CPACF_QAI(km, KM); 59 59 CPACF_QAI(kmc, KMC); ··· 69 69 CPACF_QAI(kma, KMA); 70 70 CPACF_QAI(kdsa, KDSA); 71 71 72 - static struct bin_attribute *cpacf_attrs[] = { 72 + static const struct bin_attribute *const cpacf_attrs[] = { 73 73 &bin_attr_km_query_raw, 74 74 &bin_attr_kmc_query_raw, 75 75 &bin_attr_kimd_query_raw, ··· 101 101 102 102 static const struct attribute_group cpacf_attr_grp = { 103 103 .name = "cpacf", 104 - .bin_attrs = cpacf_attrs, 104 + .bin_attrs_new = cpacf_attrs, 105 105 }; 106 106 107 107 static int __init cpacf_init(void)
+196 -45
arch/s390/kernel/debug.c
··· 24 24 #include <linux/export.h> 25 25 #include <linux/init.h> 26 26 #include <linux/fs.h> 27 + #include <linux/math.h> 27 28 #include <linux/minmax.h> 28 29 #include <linux/debugfs.h> 29 30 ··· 95 94 static int debug_hex_ascii_format_fn(debug_info_t *id, struct debug_view *view, 96 95 char *out_buf, size_t out_buf_size, 97 96 const char *in_buf); 98 - static int debug_sprintf_format_fn(debug_info_t *id, struct debug_view *view, 99 - char *out_buf, size_t out_buf_size, 100 - const char *inbuf); 101 97 static void debug_areas_swap(debug_info_t *a, debug_info_t *b); 102 98 static void debug_events_append(debug_info_t *dest, debug_info_t *src); 103 99 ··· 352 354 for (i = 0; i < in->nr_areas; i++) { 353 355 for (j = 0; j < in->pages_per_area; j++) 354 356 memcpy(rc->areas[i][j], in->areas[i][j], PAGE_SIZE); 357 + rc->active_pages[i] = in->active_pages[i]; 358 + rc->active_entries[i] = in->active_entries[i]; 355 359 } 360 + rc->active_area = in->active_area; 356 361 out: 357 362 spin_unlock_irqrestore(&in->lock, flags); 358 363 return rc; ··· 423 422 return len; 424 423 } 425 424 426 - /* 427 - * debug_next_entry: 428 - * - goto next entry in p_info 425 + /** 426 + * debug_next_entry - Go to the next entry 427 + * @p_info: Private info that is manipulated 428 + * 429 + * Sets the current position in @p_info to the next entry. If no further entry 430 + * exists the current position is set to one after the end the return value 431 + * indicates that no further entries exist. 432 + * 433 + * Return: True if there are more following entries, false otherwise 429 434 */ 430 - static inline int debug_next_entry(file_private_info_t *p_info) 435 + static inline bool debug_next_entry(file_private_info_t *p_info) 431 436 { 432 437 debug_info_t *id; 433 438 ··· 441 434 if (p_info->act_entry == DEBUG_PROLOG_ENTRY) { 442 435 p_info->act_entry = 0; 443 436 p_info->act_page = 0; 444 - goto out; 437 + return true; 445 438 } 446 439 if (!id->areas) 447 - return 1; 440 + return false; 448 441 p_info->act_entry += id->entry_size; 449 442 /* switch to next page, if we reached the end of the page */ 450 443 if (p_info->act_entry > (PAGE_SIZE - id->entry_size)) { ··· 457 450 p_info->act_page = 0; 458 451 } 459 452 if (p_info->act_area >= id->nr_areas) 460 - return 1; 453 + return false; 461 454 } 462 - out: 463 - return 0; 455 + return true; 456 + } 457 + 458 + /** 459 + * debug_to_act_entry - Go to the currently active entry 460 + * @p_info: Private info that is manipulated 461 + * 462 + * Sets the current position in @p_info to the currently active 463 + * entry of @p_info->debug_info_snap 464 + */ 465 + static void debug_to_act_entry(file_private_info_t *p_info) 466 + { 467 + debug_info_t *snap_id; 468 + 469 + snap_id = p_info->debug_info_snap; 470 + p_info->act_area = snap_id->active_area; 471 + p_info->act_page = snap_id->active_pages[snap_id->active_area]; 472 + p_info->act_entry = snap_id->active_entries[snap_id->active_area]; 473 + } 474 + 475 + /** 476 + * debug_prev_entry - Go to the previous entry 477 + * @p_info: Private info that is manipulated 478 + * 479 + * Sets the current position in @p_info to the previous entry. If no previous entry 480 + * exists the current position is set left as DEBUG_PROLOG_ENTRY and the return value 481 + * indicates that no previous entries exist. 482 + * 483 + * Return: True if there are more previous entries, false otherwise 484 + */ 485 + 486 + static inline bool debug_prev_entry(file_private_info_t *p_info) 487 + { 488 + debug_info_t *id; 489 + 490 + id = p_info->debug_info_snap; 491 + if (p_info->act_entry == DEBUG_PROLOG_ENTRY) 492 + debug_to_act_entry(p_info); 493 + if (!id->areas) 494 + return false; 495 + p_info->act_entry -= id->entry_size; 496 + /* switch to prev page, if we reached the beginning of the page */ 497 + if (p_info->act_entry < 0) { 498 + /* end of previous page */ 499 + p_info->act_entry = rounddown(PAGE_SIZE, id->entry_size) - id->entry_size; 500 + p_info->act_page--; 501 + if (p_info->act_page < 0) { 502 + /* previous area */ 503 + p_info->act_area--; 504 + p_info->act_page = id->pages_per_area - 1; 505 + } 506 + if (p_info->act_area < 0) 507 + p_info->act_area = (id->nr_areas - 1) % id->nr_areas; 508 + } 509 + /* check full circle */ 510 + if (id->active_area == p_info->act_area && 511 + id->active_pages[id->active_area] == p_info->act_page && 512 + id->active_entries[id->active_area] == p_info->act_entry) 513 + return false; 514 + return true; 515 + } 516 + 517 + /** 518 + * debug_move_entry - Go to next entry in either the forward or backward direction 519 + * @p_info: Private info that is manipulated 520 + * @reverse: If true go to the next entry in reverse i.e. previous 521 + * 522 + * Sets the current position in @p_info to the next (@reverse == false) or 523 + * previous (@reverse == true) entry. 524 + * 525 + * Return: True if there are further entries in that direction, 526 + * false otherwise. 527 + */ 528 + static bool debug_move_entry(file_private_info_t *p_info, bool reverse) 529 + { 530 + if (reverse) 531 + return debug_prev_entry(p_info); 532 + else 533 + return debug_next_entry(p_info); 464 534 } 465 535 466 536 /* ··· 579 495 } 580 496 if (copy_size == formatted_line_residue) { 581 497 entry_offset = 0; 582 - if (debug_next_entry(p_info)) 498 + if (!debug_next_entry(p_info)) 583 499 goto out; 584 500 } 585 501 } ··· 614 530 return rc; /* number of input characters */ 615 531 } 616 532 533 + static file_private_info_t *debug_file_private_alloc(debug_info_t *debug_info, 534 + struct debug_view *view) 535 + { 536 + debug_info_t *debug_info_snapshot; 537 + file_private_info_t *p_info; 538 + 539 + /* 540 + * Make snapshot of current debug areas to get it consistent. 541 + * To copy all the areas is only needed, if we have a view which 542 + * formats the debug areas. 543 + */ 544 + if (!view->format_proc && !view->header_proc) 545 + debug_info_snapshot = debug_info_copy(debug_info, NO_AREAS); 546 + else 547 + debug_info_snapshot = debug_info_copy(debug_info, ALL_AREAS); 548 + 549 + if (!debug_info_snapshot) 550 + return NULL; 551 + p_info = kmalloc(sizeof(file_private_info_t), GFP_KERNEL); 552 + if (!p_info) { 553 + debug_info_free(debug_info_snapshot); 554 + return NULL; 555 + } 556 + p_info->offset = 0; 557 + p_info->debug_info_snap = debug_info_snapshot; 558 + p_info->debug_info_org = debug_info; 559 + p_info->view = view; 560 + p_info->act_area = 0; 561 + p_info->act_page = 0; 562 + p_info->act_entry = DEBUG_PROLOG_ENTRY; 563 + p_info->act_entry_offset = 0; 564 + debug_info_get(debug_info); 565 + 566 + return p_info; 567 + } 568 + 617 569 /* 618 570 * debug_open: 619 571 * - called for user open() ··· 658 538 */ 659 539 static int debug_open(struct inode *inode, struct file *file) 660 540 { 661 - debug_info_t *debug_info, *debug_info_snapshot; 541 + debug_info_t *debug_info; 662 542 file_private_info_t *p_info; 663 543 int i, rc = 0; 664 544 ··· 676 556 goto out; 677 557 678 558 found: 679 - 680 - /* Make snapshot of current debug areas to get it consistent. */ 681 - /* To copy all the areas is only needed, if we have a view which */ 682 - /* formats the debug areas. */ 683 - 684 - if (!debug_info->views[i]->format_proc && !debug_info->views[i]->header_proc) 685 - debug_info_snapshot = debug_info_copy(debug_info, NO_AREAS); 686 - else 687 - debug_info_snapshot = debug_info_copy(debug_info, ALL_AREAS); 688 - 689 - if (!debug_info_snapshot) { 690 - rc = -ENOMEM; 691 - goto out; 692 - } 693 - p_info = kmalloc(sizeof(file_private_info_t), GFP_KERNEL); 559 + p_info = debug_file_private_alloc(debug_info, debug_info->views[i]); 694 560 if (!p_info) { 695 - debug_info_free(debug_info_snapshot); 696 561 rc = -ENOMEM; 697 562 goto out; 698 563 } 699 - p_info->offset = 0; 700 - p_info->debug_info_snap = debug_info_snapshot; 701 - p_info->debug_info_org = debug_info; 702 - p_info->view = debug_info->views[i]; 703 - p_info->act_area = 0; 704 - p_info->act_page = 0; 705 - p_info->act_entry = DEBUG_PROLOG_ENTRY; 706 - p_info->act_entry_offset = 0; 707 564 file->private_data = p_info; 708 - debug_info_get(debug_info); 709 565 nonseekable_open(inode, file); 710 566 out: 711 567 mutex_unlock(&debug_mutex); 712 568 return rc; 569 + } 570 + 571 + static void debug_file_private_free(file_private_info_t *p_info) 572 + { 573 + if (p_info->debug_info_snap) 574 + debug_info_free(p_info->debug_info_snap); 575 + debug_info_put(p_info->debug_info_org); 576 + kfree(p_info); 713 577 } 714 578 715 579 /* ··· 706 602 file_private_info_t *p_info; 707 603 708 604 p_info = (file_private_info_t *) file->private_data; 709 - if (p_info->debug_info_snap) 710 - debug_info_free(p_info->debug_info_snap); 711 - debug_info_put(p_info->debug_info_org); 712 - kfree(file->private_data); 605 + debug_file_private_free(p_info); 606 + file->private_data = NULL; 713 607 return 0; /* success */ 608 + } 609 + 610 + /** 611 + * debug_dump - Get a textual representation of debug info, or as much as fits 612 + * @id: Debug information to use 613 + * @view: View with which to dump the debug information 614 + * @buf: Buffer the textual debug data representation is written to 615 + * @buf_size: Size of the buffer, including the trailing '\0' byte 616 + * @reverse: Go backwards from the last written entry 617 + * 618 + * This function may be used whenever a textual representation of the debug 619 + * information is required without using an s390dbf file. 620 + * 621 + * Note: It is the callers responsibility to supply a view that is compatible 622 + * with the debug information data. 623 + * 624 + * Return: On success returns the number of bytes written to the buffer not 625 + * including the trailing '\0' byte. If bug_size == 0 the function returns 0. 626 + * On failure an error code less than 0 is returned. 627 + */ 628 + ssize_t debug_dump(debug_info_t *id, struct debug_view *view, 629 + char *buf, size_t buf_size, bool reverse) 630 + { 631 + file_private_info_t *p_info; 632 + size_t size, offset = 0; 633 + 634 + /* Need space for '\0' byte */ 635 + if (buf_size < 1) 636 + return 0; 637 + buf_size--; 638 + 639 + p_info = debug_file_private_alloc(id, view); 640 + if (!p_info) 641 + return -ENOMEM; 642 + 643 + /* There is always at least the DEBUG_PROLOG_ENTRY */ 644 + do { 645 + size = debug_format_entry(p_info); 646 + size = min(size, buf_size - offset); 647 + memcpy(buf + offset, p_info->temp_buf, size); 648 + offset += size; 649 + if (offset >= buf_size) 650 + break; 651 + } while (debug_move_entry(p_info, reverse)); 652 + debug_file_private_free(p_info); 653 + buf[offset] = '\0'; 654 + 655 + return offset; 714 656 } 715 657 716 658 /* Create debugfs entries and add to internal list. */ ··· 1682 1532 1683 1533 #define DEBUG_SPRINTF_MAX_ARGS 10 1684 1534 1685 - static int debug_sprintf_format_fn(debug_info_t *id, struct debug_view *view, 1686 - char *out_buf, size_t out_buf_size, const char *inbuf) 1535 + int debug_sprintf_format_fn(debug_info_t *id, struct debug_view *view, 1536 + char *out_buf, size_t out_buf_size, const char *inbuf) 1687 1537 { 1688 1538 debug_sprintf_entry_t *curr_event = (debug_sprintf_entry_t *)inbuf; 1689 1539 int num_longs, num_used_args = 0, i, rc = 0; ··· 1720 1570 out: 1721 1571 return rc; 1722 1572 } 1573 + EXPORT_SYMBOL(debug_sprintf_format_fn); 1723 1574 1724 1575 /* 1725 1576 * debug_init:
+3 -1
arch/s390/kernel/diag.c arch/s390/kernel/diag/diag.c
··· 17 17 #include <asm/trace/diag.h> 18 18 #include <asm/sections.h> 19 19 #include <asm/asm.h> 20 - #include "entry.h" 20 + #include "../entry.h" 21 21 22 22 struct diag_stat { 23 23 unsigned int counter[NR_DIAG_STAT]; ··· 51 51 [DIAG_STAT_X2FC] = { .code = 0x2fc, .name = "Guest Performance Data" }, 52 52 [DIAG_STAT_X304] = { .code = 0x304, .name = "Partition-Resource Service" }, 53 53 [DIAG_STAT_X308] = { .code = 0x308, .name = "List-Directed IPL" }, 54 + [DIAG_STAT_X310] = { .code = 0x310, .name = "Memory Topology Information" }, 54 55 [DIAG_STAT_X318] = { .code = 0x318, .name = "CP Name and Version Codes" }, 55 56 [DIAG_STAT_X320] = { .code = 0x320, .name = "Certificate Store" }, 57 + [DIAG_STAT_X324] = { .code = 0x324, .name = "Power Information Block" }, 56 58 [DIAG_STAT_X49C] = { .code = 0x49c, .name = "Warning-Track Interruption" }, 57 59 [DIAG_STAT_X500] = { .code = 0x500, .name = "Virtio Service" }, 58 60 };
+1
arch/s390/kernel/diag/Makefile
··· 1 + obj-y := diag_misc.o diag324.o diag.o diag310.o
+276
arch/s390/kernel/diag/diag310.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Request memory topology information via diag0x310. 4 + * 5 + * Copyright IBM Corp. 2025 6 + */ 7 + 8 + #include <linux/kernel.h> 9 + #include <linux/types.h> 10 + #include <linux/uaccess.h> 11 + #include <linux/vmalloc.h> 12 + #include <asm/diag.h> 13 + #include <asm/sclp.h> 14 + #include <uapi/asm/diag.h> 15 + #include "diag_ioctl.h" 16 + 17 + #define DIAG310_LEVELMIN 1 18 + #define DIAG310_LEVELMAX 6 19 + 20 + enum diag310_sc { 21 + DIAG310_SUBC_0 = 0, 22 + DIAG310_SUBC_1 = 1, 23 + DIAG310_SUBC_4 = 4, 24 + DIAG310_SUBC_5 = 5 25 + }; 26 + 27 + enum diag310_retcode { 28 + DIAG310_RET_SUCCESS = 0x0001, 29 + DIAG310_RET_BUSY = 0x0101, 30 + DIAG310_RET_OPNOTSUPP = 0x0102, 31 + DIAG310_RET_SC4_INVAL = 0x0401, 32 + DIAG310_RET_SC4_NODATA = 0x0402, 33 + DIAG310_RET_SC5_INVAL = 0x0501, 34 + DIAG310_RET_SC5_NODATA = 0x0502, 35 + DIAG310_RET_SC5_ESIZE = 0x0503 36 + }; 37 + 38 + union diag310_response { 39 + u64 response; 40 + struct { 41 + u64 result : 32; 42 + u64 : 16; 43 + u64 rc : 16; 44 + }; 45 + }; 46 + 47 + union diag310_req_subcode { 48 + u64 subcode; 49 + struct { 50 + u64 : 48; 51 + u64 st : 8; 52 + u64 sc : 8; 53 + }; 54 + }; 55 + 56 + union diag310_req_size { 57 + u64 size; 58 + struct { 59 + u64 page_count : 32; 60 + u64 : 32; 61 + }; 62 + }; 63 + 64 + static inline unsigned long diag310(unsigned long subcode, unsigned long size, void *addr) 65 + { 66 + union register_pair rp = { .even = (unsigned long)addr, .odd = size }; 67 + 68 + diag_stat_inc(DIAG_STAT_X310); 69 + asm volatile("diag %[rp],%[subcode],0x310\n" 70 + : [rp] "+d" (rp.pair) 71 + : [subcode] "d" (subcode) 72 + : "memory"); 73 + return rp.odd; 74 + } 75 + 76 + static int diag310_result_to_errno(unsigned int result) 77 + { 78 + switch (result) { 79 + case DIAG310_RET_BUSY: 80 + return -EBUSY; 81 + case DIAG310_RET_OPNOTSUPP: 82 + return -EOPNOTSUPP; 83 + default: 84 + return -EINVAL; 85 + } 86 + } 87 + 88 + static int diag310_get_subcode_mask(unsigned long *mask) 89 + { 90 + union diag310_response res; 91 + 92 + res.response = diag310(DIAG310_SUBC_0, 0, NULL); 93 + if (res.rc != DIAG310_RET_SUCCESS) 94 + return diag310_result_to_errno(res.rc); 95 + *mask = res.response; 96 + return 0; 97 + } 98 + 99 + static int diag310_get_memtop_stride(unsigned long *stride) 100 + { 101 + union diag310_response res; 102 + 103 + res.response = diag310(DIAG310_SUBC_1, 0, NULL); 104 + if (res.rc != DIAG310_RET_SUCCESS) 105 + return diag310_result_to_errno(res.rc); 106 + *stride = res.result; 107 + return 0; 108 + } 109 + 110 + static int diag310_get_memtop_size(unsigned long *pages, unsigned long level) 111 + { 112 + union diag310_req_subcode req = { .sc = DIAG310_SUBC_4, .st = level }; 113 + union diag310_response res; 114 + 115 + res.response = diag310(req.subcode, 0, NULL); 116 + switch (res.rc) { 117 + case DIAG310_RET_SUCCESS: 118 + *pages = res.result; 119 + return 0; 120 + case DIAG310_RET_SC4_NODATA: 121 + return -ENODATA; 122 + case DIAG310_RET_SC4_INVAL: 123 + return -EINVAL; 124 + default: 125 + return diag310_result_to_errno(res.rc); 126 + } 127 + } 128 + 129 + static int diag310_store_topology_map(void *buf, unsigned long pages, unsigned long level) 130 + { 131 + union diag310_req_subcode req_sc = { .sc = DIAG310_SUBC_5, .st = level }; 132 + union diag310_req_size req_size = { .page_count = pages }; 133 + union diag310_response res; 134 + 135 + res.response = diag310(req_sc.subcode, req_size.size, buf); 136 + switch (res.rc) { 137 + case DIAG310_RET_SUCCESS: 138 + return 0; 139 + case DIAG310_RET_SC5_NODATA: 140 + return -ENODATA; 141 + case DIAG310_RET_SC5_ESIZE: 142 + return -EOVERFLOW; 143 + case DIAG310_RET_SC5_INVAL: 144 + return -EINVAL; 145 + default: 146 + return diag310_result_to_errno(res.rc); 147 + } 148 + } 149 + 150 + static int diag310_check_features(void) 151 + { 152 + static int features_available; 153 + unsigned long mask; 154 + int rc; 155 + 156 + if (READ_ONCE(features_available)) 157 + return 0; 158 + if (!sclp.has_diag310) 159 + return -EOPNOTSUPP; 160 + rc = diag310_get_subcode_mask(&mask); 161 + if (rc) 162 + return rc; 163 + if (!test_bit_inv(DIAG310_SUBC_1, &mask)) 164 + return -EOPNOTSUPP; 165 + if (!test_bit_inv(DIAG310_SUBC_4, &mask)) 166 + return -EOPNOTSUPP; 167 + if (!test_bit_inv(DIAG310_SUBC_5, &mask)) 168 + return -EOPNOTSUPP; 169 + WRITE_ONCE(features_available, 1); 170 + return 0; 171 + } 172 + 173 + static int memtop_get_stride_len(unsigned long *res) 174 + { 175 + static unsigned long memtop_stride; 176 + unsigned long stride; 177 + int rc; 178 + 179 + stride = READ_ONCE(memtop_stride); 180 + if (!stride) { 181 + rc = diag310_get_memtop_stride(&stride); 182 + if (rc) 183 + return rc; 184 + WRITE_ONCE(memtop_stride, stride); 185 + } 186 + *res = stride; 187 + return 0; 188 + } 189 + 190 + static int memtop_get_page_count(unsigned long *res, unsigned long level) 191 + { 192 + static unsigned long memtop_pages[DIAG310_LEVELMAX]; 193 + unsigned long pages; 194 + int rc; 195 + 196 + if (level > DIAG310_LEVELMAX || level < DIAG310_LEVELMIN) 197 + return -EINVAL; 198 + pages = READ_ONCE(memtop_pages[level - 1]); 199 + if (!pages) { 200 + rc = diag310_get_memtop_size(&pages, level); 201 + if (rc) 202 + return rc; 203 + WRITE_ONCE(memtop_pages[level - 1], pages); 204 + } 205 + *res = pages; 206 + return 0; 207 + } 208 + 209 + long diag310_memtop_stride(unsigned long arg) 210 + { 211 + size_t __user *argp = (void __user *)arg; 212 + unsigned long stride; 213 + int rc; 214 + 215 + rc = diag310_check_features(); 216 + if (rc) 217 + return rc; 218 + rc = memtop_get_stride_len(&stride); 219 + if (rc) 220 + return rc; 221 + if (put_user(stride, argp)) 222 + return -EFAULT; 223 + return 0; 224 + } 225 + 226 + long diag310_memtop_len(unsigned long arg) 227 + { 228 + size_t __user *argp = (void __user *)arg; 229 + unsigned long pages, level; 230 + int rc; 231 + 232 + rc = diag310_check_features(); 233 + if (rc) 234 + return rc; 235 + if (get_user(level, argp)) 236 + return -EFAULT; 237 + rc = memtop_get_page_count(&pages, level); 238 + if (rc) 239 + return rc; 240 + if (put_user(pages * PAGE_SIZE, argp)) 241 + return -EFAULT; 242 + return 0; 243 + } 244 + 245 + long diag310_memtop_buf(unsigned long arg) 246 + { 247 + struct diag310_memtop __user *udata = (struct diag310_memtop __user *)arg; 248 + unsigned long level, pages, data_size; 249 + u64 address; 250 + void *buf; 251 + int rc; 252 + 253 + rc = diag310_check_features(); 254 + if (rc) 255 + return rc; 256 + if (get_user(level, &udata->nesting_lvl)) 257 + return -EFAULT; 258 + if (get_user(address, &udata->address)) 259 + return -EFAULT; 260 + rc = memtop_get_page_count(&pages, level); 261 + if (rc) 262 + return rc; 263 + data_size = pages * PAGE_SIZE; 264 + buf = __vmalloc_node(data_size, PAGE_SIZE, GFP_KERNEL | __GFP_ZERO | __GFP_ACCOUNT, 265 + NUMA_NO_NODE, __builtin_return_address(0)); 266 + if (!buf) 267 + return -ENOMEM; 268 + rc = diag310_store_topology_map(buf, pages, level); 269 + if (rc) 270 + goto out; 271 + if (copy_to_user((void __user *)address, buf, data_size)) 272 + rc = -EFAULT; 273 + out: 274 + vfree(buf); 275 + return rc; 276 + }
+224
arch/s390/kernel/diag/diag324.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Request power readings for resources in a computing environment via 4 + * diag 0x324. diag 0x324 stores the power readings in the power information 5 + * block (pib). 6 + * 7 + * Copyright IBM Corp. 2024 8 + */ 9 + 10 + #define pr_fmt(fmt) "diag324: " fmt 11 + #include <linux/fs.h> 12 + #include <linux/gfp.h> 13 + #include <linux/ioctl.h> 14 + #include <linux/jiffies.h> 15 + #include <linux/kernel.h> 16 + #include <linux/ktime.h> 17 + #include <linux/string.h> 18 + #include <linux/slab.h> 19 + #include <linux/timer.h> 20 + #include <linux/types.h> 21 + #include <linux/uaccess.h> 22 + #include <linux/vmalloc.h> 23 + 24 + #include <asm/diag.h> 25 + #include <asm/sclp.h> 26 + #include <asm/timex.h> 27 + #include <uapi/asm/diag.h> 28 + #include "diag_ioctl.h" 29 + 30 + enum subcode { 31 + DIAG324_SUBC_0 = 0, 32 + DIAG324_SUBC_1 = 1, 33 + DIAG324_SUBC_2 = 2, 34 + }; 35 + 36 + enum retcode { 37 + DIAG324_RET_SUCCESS = 0x0001, 38 + DIAG324_RET_SUBC_NOTAVAIL = 0x0103, 39 + DIAG324_RET_INSUFFICIENT_SIZE = 0x0104, 40 + DIAG324_RET_READING_UNAVAILABLE = 0x0105, 41 + }; 42 + 43 + union diag324_response { 44 + u64 response; 45 + struct { 46 + u64 installed : 32; 47 + u64 : 16; 48 + u64 rc : 16; 49 + } sc0; 50 + struct { 51 + u64 format : 16; 52 + u64 : 16; 53 + u64 pib_len : 16; 54 + u64 rc : 16; 55 + } sc1; 56 + struct { 57 + u64 : 48; 58 + u64 rc : 16; 59 + } sc2; 60 + }; 61 + 62 + union diag324_request { 63 + u64 request; 64 + struct { 65 + u64 : 32; 66 + u64 allocated : 16; 67 + u64 : 12; 68 + u64 sc : 4; 69 + } sc2; 70 + }; 71 + 72 + struct pib { 73 + u32 : 8; 74 + u32 num : 8; 75 + u32 len : 16; 76 + u32 : 24; 77 + u32 hlen : 8; 78 + u64 : 64; 79 + u64 intv; 80 + u8 r[]; 81 + } __packed; 82 + 83 + struct pibdata { 84 + struct pib *pib; 85 + ktime_t expire; 86 + u64 sequence; 87 + size_t len; 88 + int rc; 89 + }; 90 + 91 + static DEFINE_MUTEX(pibmutex); 92 + static struct pibdata pibdata; 93 + 94 + #define PIBWORK_DELAY (5 * NSEC_PER_SEC) 95 + 96 + static void pibwork_handler(struct work_struct *work); 97 + static DECLARE_DELAYED_WORK(pibwork, pibwork_handler); 98 + 99 + static unsigned long diag324(unsigned long subcode, void *addr) 100 + { 101 + union register_pair rp = { .even = (unsigned long)addr }; 102 + 103 + diag_stat_inc(DIAG_STAT_X324); 104 + asm volatile("diag %[rp],%[subcode],0x324\n" 105 + : [rp] "+d" (rp.pair) 106 + : [subcode] "d" (subcode) 107 + : "memory"); 108 + return rp.odd; 109 + } 110 + 111 + static void pibwork_handler(struct work_struct *work) 112 + { 113 + struct pibdata *data = &pibdata; 114 + ktime_t timedout; 115 + 116 + mutex_lock(&pibmutex); 117 + timedout = ktime_add_ns(data->expire, PIBWORK_DELAY); 118 + if (ktime_before(ktime_get(), timedout)) { 119 + mod_delayed_work(system_wq, &pibwork, nsecs_to_jiffies(PIBWORK_DELAY)); 120 + goto out; 121 + } 122 + vfree(data->pib); 123 + data->pib = NULL; 124 + out: 125 + mutex_unlock(&pibmutex); 126 + } 127 + 128 + static void pib_update(struct pibdata *data) 129 + { 130 + union diag324_request req = { .sc2.sc = DIAG324_SUBC_2, .sc2.allocated = data->len }; 131 + union diag324_response res; 132 + int rc; 133 + 134 + memset(data->pib, 0, data->len); 135 + res.response = diag324(req.request, data->pib); 136 + switch (res.sc2.rc) { 137 + case DIAG324_RET_SUCCESS: 138 + rc = 0; 139 + break; 140 + case DIAG324_RET_SUBC_NOTAVAIL: 141 + rc = -ENOENT; 142 + break; 143 + case DIAG324_RET_INSUFFICIENT_SIZE: 144 + rc = -EMSGSIZE; 145 + break; 146 + case DIAG324_RET_READING_UNAVAILABLE: 147 + rc = -EBUSY; 148 + break; 149 + default: 150 + rc = -EINVAL; 151 + } 152 + data->rc = rc; 153 + } 154 + 155 + long diag324_pibbuf(unsigned long arg) 156 + { 157 + struct diag324_pib __user *udata = (struct diag324_pib __user *)arg; 158 + struct pibdata *data = &pibdata; 159 + static bool first = true; 160 + u64 address; 161 + int rc; 162 + 163 + if (!data->len) 164 + return -EOPNOTSUPP; 165 + if (get_user(address, &udata->address)) 166 + return -EFAULT; 167 + mutex_lock(&pibmutex); 168 + rc = -ENOMEM; 169 + if (!data->pib) 170 + data->pib = vmalloc(data->len); 171 + if (!data->pib) 172 + goto out; 173 + if (first || ktime_after(ktime_get(), data->expire)) { 174 + pib_update(data); 175 + data->sequence++; 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)); 178 + first = false; 179 + } 180 + rc = data->rc; 181 + if (rc != 0 && rc != -EBUSY) 182 + goto out; 183 + rc = copy_to_user((void __user *)address, data->pib, data->pib->len); 184 + rc |= put_user(data->sequence, &udata->sequence); 185 + if (rc) 186 + rc = -EFAULT; 187 + out: 188 + mutex_unlock(&pibmutex); 189 + return rc; 190 + } 191 + 192 + long diag324_piblen(unsigned long arg) 193 + { 194 + struct pibdata *data = &pibdata; 195 + 196 + if (!data->len) 197 + return -EOPNOTSUPP; 198 + if (put_user(data->len, (size_t __user *)arg)) 199 + return -EFAULT; 200 + return 0; 201 + } 202 + 203 + static int __init diag324_init(void) 204 + { 205 + union diag324_response res; 206 + unsigned long installed; 207 + 208 + if (!sclp.has_diag324) 209 + return -EOPNOTSUPP; 210 + res.response = diag324(DIAG324_SUBC_0, NULL); 211 + if (res.sc0.rc != DIAG324_RET_SUCCESS) 212 + return -EOPNOTSUPP; 213 + installed = res.response; 214 + if (!test_bit_inv(DIAG324_SUBC_1, &installed)) 215 + return -EOPNOTSUPP; 216 + if (!test_bit_inv(DIAG324_SUBC_2, &installed)) 217 + return -EOPNOTSUPP; 218 + res.response = diag324(DIAG324_SUBC_1, NULL); 219 + if (res.sc1.rc != DIAG324_RET_SUCCESS) 220 + return -EOPNOTSUPP; 221 + pibdata.len = res.sc1.pib_len; 222 + return 0; 223 + } 224 + device_initcall(diag324_init);
+14
arch/s390/kernel/diag/diag_ioctl.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef _DIAG_IOCTL_H 3 + #define _DIAG_IOCTL_H 4 + 5 + #include <linux/types.h> 6 + 7 + long diag324_pibbuf(unsigned long arg); 8 + long diag324_piblen(unsigned long arg); 9 + 10 + long diag310_memtop_stride(unsigned long arg); 11 + long diag310_memtop_len(unsigned long arg); 12 + long diag310_memtop_buf(unsigned long arg); 13 + 14 + #endif /* _DIAG_IOCTL_H */
+63
arch/s390/kernel/diag/diag_misc.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Provide diagnose information via misc device /dev/diag. 4 + * 5 + * Copyright IBM Corp. 2024 6 + */ 7 + 8 + #include <linux/fs.h> 9 + #include <linux/init.h> 10 + #include <linux/ioctl.h> 11 + #include <linux/kernel.h> 12 + #include <linux/miscdevice.h> 13 + #include <linux/types.h> 14 + 15 + #include <uapi/asm/diag.h> 16 + #include "diag_ioctl.h" 17 + 18 + static long diag_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 19 + { 20 + long rc; 21 + 22 + switch (cmd) { 23 + case DIAG324_GET_PIBLEN: 24 + rc = diag324_piblen(arg); 25 + break; 26 + case DIAG324_GET_PIBBUF: 27 + rc = diag324_pibbuf(arg); 28 + break; 29 + case DIAG310_GET_STRIDE: 30 + rc = diag310_memtop_stride(arg); 31 + break; 32 + case DIAG310_GET_MEMTOPLEN: 33 + rc = diag310_memtop_len(arg); 34 + break; 35 + case DIAG310_GET_MEMTOPBUF: 36 + rc = diag310_memtop_buf(arg); 37 + break; 38 + default: 39 + rc = -ENOIOCTLCMD; 40 + break; 41 + } 42 + return rc; 43 + } 44 + 45 + static const struct file_operations fops = { 46 + .owner = THIS_MODULE, 47 + .open = nonseekable_open, 48 + .unlocked_ioctl = diag_ioctl, 49 + }; 50 + 51 + static struct miscdevice diagdev = { 52 + .name = "diag", 53 + .minor = MISC_DYNAMIC_MINOR, 54 + .fops = &fops, 55 + .mode = 0444, 56 + }; 57 + 58 + static int diag_init(void) 59 + { 60 + return misc_register(&diagdev); 61 + } 62 + 63 + device_initcall(diag_init);
+2 -18
arch/s390/kernel/entry.S
··· 52 52 ALT_FACILITY(193) 53 53 .endm 54 54 55 - .macro CHECK_STACK savearea, lowcore 56 - #ifdef CONFIG_CHECK_STACK 57 - tml %r15,THREAD_SIZE - CONFIG_STACK_GUARD 58 - la %r14,\savearea(\lowcore) 59 - jz stack_overflow 60 - #endif 61 - .endm 62 - 63 55 .macro CHECK_VMAP_STACK savearea, lowcore, oklabel 64 - #ifdef CONFIG_VMAP_STACK 65 56 lgr %r14,%r15 66 57 nill %r14,0x10000 - THREAD_SIZE 67 58 oill %r14,STACK_INIT_OFFSET ··· 68 77 je \oklabel 69 78 la %r14,\savearea(\lowcore) 70 79 j stack_overflow 71 - #else 72 - j \oklabel 73 - #endif 74 80 .endm 75 81 76 82 /* ··· 314 326 jnz 2f # -> enabled, can't be a double fault 315 327 tm __LC_PGM_ILC+3(%r13),0x80 # check for per exception 316 328 jnz .Lpgm_svcper # -> single stepped svc 317 - 2: CHECK_STACK __LC_SAVE_AREA,%r13 318 - aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) 329 + 2: aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) 319 330 # CHECK_VMAP_STACK branches to stack_overflow or 4f 320 331 CHECK_VMAP_STACK __LC_SAVE_AREA,%r13,4f 321 332 3: lg %r15,__LC_KERNEL_STACK(%r13) ··· 381 394 BPENTER __SF_SIE_FLAGS(%r15),_TIF_ISOLATE_BP_GUEST 382 395 SIEEXIT __SF_SIE_CONTROL(%r15),%r13 383 396 #endif 384 - 0: CHECK_STACK __LC_SAVE_AREA,%r13 385 - aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) 397 + 0: aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) 386 398 j 2f 387 399 1: lctlg %c1,%c1,__LC_KERNEL_ASCE(%r13) 388 400 lg %r15,__LC_KERNEL_STACK(%r13) ··· 589 603 590 604 .section .kprobes.text, "ax" 591 605 592 - #if defined(CONFIG_CHECK_STACK) || defined(CONFIG_VMAP_STACK) 593 606 /* 594 607 * The synchronous or the asynchronous stack overflowed. We are dead. 595 608 * No need to properly save the registers, we are going to panic anyway. ··· 606 621 lgr %r2,%r11 # pass pointer to pt_regs 607 622 jg kernel_stack_overflow 608 623 SYM_CODE_END(stack_overflow) 609 - #endif 610 624 611 625 .section .data, "aw" 612 626 .balign 4
+71 -71
arch/s390/kernel/ipl.c
··· 280 280 sys_##_prefix##_##_name##_show, \ 281 281 sys_##_prefix##_##_name##_store) 282 282 283 - #define IPL_ATTR_SCP_DATA_SHOW_FN(_prefix, _ipl_block) \ 284 - static ssize_t sys_##_prefix##_scp_data_show(struct file *filp, \ 285 - struct kobject *kobj, \ 286 - struct bin_attribute *attr, \ 287 - char *buf, loff_t off, \ 288 - size_t count) \ 289 - { \ 290 - size_t size = _ipl_block.scp_data_len; \ 291 - void *scp_data = _ipl_block.scp_data; \ 292 - \ 293 - return memory_read_from_buffer(buf, count, &off, \ 294 - scp_data, size); \ 283 + #define IPL_ATTR_SCP_DATA_SHOW_FN(_prefix, _ipl_block) \ 284 + static ssize_t sys_##_prefix##_scp_data_show(struct file *filp, \ 285 + struct kobject *kobj, \ 286 + const struct bin_attribute *attr, \ 287 + char *buf, loff_t off, \ 288 + size_t count) \ 289 + { \ 290 + size_t size = _ipl_block.scp_data_len; \ 291 + void *scp_data = _ipl_block.scp_data; \ 292 + \ 293 + return memory_read_from_buffer(buf, count, &off, \ 294 + scp_data, size); \ 295 295 } 296 296 297 297 #define IPL_ATTR_SCP_DATA_STORE_FN(_prefix, _ipl_block_hdr, _ipl_block, _ipl_bp_len, _ipl_bp0_len)\ 298 - static ssize_t sys_##_prefix##_scp_data_store(struct file *filp, \ 299 - struct kobject *kobj, \ 300 - struct bin_attribute *attr, \ 301 - char *buf, loff_t off, \ 302 - size_t count) \ 303 - { \ 304 - size_t scpdata_len = count; \ 305 - size_t padding; \ 306 - \ 307 - if (off) \ 308 - return -EINVAL; \ 309 - \ 310 - memcpy(_ipl_block.scp_data, buf, count); \ 311 - if (scpdata_len % 8) { \ 312 - padding = 8 - (scpdata_len % 8); \ 313 - memset(_ipl_block.scp_data + scpdata_len, \ 314 - 0, padding); \ 315 - scpdata_len += padding; \ 316 - } \ 317 - \ 318 - _ipl_block_hdr.len = _ipl_bp_len + scpdata_len; \ 319 - _ipl_block.len = _ipl_bp0_len + scpdata_len; \ 320 - _ipl_block.scp_data_len = scpdata_len; \ 321 - \ 322 - return count; \ 298 + static ssize_t sys_##_prefix##_scp_data_store(struct file *filp, \ 299 + struct kobject *kobj, \ 300 + const struct bin_attribute *attr, \ 301 + char *buf, loff_t off, \ 302 + size_t count) \ 303 + { \ 304 + size_t scpdata_len = count; \ 305 + size_t padding; \ 306 + \ 307 + if (off) \ 308 + return -EINVAL; \ 309 + \ 310 + memcpy(_ipl_block.scp_data, buf, count); \ 311 + if (scpdata_len % 8) { \ 312 + padding = 8 - (scpdata_len % 8); \ 313 + memset(_ipl_block.scp_data + scpdata_len, \ 314 + 0, padding); \ 315 + scpdata_len += padding; \ 316 + } \ 317 + \ 318 + _ipl_block_hdr.len = _ipl_bp_len + scpdata_len; \ 319 + _ipl_block.len = _ipl_bp0_len + scpdata_len; \ 320 + _ipl_block.scp_data_len = scpdata_len; \ 321 + \ 322 + return count; \ 323 323 } 324 324 325 325 #define DEFINE_IPL_ATTR_SCP_DATA_RO(_prefix, _ipl_block, _size) \ 326 326 IPL_ATTR_SCP_DATA_SHOW_FN(_prefix, _ipl_block) \ 327 - static struct bin_attribute sys_##_prefix##_scp_data_attr = \ 327 + static const struct bin_attribute sys_##_prefix##_scp_data_attr = \ 328 328 __BIN_ATTR(scp_data, 0444, sys_##_prefix##_scp_data_show, \ 329 329 NULL, _size) 330 330 331 331 #define DEFINE_IPL_ATTR_SCP_DATA_RW(_prefix, _ipl_block_hdr, _ipl_block, _ipl_bp_len, _ipl_bp0_len, _size)\ 332 332 IPL_ATTR_SCP_DATA_SHOW_FN(_prefix, _ipl_block) \ 333 333 IPL_ATTR_SCP_DATA_STORE_FN(_prefix, _ipl_block_hdr, _ipl_block, _ipl_bp_len, _ipl_bp0_len)\ 334 - static struct bin_attribute sys_##_prefix##_scp_data_attr = \ 334 + static const struct bin_attribute sys_##_prefix##_scp_data_attr = \ 335 335 __BIN_ATTR(scp_data, 0644, sys_##_prefix##_scp_data_show, \ 336 336 sys_##_prefix##_scp_data_store, _size) 337 337 ··· 434 434 __ATTR(device, 0444, sys_ipl_device_show, NULL); 435 435 436 436 static ssize_t sys_ipl_parameter_read(struct file *filp, struct kobject *kobj, 437 - struct bin_attribute *attr, char *buf, 437 + const struct bin_attribute *attr, char *buf, 438 438 loff_t off, size_t count) 439 439 { 440 440 return memory_read_from_buffer(buf, count, &off, &ipl_block, 441 441 ipl_block.hdr.len); 442 442 } 443 - static struct bin_attribute sys_ipl_parameter_attr = 443 + static const struct bin_attribute sys_ipl_parameter_attr = 444 444 __BIN_ATTR(binary_parameter, 0444, sys_ipl_parameter_read, NULL, 445 445 PAGE_SIZE); 446 446 447 447 DEFINE_IPL_ATTR_SCP_DATA_RO(ipl_fcp, ipl_block.fcp, PAGE_SIZE); 448 448 449 - static struct bin_attribute *ipl_fcp_bin_attrs[] = { 449 + static const struct bin_attribute *const ipl_fcp_bin_attrs[] = { 450 450 &sys_ipl_parameter_attr, 451 451 &sys_ipl_fcp_scp_data_attr, 452 452 NULL, ··· 454 454 455 455 DEFINE_IPL_ATTR_SCP_DATA_RO(ipl_nvme, ipl_block.nvme, PAGE_SIZE); 456 456 457 - static struct bin_attribute *ipl_nvme_bin_attrs[] = { 457 + static const struct bin_attribute *const ipl_nvme_bin_attrs[] = { 458 458 &sys_ipl_parameter_attr, 459 459 &sys_ipl_nvme_scp_data_attr, 460 460 NULL, ··· 462 462 463 463 DEFINE_IPL_ATTR_SCP_DATA_RO(ipl_eckd, ipl_block.eckd, PAGE_SIZE); 464 464 465 - static struct bin_attribute *ipl_eckd_bin_attrs[] = { 465 + static const struct bin_attribute *const ipl_eckd_bin_attrs[] = { 466 466 &sys_ipl_parameter_attr, 467 467 &sys_ipl_eckd_scp_data_attr, 468 468 NULL, ··· 593 593 NULL, 594 594 }; 595 595 596 - static struct attribute_group ipl_fcp_attr_group = { 596 + static const struct attribute_group ipl_fcp_attr_group = { 597 597 .attrs = ipl_fcp_attrs, 598 - .bin_attrs = ipl_fcp_bin_attrs, 598 + .bin_attrs_new = ipl_fcp_bin_attrs, 599 599 }; 600 600 601 601 static struct attribute *ipl_nvme_attrs[] = { ··· 607 607 NULL, 608 608 }; 609 609 610 - static struct attribute_group ipl_nvme_attr_group = { 610 + static const struct attribute_group ipl_nvme_attr_group = { 611 611 .attrs = ipl_nvme_attrs, 612 - .bin_attrs = ipl_nvme_bin_attrs, 612 + .bin_attrs_new = ipl_nvme_bin_attrs, 613 613 }; 614 614 615 615 static struct attribute *ipl_eckd_attrs[] = { ··· 620 620 NULL, 621 621 }; 622 622 623 - static struct attribute_group ipl_eckd_attr_group = { 623 + static const struct attribute_group ipl_eckd_attr_group = { 624 624 .attrs = ipl_eckd_attrs, 625 - .bin_attrs = ipl_eckd_bin_attrs, 625 + .bin_attrs_new = ipl_eckd_bin_attrs, 626 626 }; 627 627 628 628 /* CCW ipl device attributes */ ··· 640 640 NULL, 641 641 }; 642 642 643 - static struct attribute_group ipl_ccw_attr_group_vm = { 643 + static const struct attribute_group ipl_ccw_attr_group_vm = { 644 644 .attrs = ipl_ccw_attrs_vm, 645 645 }; 646 646 647 - static struct attribute_group ipl_ccw_attr_group_lpar = { 647 + static const struct attribute_group ipl_ccw_attr_group_lpar = { 648 648 .attrs = ipl_ccw_attrs_lpar 649 649 }; 650 650 ··· 655 655 NULL, 656 656 }; 657 657 658 - static struct attribute_group ipl_common_attr_group = { 658 + static const struct attribute_group ipl_common_attr_group = { 659 659 .attrs = ipl_common_attrs, 660 660 }; 661 661 ··· 808 808 IPL_BP_FCP_LEN, IPL_BP0_FCP_LEN, 809 809 DIAG308_SCPDATA_SIZE); 810 810 811 - static struct bin_attribute *reipl_fcp_bin_attrs[] = { 811 + static const struct bin_attribute *const reipl_fcp_bin_attrs[] = { 812 812 &sys_reipl_fcp_scp_data_attr, 813 813 NULL, 814 814 }; ··· 917 917 NULL, 918 918 }; 919 919 920 - static struct attribute_group reipl_fcp_attr_group = { 920 + static const struct attribute_group reipl_fcp_attr_group = { 921 921 .attrs = reipl_fcp_attrs, 922 - .bin_attrs = reipl_fcp_bin_attrs, 922 + .bin_attrs_new = reipl_fcp_bin_attrs, 923 923 }; 924 924 925 925 static struct kobj_attribute sys_reipl_fcp_clear_attr = ··· 932 932 IPL_BP_NVME_LEN, IPL_BP0_NVME_LEN, 933 933 DIAG308_SCPDATA_SIZE); 934 934 935 - static struct bin_attribute *reipl_nvme_bin_attrs[] = { 935 + static const struct bin_attribute *const reipl_nvme_bin_attrs[] = { 936 936 &sys_reipl_nvme_scp_data_attr, 937 937 NULL, 938 938 }; ··· 955 955 NULL, 956 956 }; 957 957 958 - static struct attribute_group reipl_nvme_attr_group = { 958 + static const struct attribute_group reipl_nvme_attr_group = { 959 959 .attrs = reipl_nvme_attrs, 960 - .bin_attrs = reipl_nvme_bin_attrs 960 + .bin_attrs_new = reipl_nvme_bin_attrs 961 961 }; 962 962 963 963 static ssize_t reipl_nvme_clear_show(struct kobject *kobj, ··· 1031 1031 IPL_BP_ECKD_LEN, IPL_BP0_ECKD_LEN, 1032 1032 DIAG308_SCPDATA_SIZE); 1033 1033 1034 - static struct bin_attribute *reipl_eckd_bin_attrs[] = { 1034 + static const struct bin_attribute *const reipl_eckd_bin_attrs[] = { 1035 1035 &sys_reipl_eckd_scp_data_attr, 1036 1036 NULL, 1037 1037 }; ··· 1048 1048 NULL, 1049 1049 }; 1050 1050 1051 - static struct attribute_group reipl_eckd_attr_group = { 1051 + static const struct attribute_group reipl_eckd_attr_group = { 1052 1052 .attrs = reipl_eckd_attrs, 1053 - .bin_attrs = reipl_eckd_bin_attrs 1053 + .bin_attrs_new = reipl_eckd_bin_attrs 1054 1054 }; 1055 1055 1056 1056 static ssize_t reipl_eckd_clear_show(struct kobject *kobj, ··· 1587 1587 NULL, 1588 1588 }; 1589 1589 1590 - static struct bin_attribute *dump_fcp_bin_attrs[] = { 1590 + static const struct bin_attribute *const dump_fcp_bin_attrs[] = { 1591 1591 &sys_dump_fcp_scp_data_attr, 1592 1592 NULL, 1593 1593 }; 1594 1594 1595 - static struct attribute_group dump_fcp_attr_group = { 1595 + static const struct attribute_group dump_fcp_attr_group = { 1596 1596 .name = IPL_FCP_STR, 1597 1597 .attrs = dump_fcp_attrs, 1598 - .bin_attrs = dump_fcp_bin_attrs, 1598 + .bin_attrs_new = dump_fcp_bin_attrs, 1599 1599 }; 1600 1600 1601 1601 /* NVME dump device attributes */ ··· 1621 1621 NULL, 1622 1622 }; 1623 1623 1624 - static struct bin_attribute *dump_nvme_bin_attrs[] = { 1624 + static const struct bin_attribute *const dump_nvme_bin_attrs[] = { 1625 1625 &sys_dump_nvme_scp_data_attr, 1626 1626 NULL, 1627 1627 }; 1628 1628 1629 - static struct attribute_group dump_nvme_attr_group = { 1629 + static const struct attribute_group dump_nvme_attr_group = { 1630 1630 .name = IPL_NVME_STR, 1631 1631 .attrs = dump_nvme_attrs, 1632 - .bin_attrs = dump_nvme_bin_attrs, 1632 + .bin_attrs_new = dump_nvme_bin_attrs, 1633 1633 }; 1634 1634 1635 1635 /* ECKD dump device attributes */ ··· 1655 1655 NULL, 1656 1656 }; 1657 1657 1658 - static struct bin_attribute *dump_eckd_bin_attrs[] = { 1658 + static const struct bin_attribute *const dump_eckd_bin_attrs[] = { 1659 1659 &sys_dump_eckd_scp_data_attr, 1660 1660 NULL, 1661 1661 }; 1662 1662 1663 - static struct attribute_group dump_eckd_attr_group = { 1663 + static const struct attribute_group dump_eckd_attr_group = { 1664 1664 .name = IPL_ECKD_STR, 1665 1665 .attrs = dump_eckd_attrs, 1666 - .bin_attrs = dump_eckd_bin_attrs, 1666 + .bin_attrs_new = dump_eckd_bin_attrs, 1667 1667 }; 1668 1668 1669 1669 /* CCW dump device attributes */
+1
arch/s390/kernel/os_info.c
··· 18 18 #include <asm/physmem_info.h> 19 19 #include <asm/maccess.h> 20 20 #include <asm/asm-offsets.h> 21 + #include <asm/sections.h> 21 22 #include <asm/ipl.h> 22 23 23 24 /*
+13 -20
arch/s390/kernel/setup.c
··· 157 157 EXPORT_SYMBOL(stfle_fac_list); 158 158 struct oldmem_data __bootdata_preserved(oldmem_data); 159 159 160 - unsigned long VMALLOC_START; 160 + unsigned long __bootdata_preserved(VMALLOC_START); 161 161 EXPORT_SYMBOL(VMALLOC_START); 162 162 163 - unsigned long VMALLOC_END; 163 + unsigned long __bootdata_preserved(VMALLOC_END); 164 164 EXPORT_SYMBOL(VMALLOC_END); 165 165 166 - struct page *vmemmap; 166 + struct page *__bootdata_preserved(vmemmap); 167 167 EXPORT_SYMBOL(vmemmap); 168 - unsigned long vmemmap_size; 168 + unsigned long __bootdata_preserved(vmemmap_size); 169 169 170 - unsigned long MODULES_VADDR; 171 - unsigned long MODULES_END; 170 + unsigned long __bootdata_preserved(MODULES_VADDR); 171 + unsigned long __bootdata_preserved(MODULES_END); 172 172 173 173 /* An array with a pointer to the lowcore of every CPU. */ 174 174 struct lowcore *lowcore_ptr[NR_CPUS]; ··· 359 359 360 360 unsigned long stack_alloc(void) 361 361 { 362 - #ifdef CONFIG_VMAP_STACK 363 - void *ret; 362 + void *stack; 364 363 365 - ret = __vmalloc_node(THREAD_SIZE, THREAD_SIZE, THREADINFO_GFP, 366 - NUMA_NO_NODE, __builtin_return_address(0)); 367 - kmemleak_not_leak(ret); 368 - return (unsigned long)ret; 369 - #else 370 - return __get_free_pages(GFP_KERNEL, THREAD_SIZE_ORDER); 371 - #endif 364 + stack = __vmalloc_node(THREAD_SIZE, THREAD_SIZE, THREADINFO_GFP, 365 + NUMA_NO_NODE, __builtin_return_address(0)); 366 + kmemleak_not_leak(stack); 367 + return (unsigned long)stack; 372 368 } 373 369 374 370 void stack_free(unsigned long stack) 375 371 { 376 - #ifdef CONFIG_VMAP_STACK 377 - vfree((void *) stack); 378 - #else 379 - free_pages(stack, THREAD_SIZE_ORDER); 380 - #endif 372 + vfree((void *)stack); 381 373 } 382 374 383 375 static unsigned long __init stack_alloc_early(void) ··· 971 979 if (test_facility(193)) 972 980 static_branch_enable(&cpu_has_bear); 973 981 982 + setup_protection_map(); 974 983 /* 975 984 * Create kernel page tables. 976 985 */
+1 -2
arch/s390/kernel/text_amode31.S
··· 18 18 * affects a few functions that are not performance-relevant. 19 19 */ 20 20 .macro BR_EX_AMODE31_r14 21 - larl %r1,0f 22 - ex 0,0(%r1) 21 + exrl 0,0f 23 22 j . 24 23 0: br %r14 25 24 .endm
+11
arch/s390/kernel/topology.c
··· 556 556 } 557 557 } 558 558 559 + static int __init detect_polarization(union topology_entry *tle) 560 + { 561 + struct topology_core *tl_core; 562 + 563 + while (tle->nl) 564 + tle = next_tle(tle); 565 + tl_core = (struct topology_core *)tle; 566 + return tl_core->pp != POLARIZATION_HRZ; 567 + } 568 + 559 569 void __init topology_init_early(void) 560 570 { 561 571 struct sysinfo_15_1_x *info; ··· 585 575 __func__, PAGE_SIZE, PAGE_SIZE); 586 576 info = tl_info; 587 577 store_topology(info); 578 + cpu_management = detect_polarization(info->tle); 588 579 pr_info("The CPU configuration topology of the machine is: %d %d %d %d %d %d / %d\n", 589 580 info->mag[0], info->mag[1], info->mag[2], info->mag[3], 590 581 info->mag[4], info->mag[5], info->mnest);
+1 -1
arch/s390/kernel/vdso64/Makefile
··· 5 5 include $(srctree)/lib/vdso/Makefile 6 6 obj-vdso64 = vdso_user_wrapper.o note.o vgetrandom-chacha.o 7 7 obj-cvdso64 = vdso64_generic.o getcpu.o vgetrandom.o 8 - VDSO_CFLAGS_REMOVE := -pg $(CC_FLAGS_FTRACE) $(CC_FLAGS_EXPOLINE) $(CC_FLAGS_CHECK_STACK) 8 + VDSO_CFLAGS_REMOVE := -pg $(CC_FLAGS_FTRACE) $(CC_FLAGS_EXPOLINE) 9 9 CFLAGS_REMOVE_getcpu.o = $(VDSO_CFLAGS_REMOVE) 10 10 CFLAGS_REMOVE_vgetrandom.o = $(VDSO_CFLAGS_REMOVE) 11 11 CFLAGS_REMOVE_vdso64_generic.o = $(VDSO_CFLAGS_REMOVE)
+2 -1
arch/s390/kernel/vmcore_info.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 3 3 #include <linux/vmcore_info.h> 4 - #include <asm/abs_lowcore.h> 5 4 #include <linux/mm.h> 5 + #include <asm/abs_lowcore.h> 6 + #include <asm/sections.h> 6 7 #include <asm/setup.h> 7 8 8 9 void arch_crash_save_vmcoreinfo(void)
+5 -10
arch/s390/lib/mem.S
··· 34 34 la %r3,256(%r3) 35 35 brctg %r0,.Lmemmove_forward_loop 36 36 .Lmemmove_forward_remainder: 37 - larl %r5,.Lmemmove_mvc 38 - ex %r4,0(%r5) 37 + exrl %r4,.Lmemmove_mvc 39 38 .Lmemmove_exit: 40 39 BR_EX %r14 41 40 .Lmemmove_reverse: ··· 82 83 la %r1,256(%r1) 83 84 brctg %r3,.Lmemset_clear_loop 84 85 .Lmemset_clear_remainder: 85 - larl %r3,.Lmemset_xc 86 - ex %r4,0(%r3) 86 + exrl %r4,.Lmemset_xc 87 87 .Lmemset_exit: 88 88 BR_EX %r14 89 89 .Lmemset_fill: ··· 100 102 brctg %r5,.Lmemset_fill_loop 101 103 .Lmemset_fill_remainder: 102 104 stc %r3,0(%r1) 103 - larl %r5,.Lmemset_mvc 104 - ex %r4,0(%r5) 105 + exrl %r4,.Lmemset_mvc 105 106 BR_EX %r14 106 107 .Lmemset_fill_exit: 107 108 stc %r3,0(%r1) ··· 129 132 lgr %r1,%r2 130 133 jnz .Lmemcpy_loop 131 134 .Lmemcpy_remainder: 132 - larl %r5,.Lmemcpy_mvc 133 - ex %r4,0(%r5) 135 + exrl %r4,.Lmemcpy_mvc 134 136 .Lmemcpy_exit: 135 137 BR_EX %r14 136 138 .Lmemcpy_loop: ··· 171 175 brctg %r5,.L__memset_loop\bits 172 176 .L__memset_remainder\bits: 173 177 \insn %r3,0(%r1) 174 - larl %r5,.L__memset_mvc\bits 175 - ex %r4,0(%r5) 178 + exrl %r4,.L__memset_mvc\bits 176 179 BR_EX %r14 177 180 .L__memset_store\bits: 178 181 \insn %r3,0(%r2)
+29 -32
arch/s390/lib/xor.c
··· 15 15 const unsigned long * __restrict p2) 16 16 { 17 17 asm volatile( 18 - " larl 1,2f\n" 19 18 " aghi %0,-1\n" 20 19 " jm 3f\n" 21 20 " srlg 0,%0,8\n" ··· 24 25 " la %1,256(%1)\n" 25 26 " la %2,256(%2)\n" 26 27 " brctg 0,0b\n" 27 - "1: ex %0,0(1)\n" 28 + "1: exrl %0,2f\n" 28 29 " j 3f\n" 29 30 "2: xc 0(1,%1),0(%2)\n" 30 31 "3:\n" 31 32 : : "d" (bytes), "a" (p1), "a" (p2) 32 - : "0", "1", "cc", "memory"); 33 + : "0", "cc", "memory"); 33 34 } 34 35 35 36 static void xor_xc_3(unsigned long bytes, unsigned long * __restrict p1, ··· 37 38 const unsigned long * __restrict p3) 38 39 { 39 40 asm volatile( 40 - " larl 1,2f\n" 41 41 " aghi %0,-1\n" 42 - " jm 3f\n" 42 + " jm 4f\n" 43 43 " srlg 0,%0,8\n" 44 44 " ltgr 0,0\n" 45 45 " jz 1f\n" ··· 48 50 " la %2,256(%2)\n" 49 51 " la %3,256(%3)\n" 50 52 " brctg 0,0b\n" 51 - "1: ex %0,0(1)\n" 52 - " ex %0,6(1)\n" 53 - " j 3f\n" 53 + "1: exrl %0,2f\n" 54 + " exrl %0,3f\n" 55 + " j 4f\n" 54 56 "2: xc 0(1,%1),0(%2)\n" 55 - " xc 0(1,%1),0(%3)\n" 56 - "3:\n" 57 + "3: xc 0(1,%1),0(%3)\n" 58 + "4:\n" 57 59 : "+d" (bytes), "+a" (p1), "+a" (p2), "+a" (p3) 58 - : : "0", "1", "cc", "memory"); 60 + : : "0", "cc", "memory"); 59 61 } 60 62 61 63 static void xor_xc_4(unsigned long bytes, unsigned long * __restrict p1, ··· 64 66 const unsigned long * __restrict p4) 65 67 { 66 68 asm volatile( 67 - " larl 1,2f\n" 68 69 " aghi %0,-1\n" 69 - " jm 3f\n" 70 + " jm 5f\n" 70 71 " srlg 0,%0,8\n" 71 72 " ltgr 0,0\n" 72 73 " jz 1f\n" ··· 77 80 " la %3,256(%3)\n" 78 81 " la %4,256(%4)\n" 79 82 " brctg 0,0b\n" 80 - "1: ex %0,0(1)\n" 81 - " ex %0,6(1)\n" 82 - " ex %0,12(1)\n" 83 - " j 3f\n" 83 + "1: exrl %0,2f\n" 84 + " exrl %0,3f\n" 85 + " exrl %0,4f\n" 86 + " j 5f\n" 84 87 "2: xc 0(1,%1),0(%2)\n" 85 - " xc 0(1,%1),0(%3)\n" 86 - " xc 0(1,%1),0(%4)\n" 87 - "3:\n" 88 + "3: xc 0(1,%1),0(%3)\n" 89 + "4: xc 0(1,%1),0(%4)\n" 90 + "5:\n" 88 91 : "+d" (bytes), "+a" (p1), "+a" (p2), "+a" (p3), "+a" (p4) 89 - : : "0", "1", "cc", "memory"); 92 + : : "0", "cc", "memory"); 90 93 } 91 94 92 95 static void xor_xc_5(unsigned long bytes, unsigned long * __restrict p1, ··· 98 101 asm volatile( 99 102 " larl 1,2f\n" 100 103 " aghi %0,-1\n" 101 - " jm 3f\n" 104 + " jm 6f\n" 102 105 " srlg 0,%0,8\n" 103 106 " ltgr 0,0\n" 104 107 " jz 1f\n" ··· 112 115 " la %4,256(%4)\n" 113 116 " la %5,256(%5)\n" 114 117 " brctg 0,0b\n" 115 - "1: ex %0,0(1)\n" 116 - " ex %0,6(1)\n" 117 - " ex %0,12(1)\n" 118 - " ex %0,18(1)\n" 119 - " j 3f\n" 118 + "1: exrl %0,2f\n" 119 + " exrl %0,3f\n" 120 + " exrl %0,4f\n" 121 + " exrl %0,5f\n" 122 + " j 6f\n" 120 123 "2: xc 0(1,%1),0(%2)\n" 121 - " xc 0(1,%1),0(%3)\n" 122 - " xc 0(1,%1),0(%4)\n" 123 - " xc 0(1,%1),0(%5)\n" 124 - "3:\n" 124 + "3: xc 0(1,%1),0(%3)\n" 125 + "4: xc 0(1,%1),0(%4)\n" 126 + "5: xc 0(1,%1),0(%5)\n" 127 + "6:\n" 125 128 : "+d" (bytes), "+a" (p1), "+a" (p2), "+a" (p3), "+a" (p4), 126 129 "+a" (p5) 127 - : : "0", "1", "cc", "memory"); 130 + : : "0", "cc", "memory"); 128 131 } 129 132 130 133 struct xor_block_template xor_block_xc = {
+9
arch/s390/mm/init.c
··· 56 56 57 57 struct ctlreg __bootdata_preserved(s390_invalid_asce); 58 58 59 + unsigned long __bootdata_preserved(page_noexec_mask); 60 + EXPORT_SYMBOL(page_noexec_mask); 61 + 62 + unsigned long __bootdata_preserved(segment_noexec_mask); 63 + EXPORT_SYMBOL(segment_noexec_mask); 64 + 65 + unsigned long __bootdata_preserved(region_noexec_mask); 66 + EXPORT_SYMBOL(region_noexec_mask); 67 + 59 68 unsigned long empty_zero_page, zero_page_mask; 60 69 EXPORT_SYMBOL(empty_zero_page); 61 70 EXPORT_SYMBOL(zero_page_mask);
+1
arch/s390/mm/maccess.c
··· 17 17 #include <asm/asm-extable.h> 18 18 #include <asm/abs_lowcore.h> 19 19 #include <asm/stacktrace.h> 20 + #include <asm/sections.h> 20 21 #include <asm/maccess.h> 21 22 #include <asm/ctlreg.h> 22 23
+24 -18
arch/s390/mm/mmap.c
··· 196 196 } 197 197 } 198 198 199 - static const pgprot_t protection_map[16] = { 200 - [VM_NONE] = PAGE_NONE, 201 - [VM_READ] = PAGE_RO, 202 - [VM_WRITE] = PAGE_RO, 203 - [VM_WRITE | VM_READ] = PAGE_RO, 204 - [VM_EXEC] = PAGE_RX, 205 - [VM_EXEC | VM_READ] = PAGE_RX, 206 - [VM_EXEC | VM_WRITE] = PAGE_RX, 207 - [VM_EXEC | VM_WRITE | VM_READ] = PAGE_RX, 208 - [VM_SHARED] = PAGE_NONE, 209 - [VM_SHARED | VM_READ] = PAGE_RO, 210 - [VM_SHARED | VM_WRITE] = PAGE_RW, 211 - [VM_SHARED | VM_WRITE | VM_READ] = PAGE_RW, 212 - [VM_SHARED | VM_EXEC] = PAGE_RX, 213 - [VM_SHARED | VM_EXEC | VM_READ] = PAGE_RX, 214 - [VM_SHARED | VM_EXEC | VM_WRITE] = PAGE_RWX, 215 - [VM_SHARED | VM_EXEC | VM_WRITE | VM_READ] = PAGE_RWX 216 - }; 199 + static pgprot_t protection_map[16] __ro_after_init; 200 + 201 + void __init setup_protection_map(void) 202 + { 203 + pgprot_t *pm = protection_map; 204 + 205 + pm[VM_NONE] = PAGE_NONE; 206 + pm[VM_READ] = PAGE_RO; 207 + pm[VM_WRITE] = PAGE_RO; 208 + pm[VM_WRITE | VM_READ] = PAGE_RO; 209 + pm[VM_EXEC] = PAGE_RX; 210 + pm[VM_EXEC | VM_READ] = PAGE_RX; 211 + pm[VM_EXEC | VM_WRITE] = PAGE_RX; 212 + pm[VM_EXEC | VM_WRITE | VM_READ] = PAGE_RX; 213 + pm[VM_SHARED] = PAGE_NONE; 214 + pm[VM_SHARED | VM_READ] = PAGE_RO; 215 + pm[VM_SHARED | VM_WRITE] = PAGE_RW; 216 + pm[VM_SHARED | VM_WRITE | VM_READ] = PAGE_RW; 217 + pm[VM_SHARED | VM_EXEC] = PAGE_RX; 218 + pm[VM_SHARED | VM_EXEC | VM_READ] = PAGE_RX; 219 + pm[VM_SHARED | VM_EXEC | VM_WRITE] = PAGE_RWX; 220 + pm[VM_SHARED | VM_EXEC | VM_WRITE | VM_READ] = PAGE_RWX; 221 + } 222 + 217 223 DECLARE_VM_GET_PAGE_PROT
-6
arch/s390/mm/pageattr.c
··· 109 109 } else if (flags & SET_MEMORY_DEF) { 110 110 new = __pte(pte_val(new) & PAGE_MASK); 111 111 new = set_pte_bit(new, PAGE_KERNEL); 112 - if (!MACHINE_HAS_NX) 113 - new = clear_pte_bit(new, __pgprot(_PAGE_NOEXEC)); 114 112 } 115 113 pgt_set((unsigned long *)ptep, pte_val(new), addr, CRDTE_DTT_PAGE); 116 114 ptep++; ··· 165 167 } else if (flags & SET_MEMORY_DEF) { 166 168 new = __pmd(pmd_val(new) & PMD_MASK); 167 169 new = set_pmd_bit(new, SEGMENT_KERNEL); 168 - if (!MACHINE_HAS_NX) 169 - new = clear_pmd_bit(new, __pgprot(_SEGMENT_ENTRY_NOEXEC)); 170 170 } 171 171 pgt_set((unsigned long *)pmdp, pmd_val(new), addr, CRDTE_DTT_SEGMENT); 172 172 } ··· 252 256 } else if (flags & SET_MEMORY_DEF) { 253 257 new = __pud(pud_val(new) & PUD_MASK); 254 258 new = set_pud_bit(new, REGION3_KERNEL); 255 - if (!MACHINE_HAS_NX) 256 - new = clear_pud_bit(new, __pgprot(_REGION_ENTRY_NOEXEC)); 257 259 } 258 260 pgt_set((unsigned long *)pudp, pud_val(new), addr, CRDTE_DTT_REGION3); 259 261 }
-2
arch/s390/mm/pgtable.c
··· 360 360 pgste_t pgste; 361 361 struct mm_struct *mm = vma->vm_mm; 362 362 363 - if (!MACHINE_HAS_NX) 364 - pte = clear_pte_bit(pte, __pgprot(_PAGE_NOEXEC)); 365 363 if (mm_has_pgste(mm)) { 366 364 pgste = pgste_get(ptep); 367 365 pgste_set_key(ptep, pgste, pte, mm);
-8
arch/s390/mm/vmem.c
··· 171 171 pte_t *pte; 172 172 173 173 prot = pgprot_val(PAGE_KERNEL); 174 - if (!MACHINE_HAS_NX) 175 - prot &= ~_PAGE_NOEXEC; 176 - 177 174 pte = pte_offset_kernel(pmd, addr); 178 175 for (; addr < end; addr += PAGE_SIZE, pte++) { 179 176 if (!add) { ··· 227 230 pte_t *pte; 228 231 229 232 prot = pgprot_val(SEGMENT_KERNEL); 230 - if (!MACHINE_HAS_NX) 231 - prot &= ~_SEGMENT_ENTRY_NOEXEC; 232 - 233 233 pmd = pmd_offset(pud, addr); 234 234 for (; addr < end; addr = next, pmd++) { 235 235 next = pmd_addr_end(addr, end); ··· 318 324 pmd_t *pmd; 319 325 320 326 prot = pgprot_val(REGION3_KERNEL); 321 - if (!MACHINE_HAS_NX) 322 - prot &= ~_REGION_ENTRY_NOEXEC; 323 327 pud = pud_offset(p4d, addr); 324 328 for (; addr < end; addr = next, pud++) { 325 329 next = pud_addr_end(addr, end);
+1 -1
arch/s390/pci/Makefile
··· 5 5 6 6 obj-$(CONFIG_PCI) += pci.o pci_irq.o pci_clp.o \ 7 7 pci_event.o pci_debug.o pci_insn.o pci_mmio.o \ 8 - pci_bus.o pci_kvm_hook.o 8 + pci_bus.o pci_kvm_hook.o pci_report.o 9 9 obj-$(CONFIG_PCI_IOV) += pci_iov.o 10 10 obj-$(CONFIG_SYSFS) += pci_sysfs.o
+17 -4
arch/s390/pci/pci_event.c
··· 16 16 #include <asm/sclp.h> 17 17 18 18 #include "pci_bus.h" 19 + #include "pci_report.h" 19 20 20 21 /* Content Code Description for PCI Function Error */ 21 22 struct zpci_ccdf_err { ··· 170 169 static pci_ers_result_t zpci_event_attempt_error_recovery(struct pci_dev *pdev) 171 170 { 172 171 pci_ers_result_t ers_res = PCI_ERS_RESULT_DISCONNECT; 172 + struct zpci_dev *zdev = to_zpci(pdev); 173 + char *status_str = "success"; 173 174 struct pci_driver *driver; 174 175 175 176 /* ··· 189 186 if (is_passed_through(pdev)) { 190 187 pr_info("%s: Cannot be recovered in the host because it is a pass-through device\n", 191 188 pci_name(pdev)); 189 + status_str = "failed (pass-through)"; 192 190 goto out_unlock; 193 191 } 194 192 195 193 driver = to_pci_driver(pdev->dev.driver); 196 194 if (!is_driver_supported(driver)) { 197 - if (!driver) 195 + if (!driver) { 198 196 pr_info("%s: Cannot be recovered because no driver is bound to the device\n", 199 197 pci_name(pdev)); 200 - else 198 + status_str = "failed (no driver)"; 199 + } else { 201 200 pr_info("%s: The %s driver bound to the device does not support error recovery\n", 202 201 pci_name(pdev), 203 202 driver->name); 203 + status_str = "failed (no driver support)"; 204 + } 204 205 goto out_unlock; 205 206 } 206 207 207 208 ers_res = zpci_event_notify_error_detected(pdev, driver); 208 - if (ers_result_indicates_abort(ers_res)) 209 + if (ers_result_indicates_abort(ers_res)) { 210 + status_str = "failed (abort on detection)"; 209 211 goto out_unlock; 212 + } 210 213 211 214 if (ers_res == PCI_ERS_RESULT_CAN_RECOVER) { 212 215 ers_res = zpci_event_do_error_state_clear(pdev, driver); 213 - if (ers_result_indicates_abort(ers_res)) 216 + if (ers_result_indicates_abort(ers_res)) { 217 + status_str = "failed (abort on MMIO enable)"; 214 218 goto out_unlock; 219 + } 215 220 } 216 221 217 222 if (ers_res == PCI_ERS_RESULT_NEED_RESET) ··· 228 217 if (ers_res != PCI_ERS_RESULT_RECOVERED) { 229 218 pr_err("%s: Automatic recovery failed; operator intervention is required\n", 230 219 pci_name(pdev)); 220 + status_str = "failed (driver can't recover)"; 231 221 goto out_unlock; 232 222 } 233 223 ··· 237 225 driver->err_handler->resume(pdev); 238 226 out_unlock: 239 227 pci_dev_unlock(pdev); 228 + zpci_report_status(zdev, "recovery", status_str); 240 229 241 230 return ers_res; 242 231 }
+158
arch/s390/pci/pci_report.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright IBM Corp. 2024 4 + * 5 + * Author(s): 6 + * Niklas Schnelle <schnelle@linux.ibm.com> 7 + * 8 + */ 9 + 10 + #define KMSG_COMPONENT "zpci" 11 + #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 12 + 13 + #include <linux/kernel.h> 14 + #include <linux/sprintf.h> 15 + #include <linux/pci.h> 16 + 17 + #include <asm/sclp.h> 18 + #include <asm/debug.h> 19 + #include <asm/pci_debug.h> 20 + 21 + #include "pci_report.h" 22 + 23 + #define ZPCI_ERR_LOG_ID_KERNEL_REPORT 0x4714 24 + 25 + struct zpci_report_error_data { 26 + u64 timestamp; 27 + u64 err_log_id; 28 + char log_data[]; 29 + } __packed; 30 + 31 + #define ZPCI_REPORT_SIZE (PAGE_SIZE - sizeof(struct err_notify_sccb)) 32 + #define ZPCI_REPORT_DATA_SIZE (ZPCI_REPORT_SIZE - sizeof(struct zpci_report_error_data)) 33 + 34 + struct zpci_report_error { 35 + struct zpci_report_error_header header; 36 + struct zpci_report_error_data data; 37 + } __packed; 38 + 39 + static const char *zpci_state_str(pci_channel_state_t state) 40 + { 41 + switch (state) { 42 + case pci_channel_io_normal: 43 + return "normal"; 44 + case pci_channel_io_frozen: 45 + return "frozen"; 46 + case pci_channel_io_perm_failure: 47 + return "permanent-failure"; 48 + default: 49 + return "invalid"; 50 + }; 51 + } 52 + 53 + static int debug_log_header_fn(debug_info_t *id, struct debug_view *view, 54 + int area, debug_entry_t *entry, char *out_buf, 55 + size_t out_buf_size) 56 + { 57 + unsigned long sec, usec; 58 + unsigned int level; 59 + char *except_str; 60 + int rc = 0; 61 + 62 + level = entry->level; 63 + sec = entry->clock; 64 + usec = do_div(sec, USEC_PER_SEC); 65 + 66 + if (entry->exception) 67 + except_str = "*"; 68 + else 69 + except_str = "-"; 70 + rc += scnprintf(out_buf, out_buf_size, "%011ld:%06lu %1u %1s %04u ", 71 + sec, usec, level, except_str, 72 + entry->cpu); 73 + return rc; 74 + } 75 + 76 + static int debug_prolog_header(debug_info_t *id, struct debug_view *view, 77 + char *out_buf, size_t out_buf_size) 78 + { 79 + return scnprintf(out_buf, out_buf_size, "sec:usec level except cpu msg\n"); 80 + } 81 + 82 + static struct debug_view debug_log_view = { 83 + "pci_msg_log", 84 + &debug_prolog_header, 85 + &debug_log_header_fn, 86 + &debug_sprintf_format_fn, 87 + NULL, 88 + NULL 89 + }; 90 + 91 + /** 92 + * zpci_report_status - Report the status of operations on a PCI device 93 + * @zdev: The PCI device for which to report status 94 + * @operation: A string representing the operation reported 95 + * @status: A string representing the status of the operation 96 + * 97 + * This function creates a human readable report about an operation such as 98 + * PCI device recovery and forwards this to the platform using the SCLP Write 99 + * Event Data mechanism. Besides the operation and status strings the report 100 + * also contains additional information about the device deemed useful for 101 + * debug such as the currently bound device driver, if any, and error state. 102 + * Additionally a string representation of pci_debug_msg_id, or as much as fits, 103 + * is also included. 104 + * 105 + * Return: 0 on success an error code < 0 otherwise. 106 + */ 107 + int zpci_report_status(struct zpci_dev *zdev, const char *operation, const char *status) 108 + { 109 + struct zpci_report_error *report; 110 + struct pci_driver *driver = NULL; 111 + struct pci_dev *pdev = NULL; 112 + char *buf, *end; 113 + int ret; 114 + 115 + if (!zdev || !zdev->zbus) 116 + return -ENODEV; 117 + 118 + /* Protected virtualization hosts get nothing from us */ 119 + if (prot_virt_guest) 120 + return -ENODATA; 121 + 122 + report = (void *)get_zeroed_page(GFP_KERNEL); 123 + if (!report) 124 + return -ENOMEM; 125 + if (zdev->zbus->bus) 126 + pdev = pci_get_slot(zdev->zbus->bus, zdev->devfn); 127 + if (pdev) 128 + driver = to_pci_driver(pdev->dev.driver); 129 + 130 + buf = report->data.log_data; 131 + end = report->data.log_data + ZPCI_REPORT_DATA_SIZE; 132 + buf += scnprintf(buf, end - buf, "report: %s\n", operation); 133 + buf += scnprintf(buf, end - buf, "status: %s\n", status); 134 + buf += scnprintf(buf, end - buf, "state: %s\n", 135 + (pdev) ? zpci_state_str(pdev->error_state) : "n/a"); 136 + buf += scnprintf(buf, end - buf, "driver: %s\n", (driver) ? driver->name : "n/a"); 137 + ret = debug_dump(pci_debug_msg_id, &debug_log_view, buf, end - buf, true); 138 + if (ret < 0) 139 + pr_err("Reading PCI debug messages failed with code %d\n", ret); 140 + else 141 + buf += ret; 142 + 143 + report->header.version = 1; 144 + report->header.action = SCLP_ERRNOTIFY_AQ_INFO_LOG; 145 + report->header.length = buf - (char *)&report->data; 146 + report->data.timestamp = ktime_get_clocktai_seconds(); 147 + report->data.err_log_id = ZPCI_ERR_LOG_ID_KERNEL_REPORT; 148 + 149 + ret = sclp_pci_report(&report->header, zdev->fh, zdev->fid); 150 + if (ret) 151 + pr_err("Reporting PCI status failed with code %d\n", ret); 152 + else 153 + pr_info("Reported PCI device status\n"); 154 + 155 + free_page((unsigned long)report); 156 + 157 + return ret; 158 + }
+16
arch/s390/pci/pci_report.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright IBM Corp. 2024 4 + * 5 + * Author(s): 6 + * Niklas Schnelle <schnelle@linux.ibm.com> 7 + * 8 + */ 9 + #ifndef __S390_PCI_REPORT_H 10 + #define __S390_PCI_REPORT_H 11 + 12 + struct zpci_dev; 13 + 14 + int zpci_report_status(struct zpci_dev *zdev, const char *operation, const char *status); 15 + 16 + #endif /* __S390_PCI_REPORT_H */
+6 -6
arch/s390/pci/pci_sysfs.c
··· 135 135 static DEVICE_ATTR_WO(recover); 136 136 137 137 static ssize_t util_string_read(struct file *filp, struct kobject *kobj, 138 - struct bin_attribute *attr, char *buf, 138 + const struct bin_attribute *attr, char *buf, 139 139 loff_t off, size_t count) 140 140 { 141 141 struct device *dev = kobj_to_dev(kobj); ··· 145 145 return memory_read_from_buffer(buf, count, &off, zdev->util_str, 146 146 sizeof(zdev->util_str)); 147 147 } 148 - static BIN_ATTR_RO(util_string, CLP_UTIL_STR_LEN); 148 + static const BIN_ATTR_RO(util_string, CLP_UTIL_STR_LEN); 149 149 150 150 static ssize_t report_error_write(struct file *filp, struct kobject *kobj, 151 - struct bin_attribute *attr, char *buf, 151 + const struct bin_attribute *attr, char *buf, 152 152 loff_t off, size_t count) 153 153 { 154 154 struct zpci_report_error_header *report = (void *) buf; ··· 164 164 165 165 return ret ? ret : count; 166 166 } 167 - static BIN_ATTR(report_error, S_IWUSR, NULL, report_error_write, PAGE_SIZE); 167 + static const BIN_ATTR(report_error, S_IWUSR, NULL, report_error_write, PAGE_SIZE); 168 168 169 169 static ssize_t uid_is_unique_show(struct device *dev, 170 170 struct device_attribute *attr, char *buf) ··· 203 203 .is_visible = zpci_index_is_visible, 204 204 }; 205 205 206 - static struct bin_attribute *zpci_bin_attrs[] = { 206 + static const struct bin_attribute *const zpci_bin_attrs[] = { 207 207 &bin_attr_util_string, 208 208 &bin_attr_report_error, 209 209 NULL, ··· 227 227 228 228 const struct attribute_group zpci_attr_group = { 229 229 .attrs = zpci_dev_attrs, 230 - .bin_attrs = zpci_bin_attrs, 230 + .bin_attrs_new = zpci_bin_attrs, 231 231 }; 232 232 233 233 static struct attribute *pfip_attrs[] = {
+3 -15
drivers/s390/char/sclp.h
··· 85 85 86 86 typedef u64 sccb_mask_t; 87 87 88 - struct sccb_header { 89 - u16 length; 90 - u8 function_code; 91 - u8 control_mask[3]; 92 - u16 response_code; 93 - } __attribute__((packed)); 94 - 95 88 struct init_sccb { 96 89 struct sccb_header header; 97 90 u16 _reserved; ··· 189 196 u8 byte_134; /* 134 */ 190 197 u8 cpudirq; /* 135 */ 191 198 u16 cbl; /* 136-137 */ 192 - u8 _pad_138[EXT_SCCB_READ_SCP - 138]; 199 + u8 byte_138; /* 138 */ 200 + u8 byte_139; /* 139 */ 201 + u8 _pad_140[EXT_SCCB_READ_SCP - 140]; 193 202 } __packed __aligned(PAGE_SIZE); 194 203 195 204 struct read_storage_sccb { ··· 231 236 struct gds_vector { 232 237 u16 length; 233 238 u16 gds_id; 234 - } __attribute__((packed)); 235 - 236 - struct evbuf_header { 237 - u16 length; 238 - u8 type; 239 - u8 flags; 240 - u16 _reserved; 241 239 } __attribute__((packed)); 242 240 243 241 struct sclp_req {
+2 -2
drivers/s390/char/sclp_config.c
··· 128 128 } 129 129 130 130 static ssize_t sysfs_ofb_data_write(struct file *filp, struct kobject *kobj, 131 - struct bin_attribute *bin_attr, 131 + const struct bin_attribute *bin_attr, 132 132 char *buf, loff_t off, size_t count) 133 133 { 134 134 int rc; ··· 142 142 .name = "event_data", 143 143 .mode = S_IWUSR, 144 144 }, 145 - .write = sysfs_ofb_data_write, 145 + .write_new = sysfs_ofb_data_write, 146 146 }; 147 147 #endif 148 148
+3
drivers/s390/char/sclp_early.c
··· 55 55 if (sccb->fac91 & 0x40) 56 56 get_lowcore()->machine_flags |= MACHINE_FLAG_TLB_GUEST; 57 57 sclp.has_diag204_bif = !!(sccb->fac98 & 0x80); 58 + sclp.has_diag310 = !!(sccb->fac91 & 0x80); 58 59 if (sccb->cpuoff > 134) { 59 60 sclp.has_diag318 = !!(sccb->byte_134 & 0x80); 60 61 sclp.has_diag320 = !!(sccb->byte_134 & 0x04); ··· 65 64 sclp.has_sipl = !!(sccb->cbl & 0x4000); 66 65 sclp.has_sipl_eckd = !!(sccb->cbl & 0x2000); 67 66 } 67 + if (sccb->cpuoff > 139) 68 + sclp.has_diag324 = !!(sccb->byte_139 & 0x80); 68 69 sclp.rnmax = sccb->rnmax ? sccb->rnmax : sccb->rnmax2; 69 70 sclp.rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2; 70 71 sclp.rzm <<= 20;
-19
drivers/s390/char/sclp_pci.c
··· 24 24 25 25 #define SCLP_ATYPE_PCI 2 26 26 27 - #define SCLP_ERRNOTIFY_AQ_RESET 0 28 - #define SCLP_ERRNOTIFY_AQ_REPAIR 1 29 - #define SCLP_ERRNOTIFY_AQ_INFO_LOG 2 30 - #define SCLP_ERRNOTIFY_AQ_OPTICS_DATA 3 31 - 32 27 static DEFINE_MUTEX(sclp_pci_mutex); 33 28 static struct sclp_register sclp_pci_event = { 34 29 .send_mask = EVTYP_ERRNOTIFY_MASK, 35 30 }; 36 - 37 - struct err_notify_evbuf { 38 - struct evbuf_header header; 39 - u8 action; 40 - u8 atype; 41 - u32 fh; 42 - u32 fid; 43 - u8 data[]; 44 - } __packed; 45 - 46 - struct err_notify_sccb { 47 - struct sccb_header header; 48 - struct err_notify_evbuf evbuf; 49 - } __packed; 50 31 51 32 struct pci_cfg_sccb { 52 33 struct sccb_header header;
+2 -2
drivers/s390/char/sclp_sd.c
··· 476 476 * on EOF. 477 477 */ 478 478 static ssize_t data_read(struct file *file, struct kobject *kobj, 479 - struct bin_attribute *attr, char *buffer, 479 + const struct bin_attribute *attr, char *buffer, 480 480 loff_t off, size_t size) 481 481 { 482 482 struct sclp_sd_file *sd_file = to_sd_file(kobj); ··· 539 539 sysfs_bin_attr_init(&sd_file->data_attr); 540 540 sd_file->data_attr.attr.name = "data"; 541 541 sd_file->data_attr.attr.mode = 0444; 542 - sd_file->data_attr.read = data_read; 542 + sd_file->data_attr.read_new = data_read; 543 543 544 544 rc = sysfs_create_bin_file(&sd_file->kobj, &sd_file->data_attr); 545 545 if (rc) {
+1 -1
drivers/s390/cio/device_ops.c
··· 445 445 return NULL; 446 446 for (ciw_cnt = 0; ciw_cnt < MAX_CIWS; ciw_cnt++) 447 447 if (cdev->private->dma_area->senseid.ciw[ciw_cnt].ct == ct) 448 - return cdev->private->dma_area->senseid.ciw + ciw_cnt; 448 + return &cdev->private->dma_area->senseid.ciw[ciw_cnt]; 449 449 return NULL; 450 450 } 451 451
+4 -5
drivers/s390/cio/qdio.h
··· 210 210 qdio_handler_t (*handler); 211 211 212 212 struct qdio_irq *irq_ptr; 213 + 214 + /* memory page (PAGE_SIZE) used to place slib and sl on */ 215 + void *sl_page; 213 216 struct sl *sl; 214 - /* 215 - * A page is allocated under this pointer and used for slib and sl. 216 - * slib is 2048 bytes big and sl points to offset PAGE_SIZE / 2. 217 - */ 218 217 struct slib *slib; 219 218 } __attribute__ ((aligned(256))); 220 219 ··· 265 266 266 267 #define is_thinint_irq(irq) \ 267 268 (irq->qib.qfmt == QDIO_IQDIO_QFMT || \ 268 - css_general_characteristics.aif_osa) 269 + css_general_characteristics.aif_qdio) 269 270 270 271 #define qperf(__qdev, __attr) ((__qdev)->perf_stat.(__attr)) 271 272
+14 -7
drivers/s390/cio/qdio_setup.c
··· 83 83 84 84 for (i = 0; i < count; i++) { 85 85 q = queues[i]; 86 - free_page((unsigned long) q->slib); 86 + free_page((unsigned long)q->sl_page); 87 87 kmem_cache_free(qdio_q_cache, q); 88 88 } 89 89 } ··· 109 109 return -ENOMEM; 110 110 } 111 111 112 - q->slib = (struct slib *) __get_free_page(GFP_KERNEL); 113 - if (!q->slib) { 112 + q->sl_page = (void *)__get_free_page(GFP_KERNEL); 113 + if (!q->sl_page) { 114 114 kmem_cache_free(qdio_q_cache, q); 115 115 __qdio_free_queues(irq_ptr_qs, i); 116 116 return -ENOMEM; 117 117 } 118 + q->slib = q->sl_page; 119 + /* As per architecture: SLIB is 2K bytes long, and SL 1K. */ 120 + q->sl = (struct sl *)(q->slib + 1); 121 + 118 122 irq_ptr_qs[i] = q; 119 123 } 120 124 return 0; ··· 146 142 static void setup_queues_misc(struct qdio_q *q, struct qdio_irq *irq_ptr, 147 143 qdio_handler_t *handler, int i) 148 144 { 149 - struct slib *slib = q->slib; 145 + struct slib *const slib = q->slib; 146 + void *const sl_page = q->sl_page; 147 + struct sl *const sl = q->sl; 150 148 151 149 /* queue must be cleared for qdio_establish */ 152 150 memset(q, 0, sizeof(*q)); 153 - memset(slib, 0, PAGE_SIZE); 151 + memset(sl_page, 0, PAGE_SIZE); 152 + q->sl_page = sl_page; 153 + q->sl = sl; 154 154 q->slib = slib; 155 155 q->irq_ptr = irq_ptr; 156 156 q->mask = 1 << (31 - i); ··· 169 161 int j; 170 162 171 163 DBF_HEX(&q, sizeof(void *)); 172 - q->sl = (struct sl *)((char *)q->slib + PAGE_SIZE / 2); 173 164 174 165 /* fill in sbal */ 175 166 for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++) ··· 430 423 431 424 /* Check for OSA/FCP thin interrupts (bit 67). */ 432 425 DBF_EVENT("thinint:%1d", 433 - (css_general_characteristics.aif_osa) ? 1 : 0); 426 + (css_general_characteristics.aif_qdio) ? 1 : 0); 434 427 435 428 /* Check for QEBSM support in general (bit 58). */ 436 429 DBF_EVENT("cssQEBSM:%1d", css_general_characteristics.qebsm);
+63 -63
drivers/s390/crypto/pkey_sysfs.c
··· 184 184 185 185 static ssize_t protkey_aes_128_read(struct file *filp, 186 186 struct kobject *kobj, 187 - struct bin_attribute *attr, 187 + const struct bin_attribute *attr, 188 188 char *buf, loff_t off, 189 189 size_t count) 190 190 { ··· 194 194 195 195 static ssize_t protkey_aes_192_read(struct file *filp, 196 196 struct kobject *kobj, 197 - struct bin_attribute *attr, 197 + const struct bin_attribute *attr, 198 198 char *buf, loff_t off, 199 199 size_t count) 200 200 { ··· 204 204 205 205 static ssize_t protkey_aes_256_read(struct file *filp, 206 206 struct kobject *kobj, 207 - struct bin_attribute *attr, 207 + const struct bin_attribute *attr, 208 208 char *buf, loff_t off, 209 209 size_t count) 210 210 { ··· 214 214 215 215 static ssize_t protkey_aes_128_xts_read(struct file *filp, 216 216 struct kobject *kobj, 217 - struct bin_attribute *attr, 217 + const struct bin_attribute *attr, 218 218 char *buf, loff_t off, 219 219 size_t count) 220 220 { ··· 224 224 225 225 static ssize_t protkey_aes_256_xts_read(struct file *filp, 226 226 struct kobject *kobj, 227 - struct bin_attribute *attr, 227 + const struct bin_attribute *attr, 228 228 char *buf, loff_t off, 229 229 size_t count) 230 230 { ··· 234 234 235 235 static ssize_t protkey_aes_xts_128_read(struct file *filp, 236 236 struct kobject *kobj, 237 - struct bin_attribute *attr, 237 + const struct bin_attribute *attr, 238 238 char *buf, loff_t off, 239 239 size_t count) 240 240 { ··· 244 244 245 245 static ssize_t protkey_aes_xts_256_read(struct file *filp, 246 246 struct kobject *kobj, 247 - struct bin_attribute *attr, 247 + const struct bin_attribute *attr, 248 248 char *buf, loff_t off, 249 249 size_t count) 250 250 { ··· 254 254 255 255 static ssize_t protkey_hmac_512_read(struct file *filp, 256 256 struct kobject *kobj, 257 - struct bin_attribute *attr, 257 + const struct bin_attribute *attr, 258 258 char *buf, loff_t off, 259 259 size_t count) 260 260 { ··· 264 264 265 265 static ssize_t protkey_hmac_1024_read(struct file *filp, 266 266 struct kobject *kobj, 267 - struct bin_attribute *attr, 267 + const struct bin_attribute *attr, 268 268 char *buf, loff_t off, 269 269 size_t count) 270 270 { ··· 272 272 buf, off, count); 273 273 } 274 274 275 - static BIN_ATTR_RO(protkey_aes_128, sizeof(struct protaeskeytoken)); 276 - static BIN_ATTR_RO(protkey_aes_192, sizeof(struct protaeskeytoken)); 277 - static BIN_ATTR_RO(protkey_aes_256, sizeof(struct protaeskeytoken)); 278 - static BIN_ATTR_RO(protkey_aes_128_xts, 2 * sizeof(struct protaeskeytoken)); 279 - static BIN_ATTR_RO(protkey_aes_256_xts, 2 * sizeof(struct protaeskeytoken)); 280 - static BIN_ATTR_RO(protkey_aes_xts_128, sizeof(struct protkeytoken) + 64); 281 - static BIN_ATTR_RO(protkey_aes_xts_256, sizeof(struct protkeytoken) + 96); 282 - static BIN_ATTR_RO(protkey_hmac_512, sizeof(struct protkeytoken) + 96); 283 - static BIN_ATTR_RO(protkey_hmac_1024, sizeof(struct protkeytoken) + 160); 275 + static const BIN_ATTR_RO(protkey_aes_128, sizeof(struct protaeskeytoken)); 276 + static const BIN_ATTR_RO(protkey_aes_192, sizeof(struct protaeskeytoken)); 277 + static const BIN_ATTR_RO(protkey_aes_256, sizeof(struct protaeskeytoken)); 278 + static const BIN_ATTR_RO(protkey_aes_128_xts, 2 * sizeof(struct protaeskeytoken)); 279 + static const BIN_ATTR_RO(protkey_aes_256_xts, 2 * sizeof(struct protaeskeytoken)); 280 + static const BIN_ATTR_RO(protkey_aes_xts_128, sizeof(struct protkeytoken) + 64); 281 + static const BIN_ATTR_RO(protkey_aes_xts_256, sizeof(struct protkeytoken) + 96); 282 + static const BIN_ATTR_RO(protkey_hmac_512, sizeof(struct protkeytoken) + 96); 283 + static const BIN_ATTR_RO(protkey_hmac_1024, sizeof(struct protkeytoken) + 160); 284 284 285 - static struct bin_attribute *protkey_attrs[] = { 285 + static const struct bin_attribute *const protkey_attrs[] = { 286 286 &bin_attr_protkey_aes_128, 287 287 &bin_attr_protkey_aes_192, 288 288 &bin_attr_protkey_aes_256, ··· 295 295 NULL 296 296 }; 297 297 298 - static struct attribute_group protkey_attr_group = { 299 - .name = "protkey", 300 - .bin_attrs = protkey_attrs, 298 + static const struct attribute_group protkey_attr_group = { 299 + .name = "protkey", 300 + .bin_attrs_new = protkey_attrs, 301 301 }; 302 302 303 303 /* ··· 341 341 342 342 static ssize_t ccadata_aes_128_read(struct file *filp, 343 343 struct kobject *kobj, 344 - struct bin_attribute *attr, 344 + const struct bin_attribute *attr, 345 345 char *buf, loff_t off, 346 346 size_t count) 347 347 { ··· 351 351 352 352 static ssize_t ccadata_aes_192_read(struct file *filp, 353 353 struct kobject *kobj, 354 - struct bin_attribute *attr, 354 + const struct bin_attribute *attr, 355 355 char *buf, loff_t off, 356 356 size_t count) 357 357 { ··· 361 361 362 362 static ssize_t ccadata_aes_256_read(struct file *filp, 363 363 struct kobject *kobj, 364 - struct bin_attribute *attr, 364 + const struct bin_attribute *attr, 365 365 char *buf, loff_t off, 366 366 size_t count) 367 367 { ··· 371 371 372 372 static ssize_t ccadata_aes_128_xts_read(struct file *filp, 373 373 struct kobject *kobj, 374 - struct bin_attribute *attr, 374 + const struct bin_attribute *attr, 375 375 char *buf, loff_t off, 376 376 size_t count) 377 377 { ··· 381 381 382 382 static ssize_t ccadata_aes_256_xts_read(struct file *filp, 383 383 struct kobject *kobj, 384 - struct bin_attribute *attr, 384 + const struct bin_attribute *attr, 385 385 char *buf, loff_t off, 386 386 size_t count) 387 387 { ··· 389 389 off, count); 390 390 } 391 391 392 - static BIN_ATTR_RO(ccadata_aes_128, sizeof(struct secaeskeytoken)); 393 - static BIN_ATTR_RO(ccadata_aes_192, sizeof(struct secaeskeytoken)); 394 - static BIN_ATTR_RO(ccadata_aes_256, sizeof(struct secaeskeytoken)); 395 - static BIN_ATTR_RO(ccadata_aes_128_xts, 2 * sizeof(struct secaeskeytoken)); 396 - static BIN_ATTR_RO(ccadata_aes_256_xts, 2 * sizeof(struct secaeskeytoken)); 392 + static const BIN_ATTR_RO(ccadata_aes_128, sizeof(struct secaeskeytoken)); 393 + static const BIN_ATTR_RO(ccadata_aes_192, sizeof(struct secaeskeytoken)); 394 + static const BIN_ATTR_RO(ccadata_aes_256, sizeof(struct secaeskeytoken)); 395 + static const BIN_ATTR_RO(ccadata_aes_128_xts, 2 * sizeof(struct secaeskeytoken)); 396 + static const BIN_ATTR_RO(ccadata_aes_256_xts, 2 * sizeof(struct secaeskeytoken)); 397 397 398 - static struct bin_attribute *ccadata_attrs[] = { 398 + static const struct bin_attribute *const ccadata_attrs[] = { 399 399 &bin_attr_ccadata_aes_128, 400 400 &bin_attr_ccadata_aes_192, 401 401 &bin_attr_ccadata_aes_256, ··· 404 404 NULL 405 405 }; 406 406 407 - static struct attribute_group ccadata_attr_group = { 408 - .name = "ccadata", 409 - .bin_attrs = ccadata_attrs, 407 + static const struct attribute_group ccadata_attr_group = { 408 + .name = "ccadata", 409 + .bin_attrs_new = ccadata_attrs, 410 410 }; 411 411 412 412 #define CCACIPHERTOKENSIZE (sizeof(struct cipherkeytoken) + 80) ··· 455 455 456 456 static ssize_t ccacipher_aes_128_read(struct file *filp, 457 457 struct kobject *kobj, 458 - struct bin_attribute *attr, 458 + const struct bin_attribute *attr, 459 459 char *buf, loff_t off, 460 460 size_t count) 461 461 { ··· 465 465 466 466 static ssize_t ccacipher_aes_192_read(struct file *filp, 467 467 struct kobject *kobj, 468 - struct bin_attribute *attr, 468 + const struct bin_attribute *attr, 469 469 char *buf, loff_t off, 470 470 size_t count) 471 471 { ··· 475 475 476 476 static ssize_t ccacipher_aes_256_read(struct file *filp, 477 477 struct kobject *kobj, 478 - struct bin_attribute *attr, 478 + const struct bin_attribute *attr, 479 479 char *buf, loff_t off, 480 480 size_t count) 481 481 { ··· 485 485 486 486 static ssize_t ccacipher_aes_128_xts_read(struct file *filp, 487 487 struct kobject *kobj, 488 - struct bin_attribute *attr, 488 + const struct bin_attribute *attr, 489 489 char *buf, loff_t off, 490 490 size_t count) 491 491 { ··· 495 495 496 496 static ssize_t ccacipher_aes_256_xts_read(struct file *filp, 497 497 struct kobject *kobj, 498 - struct bin_attribute *attr, 498 + const struct bin_attribute *attr, 499 499 char *buf, loff_t off, 500 500 size_t count) 501 501 { ··· 503 503 off, count); 504 504 } 505 505 506 - static BIN_ATTR_RO(ccacipher_aes_128, CCACIPHERTOKENSIZE); 507 - static BIN_ATTR_RO(ccacipher_aes_192, CCACIPHERTOKENSIZE); 508 - static BIN_ATTR_RO(ccacipher_aes_256, CCACIPHERTOKENSIZE); 509 - static BIN_ATTR_RO(ccacipher_aes_128_xts, 2 * CCACIPHERTOKENSIZE); 510 - static BIN_ATTR_RO(ccacipher_aes_256_xts, 2 * CCACIPHERTOKENSIZE); 506 + static const BIN_ATTR_RO(ccacipher_aes_128, CCACIPHERTOKENSIZE); 507 + static const BIN_ATTR_RO(ccacipher_aes_192, CCACIPHERTOKENSIZE); 508 + static const BIN_ATTR_RO(ccacipher_aes_256, CCACIPHERTOKENSIZE); 509 + static const BIN_ATTR_RO(ccacipher_aes_128_xts, 2 * CCACIPHERTOKENSIZE); 510 + static const BIN_ATTR_RO(ccacipher_aes_256_xts, 2 * CCACIPHERTOKENSIZE); 511 511 512 - static struct bin_attribute *ccacipher_attrs[] = { 512 + static const struct bin_attribute *const ccacipher_attrs[] = { 513 513 &bin_attr_ccacipher_aes_128, 514 514 &bin_attr_ccacipher_aes_192, 515 515 &bin_attr_ccacipher_aes_256, ··· 518 518 NULL 519 519 }; 520 520 521 - static struct attribute_group ccacipher_attr_group = { 522 - .name = "ccacipher", 523 - .bin_attrs = ccacipher_attrs, 521 + static const struct attribute_group ccacipher_attr_group = { 522 + .name = "ccacipher", 523 + .bin_attrs_new = ccacipher_attrs, 524 524 }; 525 525 526 526 /* ··· 570 570 571 571 static ssize_t ep11_aes_128_read(struct file *filp, 572 572 struct kobject *kobj, 573 - struct bin_attribute *attr, 573 + const struct bin_attribute *attr, 574 574 char *buf, loff_t off, 575 575 size_t count) 576 576 { ··· 580 580 581 581 static ssize_t ep11_aes_192_read(struct file *filp, 582 582 struct kobject *kobj, 583 - struct bin_attribute *attr, 583 + const struct bin_attribute *attr, 584 584 char *buf, loff_t off, 585 585 size_t count) 586 586 { ··· 590 590 591 591 static ssize_t ep11_aes_256_read(struct file *filp, 592 592 struct kobject *kobj, 593 - struct bin_attribute *attr, 593 + const struct bin_attribute *attr, 594 594 char *buf, loff_t off, 595 595 size_t count) 596 596 { ··· 600 600 601 601 static ssize_t ep11_aes_128_xts_read(struct file *filp, 602 602 struct kobject *kobj, 603 - struct bin_attribute *attr, 603 + const struct bin_attribute *attr, 604 604 char *buf, loff_t off, 605 605 size_t count) 606 606 { ··· 610 610 611 611 static ssize_t ep11_aes_256_xts_read(struct file *filp, 612 612 struct kobject *kobj, 613 - struct bin_attribute *attr, 613 + const struct bin_attribute *attr, 614 614 char *buf, loff_t off, 615 615 size_t count) 616 616 { ··· 618 618 off, count); 619 619 } 620 620 621 - static BIN_ATTR_RO(ep11_aes_128, MAXEP11AESKEYBLOBSIZE); 622 - static BIN_ATTR_RO(ep11_aes_192, MAXEP11AESKEYBLOBSIZE); 623 - static BIN_ATTR_RO(ep11_aes_256, MAXEP11AESKEYBLOBSIZE); 624 - static BIN_ATTR_RO(ep11_aes_128_xts, 2 * MAXEP11AESKEYBLOBSIZE); 625 - static BIN_ATTR_RO(ep11_aes_256_xts, 2 * MAXEP11AESKEYBLOBSIZE); 621 + static const BIN_ATTR_RO(ep11_aes_128, MAXEP11AESKEYBLOBSIZE); 622 + static const BIN_ATTR_RO(ep11_aes_192, MAXEP11AESKEYBLOBSIZE); 623 + static const BIN_ATTR_RO(ep11_aes_256, MAXEP11AESKEYBLOBSIZE); 624 + static const BIN_ATTR_RO(ep11_aes_128_xts, 2 * MAXEP11AESKEYBLOBSIZE); 625 + static const BIN_ATTR_RO(ep11_aes_256_xts, 2 * MAXEP11AESKEYBLOBSIZE); 626 626 627 - static struct bin_attribute *ep11_attrs[] = { 627 + static const struct bin_attribute *const ep11_attrs[] = { 628 628 &bin_attr_ep11_aes_128, 629 629 &bin_attr_ep11_aes_192, 630 630 &bin_attr_ep11_aes_256, ··· 633 633 NULL 634 634 }; 635 635 636 - static struct attribute_group ep11_attr_group = { 636 + static const struct attribute_group ep11_attr_group = { 637 637 .name = "ep11", 638 - .bin_attrs = ep11_attrs, 638 + .bin_attrs_new = ep11_attrs, 639 639 }; 640 640 641 641 const struct attribute_group *pkey_attr_groups[] = {