Skip to content

Commit 9cc220a

Browse files
committed
Merge tag 's390-6.18-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 updates from Alexander Gordeev: - Refactor SCLP memory hotplug code - Introduce common boot_panic() decompressor helper macro and use it to get rid of nearly few identical implementations - Take into account additional key generation flags and forward it to the ep11 implementation. With that allow users to modify the key generation process, e.g. provide valid combinations of XCP_BLOB_* flags - Replace kmalloc() + copy_from_user() with memdup_user_nul() in s390 debug facility and HMC driver - Add DAX support for DCSS memory block devices - Make the compiler statement attribute "assume" available with a new __assume macro - Rework ffs() and fls() family bitops functions, including source code improvements and generated code optimizations. Use the newly introduced __assume macro for that - Enable additional network features in default configurations - Use __GFP_ACCOUNT flag for user page table allocations to add missing kmemcg accounting - Add WQ_PERCPU flag to explicitly request the use of the per-CPU workqueue for 3590 tape driver - Switch power reading to the per-CPU and the Hiperdispatch to the default workqueue - Add memory allocation profiling hooks to allow better profiling data and the /proc/allocinfo output similar to other architectures * tag 's390-6.18-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (21 commits) s390/mm: Add memory allocation profiling hooks s390: Replace use of system_wq with system_dfl_wq s390/diag324: Replace use of system_wq with system_percpu_wq s390/tape: Add WQ_PERCPU to alloc_workqueue users s390/bitops: Switch to generic ffs() if supported by compiler s390/bitops: Switch to generic fls(), fls64(), etc. s390/mm: Use __GFP_ACCOUNT for user page table allocations s390/configs: Enable additional network features s390/bitops: Cleanup __flogr() s390/bitops: Use __assume() for __flogr() inline assembly return value compiler_types: Add __assume macro s390/bitops: Limit return value range of __flogr() s390/dcssblk: Add DAX support s390/hmcdrv: Replace kmalloc() + copy_from_user() with memdup_user_nul() s390/debug: Replace kmalloc() + copy_from_user() with memdup_user_nul() s390/pkey: Forward keygenflags to ep11_unwrapkey s390/boot: Add common boot_panic() code s390/bitops: Optimize inlining s390/bitops: Slightly optimize ffs() and fls64() s390/sclp: Move memory hotplug code for better modularity ...
2 parents f1004b2 + 088bb10 commit 9cc220a

23 files changed

Lines changed: 611 additions & 575 deletions

File tree

arch/s390/Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,13 @@ config KASAN_SHADOW_OFFSET
4949
depends on KASAN
5050
default 0x1C000000000000
5151

52+
config CC_HAS_BUILTIN_FFS
53+
def_bool !(CC_IS_GCC && GCC_VERSION < 160000)
54+
help
55+
GCC versions before 16.0.0 generate library calls to ffs()
56+
for __builtin_ffs() even when __has_builtin(__builtin_ffs)
57+
is true.
58+
5259
config CC_ASM_FLAG_OUTPUT_BROKEN
5360
def_bool CC_IS_GCC && GCC_VERSION < 140200
5461
help

arch/s390/boot/boot.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include <linux/printk.h>
1212
#include <asm/physmem_info.h>
13+
#include <asm/stacktrace.h>
1314

1415
struct vmlinux_info {
1516
unsigned long entry;
@@ -89,6 +90,13 @@ void __noreturn jump_to_kernel(psw_t *psw);
8990
#define boot_info(fmt, ...) boot_printk(KERN_INFO boot_fmt(fmt), ##__VA_ARGS__)
9091
#define boot_debug(fmt, ...) boot_printk(KERN_DEBUG boot_fmt(fmt), ##__VA_ARGS__)
9192

93+
#define boot_panic(...) do { \
94+
boot_emerg(__VA_ARGS__); \
95+
print_stacktrace(current_frame_address()); \
96+
boot_emerg(" -- System halted\n"); \
97+
disabled_wait(); \
98+
} while (0)
99+
92100
extern struct machine_info machine;
93101
extern int boot_console_loglevel;
94102
extern bool boot_ignore_loglevel;

arch/s390/boot/decompressor.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,7 @@ static void decompress_error(char *m)
6868
{
6969
if (bootdebug)
7070
boot_rb_dump();
71-
boot_emerg("Decompression error: %s\n", m);
72-
boot_emerg(" -- System halted\n");
73-
disabled_wait();
71+
boot_panic("Decompression error: %s\n", m);
7472
}
7573

7674
unsigned long mem_safe_offset(void)

arch/s390/boot/physmem_info.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -228,9 +228,7 @@ static void die_oom(unsigned long size, unsigned long align, unsigned long min,
228228
boot_emerg("Usable online memory total: %lu Reserved: %lu Free: %lu\n",
229229
total_mem, total_reserved_mem,
230230
total_mem > total_reserved_mem ? total_mem - total_reserved_mem : 0);
231-
print_stacktrace(current_frame_address());
232-
boot_emerg(" -- System halted\n");
233-
disabled_wait();
231+
boot_panic("Oom\n");
234232
}
235233

236234
static void _physmem_reserve(enum reserved_range_type type, unsigned long addr, unsigned long size)

arch/s390/boot/startup.c

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,6 @@ u64 __bootdata_preserved(clock_comparator_max) = -1UL;
4444
u64 __bootdata_preserved(stfle_fac_list[16]);
4545
struct oldmem_data __bootdata_preserved(oldmem_data);
4646

47-
void error(char *x)
48-
{
49-
boot_emerg("%s\n", x);
50-
boot_emerg(" -- System halted\n");
51-
disabled_wait();
52-
}
53-
5447
static char sysinfo_page[PAGE_SIZE] __aligned(PAGE_SIZE);
5548

5649
static void detect_machine_type(void)
@@ -220,10 +213,10 @@ static void rescue_initrd(unsigned long min, unsigned long max)
220213
static void copy_bootdata(void)
221214
{
222215
if (__boot_data_end - __boot_data_start != vmlinux.bootdata_size)
223-
error(".boot.data section size mismatch");
216+
boot_panic(".boot.data section size mismatch\n");
224217
memcpy((void *)vmlinux.bootdata_off, __boot_data_start, vmlinux.bootdata_size);
225218
if (__boot_data_preserved_end - __boot_data_preserved_start != vmlinux.bootdata_preserved_size)
226-
error(".boot.preserved.data section size mismatch");
219+
boot_panic(".boot.preserved.data section size mismatch\n");
227220
memcpy((void *)vmlinux.bootdata_preserved_off, __boot_data_preserved_start, vmlinux.bootdata_preserved_size);
228221
}
229222

@@ -237,7 +230,7 @@ static void kaslr_adjust_relocs(unsigned long min_addr, unsigned long max_addr,
237230
for (reloc = (int *)__vmlinux_relocs_64_start; reloc < (int *)__vmlinux_relocs_64_end; reloc++) {
238231
loc = (long)*reloc + phys_offset;
239232
if (loc < min_addr || loc > max_addr)
240-
error("64-bit relocation outside of kernel!\n");
233+
boot_panic("64-bit relocation outside of kernel!\n");
241234
*(u64 *)loc += offset;
242235
}
243236
}

arch/s390/configs/debug_defconfig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,13 @@ CONFIG_PACKET=y
118118
CONFIG_PACKET_DIAG=m
119119
CONFIG_UNIX=y
120120
CONFIG_UNIX_DIAG=m
121+
CONFIG_TLS=m
122+
CONFIG_TLS_DEVICE=y
123+
CONFIG_TLS_TOE=y
121124
CONFIG_XFRM_USER=m
122125
CONFIG_NET_KEY=m
126+
CONFIG_XDP_SOCKETS=y
127+
CONFIG_XDP_SOCKETS_DIAG=m
123128
CONFIG_SMC_DIAG=m
124129
CONFIG_SMC_LO=y
125130
CONFIG_INET=y
@@ -542,6 +547,7 @@ CONFIG_NLMON=m
542547
CONFIG_MLX4_EN=m
543548
CONFIG_MLX5_CORE=m
544549
CONFIG_MLX5_CORE_EN=y
550+
CONFIG_MLX5_SF=y
545551
# CONFIG_NET_VENDOR_META is not set
546552
# CONFIG_NET_VENDOR_MICREL is not set
547553
# CONFIG_NET_VENDOR_MICROCHIP is not set

arch/s390/configs/defconfig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,13 @@ CONFIG_PACKET=y
109109
CONFIG_PACKET_DIAG=m
110110
CONFIG_UNIX=y
111111
CONFIG_UNIX_DIAG=m
112+
CONFIG_TLS=m
113+
CONFIG_TLS_DEVICE=y
114+
CONFIG_TLS_TOE=y
112115
CONFIG_XFRM_USER=m
113116
CONFIG_NET_KEY=m
117+
CONFIG_XDP_SOCKETS=y
118+
CONFIG_XDP_SOCKETS_DIAG=m
114119
CONFIG_SMC_DIAG=m
115120
CONFIG_SMC_LO=y
116121
CONFIG_INET=y
@@ -532,6 +537,7 @@ CONFIG_NLMON=m
532537
CONFIG_MLX4_EN=m
533538
CONFIG_MLX5_CORE=m
534539
CONFIG_MLX5_CORE_EN=y
540+
CONFIG_MLX5_SF=y
535541
# CONFIG_NET_VENDOR_META is not set
536542
# CONFIG_NET_VENDOR_MICREL is not set
537543
# CONFIG_NET_VENDOR_MICROCHIP is not set

arch/s390/include/asm/bitops.h

Lines changed: 27 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ static inline bool test_bit_inv(unsigned long nr,
122122
return test_bit(nr ^ (BITS_PER_LONG - 1), ptr);
123123
}
124124

125+
#ifndef CONFIG_CC_HAS_BUILTIN_FFS
126+
125127
/**
126128
* __flogr - find leftmost one
127129
* @word - The word to search
@@ -130,11 +132,12 @@ static inline bool test_bit_inv(unsigned long nr,
130132
* where the most significant bit has bit number 0.
131133
* If no bit is set this function returns 64.
132134
*/
133-
static inline unsigned char __flogr(unsigned long word)
135+
static __always_inline __attribute_const__ unsigned long __flogr(unsigned long word)
134136
{
135-
if (__builtin_constant_p(word)) {
136-
unsigned long bit = 0;
137+
unsigned long bit;
137138

139+
if (__builtin_constant_p(word)) {
140+
bit = 0;
138141
if (!word)
139142
return 64;
140143
if (!(word & 0xffffffff00000000UL)) {
@@ -163,86 +166,49 @@ static inline unsigned char __flogr(unsigned long word)
163166
}
164167
return bit;
165168
} else {
166-
union register_pair rp;
169+
union register_pair rp __uninitialized;
167170

168171
rp.even = word;
169-
asm volatile(
170-
" flogr %[rp],%[rp]\n"
171-
: [rp] "+d" (rp.pair) : : "cc");
172-
return rp.even;
172+
asm("flogr %[rp],%[rp]"
173+
: [rp] "+d" (rp.pair) : : "cc");
174+
bit = rp.even;
175+
/*
176+
* The result of the flogr instruction is a value in the range
177+
* of 0..64. Let the compiler know that the AND operation can
178+
* be optimized away.
179+
*/
180+
__assume(bit <= 64);
181+
return bit & 127;
173182
}
174183
}
175184

176-
/**
177-
* __ffs - find first bit in word.
178-
* @word: The word to search
179-
*
180-
* Undefined if no bit exists, so code should check against 0 first.
181-
*/
182-
static inline __attribute_const__ unsigned long __ffs(unsigned long word)
183-
{
184-
return __flogr(-word & word) ^ (BITS_PER_LONG - 1);
185-
}
186-
187185
/**
188186
* ffs - find first bit set
189187
* @word: the word to search
190188
*
191189
* This is defined the same way as the libc and
192190
* compiler builtin ffs routines (man ffs).
193191
*/
194-
static inline __attribute_const__ int ffs(int word)
192+
static __always_inline __flatten __attribute_const__ int ffs(int word)
195193
{
196-
unsigned long mask = 2 * BITS_PER_LONG - 1;
197194
unsigned int val = (unsigned int)word;
198195

199-
return (1 + (__flogr(-val & val) ^ (BITS_PER_LONG - 1))) & mask;
200-
}
201-
202-
/**
203-
* __fls - find last (most-significant) set bit in a long word
204-
* @word: the word to search
205-
*
206-
* Undefined if no set bit exists, so code should check against 0 first.
207-
*/
208-
static inline __attribute_const__ unsigned long __fls(unsigned long word)
209-
{
210-
return __flogr(word) ^ (BITS_PER_LONG - 1);
196+
return BITS_PER_LONG - __flogr(-val & val);
211197
}
212198

213-
/**
214-
* fls64 - find last set bit in a 64-bit word
215-
* @word: the word to search
216-
*
217-
* This is defined in a similar way as the libc and compiler builtin
218-
* ffsll, but returns the position of the most significant set bit.
219-
*
220-
* fls64(value) returns 0 if value is 0 or the position of the last
221-
* set bit if value is nonzero. The last (most significant) bit is
222-
* at position 64.
223-
*/
224-
static inline __attribute_const__ int fls64(unsigned long word)
225-
{
226-
unsigned long mask = 2 * BITS_PER_LONG - 1;
199+
#else /* CONFIG_CC_HAS_BUILTIN_FFS */
227200

228-
return (1 + (__flogr(word) ^ (BITS_PER_LONG - 1))) & mask;
229-
}
201+
#include <asm-generic/bitops/builtin-ffs.h>
230202

231-
/**
232-
* fls - find last (most-significant) bit set
233-
* @word: the word to search
234-
*
235-
* This is defined the same way as ffs.
236-
* Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
237-
*/
238-
static inline __attribute_const__ int fls(unsigned int word)
239-
{
240-
return fls64(word);
241-
}
203+
#endif /* CONFIG_CC_HAS_BUILTIN_FFS */
242204

205+
#include <asm-generic/bitops/builtin-__ffs.h>
206+
#include <asm-generic/bitops/ffz.h>
207+
#include <asm-generic/bitops/builtin-__fls.h>
208+
#include <asm-generic/bitops/builtin-fls.h>
209+
#include <asm-generic/bitops/fls64.h>
243210
#include <asm/arch_hweight.h>
244211
#include <asm-generic/bitops/const_hweight.h>
245-
#include <asm-generic/bitops/ffz.h>
246212
#include <asm-generic/bitops/sched.h>
247213
#include <asm-generic/bitops/le.h>
248214
#include <asm-generic/bitops/ext2-atomic-setbit.h>

arch/s390/include/asm/pgalloc.h

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,16 @@
1919

2020
#define CRST_ALLOC_ORDER 2
2121

22-
unsigned long *crst_table_alloc(struct mm_struct *);
22+
unsigned long *crst_table_alloc_noprof(struct mm_struct *);
23+
#define crst_table_alloc(...) alloc_hooks(crst_table_alloc_noprof(__VA_ARGS__))
2324
void crst_table_free(struct mm_struct *, unsigned long *);
2425

25-
unsigned long *page_table_alloc(struct mm_struct *);
26-
struct ptdesc *page_table_alloc_pgste(struct mm_struct *mm);
26+
unsigned long *page_table_alloc_noprof(struct mm_struct *);
27+
#define page_table_alloc(...) alloc_hooks(page_table_alloc_noprof(__VA_ARGS__))
2728
void page_table_free(struct mm_struct *, unsigned long *);
29+
30+
struct ptdesc *page_table_alloc_pgste_noprof(struct mm_struct *mm);
31+
#define page_table_alloc_pgste(...) alloc_hooks(page_table_alloc_pgste_noprof(__VA_ARGS__))
2832
void page_table_free_pgste(struct ptdesc *ptdesc);
2933

3034
static inline void crst_table_init(unsigned long *crst, unsigned long entry)
@@ -48,9 +52,9 @@ static inline unsigned long check_asce_limit(struct mm_struct *mm, unsigned long
4852
return addr;
4953
}
5054

51-
static inline p4d_t *p4d_alloc_one(struct mm_struct *mm, unsigned long address)
55+
static inline p4d_t *p4d_alloc_one_noprof(struct mm_struct *mm, unsigned long address)
5256
{
53-
unsigned long *table = crst_table_alloc(mm);
57+
unsigned long *table = crst_table_alloc_noprof(mm);
5458

5559
if (!table)
5660
return NULL;
@@ -59,6 +63,7 @@ static inline p4d_t *p4d_alloc_one(struct mm_struct *mm, unsigned long address)
5963

6064
return (p4d_t *) table;
6165
}
66+
#define p4d_alloc_one(...) alloc_hooks(p4d_alloc_one_noprof(__VA_ARGS__))
6267

6368
static inline void p4d_free(struct mm_struct *mm, p4d_t *p4d)
6469
{
@@ -69,9 +74,9 @@ static inline void p4d_free(struct mm_struct *mm, p4d_t *p4d)
6974
crst_table_free(mm, (unsigned long *) p4d);
7075
}
7176

72-
static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long address)
77+
static inline pud_t *pud_alloc_one_noprof(struct mm_struct *mm, unsigned long address)
7378
{
74-
unsigned long *table = crst_table_alloc(mm);
79+
unsigned long *table = crst_table_alloc_noprof(mm);
7580

7681
if (!table)
7782
return NULL;
@@ -80,6 +85,7 @@ static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long address)
8085

8186
return (pud_t *) table;
8287
}
88+
#define pud_alloc_one(...) alloc_hooks(pud_alloc_one_noprof(__VA_ARGS__))
8389

8490
static inline void pud_free(struct mm_struct *mm, pud_t *pud)
8591
{
@@ -90,9 +96,9 @@ static inline void pud_free(struct mm_struct *mm, pud_t *pud)
9096
crst_table_free(mm, (unsigned long *) pud);
9197
}
9298

93-
static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr)
99+
static inline pmd_t *pmd_alloc_one_noprof(struct mm_struct *mm, unsigned long vmaddr)
94100
{
95-
unsigned long *table = crst_table_alloc(mm);
101+
unsigned long *table = crst_table_alloc_noprof(mm);
96102

97103
if (!table)
98104
return NULL;
@@ -103,6 +109,7 @@ static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr)
103109
}
104110
return (pmd_t *) table;
105111
}
112+
#define pmd_alloc_one(...) alloc_hooks(pmd_alloc_one_noprof(__VA_ARGS__))
106113

107114
static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
108115
{
@@ -127,16 +134,17 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
127134
set_pud(pud, __pud(_REGION3_ENTRY | __pa(pmd)));
128135
}
129136

130-
static inline pgd_t *pgd_alloc(struct mm_struct *mm)
137+
static inline pgd_t *pgd_alloc_noprof(struct mm_struct *mm)
131138
{
132-
unsigned long *table = crst_table_alloc(mm);
139+
unsigned long *table = crst_table_alloc_noprof(mm);
133140

134141
if (!table)
135142
return NULL;
136143
pagetable_pgd_ctor(virt_to_ptdesc(table));
137144

138145
return (pgd_t *) table;
139146
}
147+
#define pgd_alloc(...) alloc_hooks(pgd_alloc_noprof(__VA_ARGS__))
140148

141149
static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
142150
{

arch/s390/kernel/debug.c

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1416,18 +1416,12 @@ static inline char *debug_get_user_string(const char __user *user_buf,
14161416
{
14171417
char *buffer;
14181418

1419-
buffer = kmalloc(user_len + 1, GFP_KERNEL);
1420-
if (!buffer)
1421-
return ERR_PTR(-ENOMEM);
1422-
if (copy_from_user(buffer, user_buf, user_len) != 0) {
1423-
kfree(buffer);
1424-
return ERR_PTR(-EFAULT);
1425-
}
1419+
buffer = memdup_user_nul(user_buf, user_len);
1420+
if (IS_ERR(buffer))
1421+
return buffer;
14261422
/* got the string, now strip linefeed. */
14271423
if (buffer[user_len - 1] == '\n')
14281424
buffer[user_len - 1] = 0;
1429-
else
1430-
buffer[user_len] = 0;
14311425
return buffer;
14321426
}
14331427

0 commit comments

Comments
 (0)