Skip to content

Commit cd546f7

Browse files
committed
Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
Pull arm64 fixes from Catalin Marinas: - Avoid writing an uninitialised stack variable to POR_EL0 on sigreturn if the poe_context record is absent - Reserve one more page for the early 4K-page kernel mapping to cover the extra [_text, _stext) split introduced by the non-executable read-only mapping - Force the arch_local_irq_*() wrappers to be __always_inline so that noinstr entry and idle paths cannot call out-of-line, instrumentable copies - Fix potential sign extension in the arm64 SCS unwinder's DWARF advance_loc4 decoding - Tolerate arm64 ACPI platforms with only WFI and no deeper PSCI idle states, restoring cpuidle registration on such systems - Include the UAPI <asm/ptrace.h> header in the arm64 GCS libc test rather than carrying a duplicate struct user_gcs definition (the original #ifdef NT_ARM_GCS was wrong to cover the structure definition as it would be masked out if the toolchain defined it) * tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: arm64: signal: Preserve POR_EL0 if poe_context is missing arm64: Reserve an extra page for early kernel mapping kselftest/arm64: Include <asm/ptrace.h> for user_gcs definition ACPI: arm64: cpuidle: Tolerate platforms with no deep PSCI idle states arm64/irqflags: __always_inline the arch_local_irq_*() helpers arm64/scs: Fix potential sign extension issue of advance_loc4
2 parents ef5f46b + 030e8a4 commit cd546f7

7 files changed

Lines changed: 62 additions & 34 deletions

File tree

arch/arm64/include/asm/irqflags.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ static __always_inline void __pmr_local_irq_enable(void)
4040
barrier();
4141
}
4242

43-
static inline void arch_local_irq_enable(void)
43+
static __always_inline void arch_local_irq_enable(void)
4444
{
4545
if (system_uses_irq_prio_masking()) {
4646
__pmr_local_irq_enable();
@@ -68,7 +68,7 @@ static __always_inline void __pmr_local_irq_disable(void)
6868
barrier();
6969
}
7070

71-
static inline void arch_local_irq_disable(void)
71+
static __always_inline void arch_local_irq_disable(void)
7272
{
7373
if (system_uses_irq_prio_masking()) {
7474
__pmr_local_irq_disable();
@@ -90,7 +90,7 @@ static __always_inline unsigned long __pmr_local_save_flags(void)
9090
/*
9191
* Save the current interrupt enable state.
9292
*/
93-
static inline unsigned long arch_local_save_flags(void)
93+
static __always_inline unsigned long arch_local_save_flags(void)
9494
{
9595
if (system_uses_irq_prio_masking()) {
9696
return __pmr_local_save_flags();
@@ -109,7 +109,7 @@ static __always_inline bool __pmr_irqs_disabled_flags(unsigned long flags)
109109
return flags != GIC_PRIO_IRQON;
110110
}
111111

112-
static inline bool arch_irqs_disabled_flags(unsigned long flags)
112+
static __always_inline bool arch_irqs_disabled_flags(unsigned long flags)
113113
{
114114
if (system_uses_irq_prio_masking()) {
115115
return __pmr_irqs_disabled_flags(flags);
@@ -128,7 +128,7 @@ static __always_inline bool __pmr_irqs_disabled(void)
128128
return __pmr_irqs_disabled_flags(__pmr_local_save_flags());
129129
}
130130

131-
static inline bool arch_irqs_disabled(void)
131+
static __always_inline bool arch_irqs_disabled(void)
132132
{
133133
if (system_uses_irq_prio_masking()) {
134134
return __pmr_irqs_disabled();
@@ -160,7 +160,7 @@ static __always_inline unsigned long __pmr_local_irq_save(void)
160160
return flags;
161161
}
162162

163-
static inline unsigned long arch_local_irq_save(void)
163+
static __always_inline unsigned long arch_local_irq_save(void)
164164
{
165165
if (system_uses_irq_prio_masking()) {
166166
return __pmr_local_irq_save();
@@ -187,7 +187,7 @@ static __always_inline void __pmr_local_irq_restore(unsigned long flags)
187187
/*
188188
* restore saved IRQ state
189189
*/
190-
static inline void arch_local_irq_restore(unsigned long flags)
190+
static __always_inline void arch_local_irq_restore(unsigned long flags)
191191
{
192192
if (system_uses_irq_prio_masking()) {
193193
__pmr_local_irq_restore(flags);

arch/arm64/include/asm/kernel-pgtable.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,12 @@
6868
#define KERNEL_SEGMENT_COUNT 5
6969

7070
#if SWAPPER_BLOCK_SIZE > SEGMENT_ALIGN
71-
#define EARLY_SEGMENT_EXTRA_PAGES (KERNEL_SEGMENT_COUNT + 1)
71+
/*
72+
* KERNEL_SEGMENT_COUNT counts the permanent kernel VMAs. The early mapping
73+
* has one additional split, [_text, _stext). Reserve one more page for the
74+
* SWAPPER_BLOCK_SIZE-unaligned boundaries.
75+
*/
76+
#define EARLY_SEGMENT_EXTRA_PAGES (KERNEL_SEGMENT_COUNT + 2)
7277
/*
7378
* The initial ID map consists of the kernel image, mapped as two separate
7479
* segments, and may appear misaligned wrt the swapper block size. This means

arch/arm64/kernel/pi/patch-scs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,9 +196,9 @@ static int scs_handle_fde_frame(const struct eh_frame *frame,
196196
loc += *opcode++ * code_alignment_factor;
197197
loc += (*opcode++ << 8) * code_alignment_factor;
198198
loc += (*opcode++ << 16) * code_alignment_factor;
199-
loc += (*opcode++ << 24) * code_alignment_factor;
199+
loc += ((u64)*opcode++ << 24) * code_alignment_factor;
200200
size -= 4;
201-
break;
201+
break;
202202

203203
case DW_CFA_def_cfa:
204204
case DW_CFA_offset_extended:

arch/arm64/kernel/signal.c

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -67,20 +67,45 @@ struct rt_sigframe_user_layout {
6767
unsigned long end_offset;
6868
};
6969

70+
#define TERMINATOR_SIZE round_up(sizeof(struct _aarch64_ctx), 16)
71+
#define EXTRA_CONTEXT_SIZE round_up(sizeof(struct extra_context), 16)
72+
7073
/*
7174
* Holds any EL0-controlled state that influences unprivileged memory accesses.
7275
* This includes both accesses done in userspace and uaccess done in the kernel.
7376
*
7477
* This state needs to be carefully managed to ensure that it doesn't cause
7578
* uaccess to fail when setting up the signal frame, and the signal handler
7679
* itself also expects a well-defined state when entered.
80+
*
81+
* The struct should be zero-initialised. Its members should only be accessed
82+
* via the accessors below. __valid_fields tracks which of the fields are valid
83+
* (have been set to some value).
7784
*/
7885
struct user_access_state {
79-
u64 por_el0;
86+
unsigned int __valid_fields;
87+
u64 __por_el0;
8088
};
8189

82-
#define TERMINATOR_SIZE round_up(sizeof(struct _aarch64_ctx), 16)
83-
#define EXTRA_CONTEXT_SIZE round_up(sizeof(struct extra_context), 16)
90+
#define UA_STATE_HAS_POR_EL0 BIT(0)
91+
92+
static void set_ua_state_por_el0(struct user_access_state *ua_state,
93+
u64 por_el0)
94+
{
95+
ua_state->__por_el0 = por_el0;
96+
ua_state->__valid_fields |= UA_STATE_HAS_POR_EL0;
97+
}
98+
99+
static int get_ua_state_por_el0(const struct user_access_state *ua_state,
100+
u64 *por_el0)
101+
{
102+
if (ua_state->__valid_fields & UA_STATE_HAS_POR_EL0) {
103+
*por_el0 = ua_state->__por_el0;
104+
return 0;
105+
}
106+
107+
return -ENOENT;
108+
}
84109

85110
/*
86111
* Save the user access state into ua_state and reset it to disable any
@@ -94,7 +119,7 @@ static void save_reset_user_access_state(struct user_access_state *ua_state)
94119
for (int pkey = 0; pkey < arch_max_pkey(); pkey++)
95120
por_enable_all |= POR_ELx_PERM_PREP(pkey, POE_RWX);
96121

97-
ua_state->por_el0 = read_sysreg_s(SYS_POR_EL0);
122+
set_ua_state_por_el0(ua_state, read_sysreg_s(SYS_POR_EL0));
98123
write_sysreg_s(por_enable_all, SYS_POR_EL0);
99124
/*
100125
* No ISB required as we can tolerate spurious Overlay faults -
@@ -122,8 +147,10 @@ static void set_handler_user_access_state(void)
122147
*/
123148
static void restore_user_access_state(const struct user_access_state *ua_state)
124149
{
125-
if (system_supports_poe())
126-
write_sysreg_s(ua_state->por_el0, SYS_POR_EL0);
150+
u64 por_el0;
151+
152+
if (get_ua_state_por_el0(ua_state, &por_el0) == 0)
153+
write_sysreg_s(por_el0, SYS_POR_EL0);
127154
}
128155

129156
static void init_user_layout(struct rt_sigframe_user_layout *user)
@@ -333,11 +360,16 @@ static int restore_fpmr_context(struct user_ctxs *user)
333360
static int preserve_poe_context(struct poe_context __user *ctx,
334361
const struct user_access_state *ua_state)
335362
{
336-
int err = 0;
363+
int err;
364+
u64 por_el0;
365+
366+
err = get_ua_state_por_el0(ua_state, &por_el0);
367+
if (WARN_ON_ONCE(err))
368+
return err;
337369

338370
__put_user_error(POE_MAGIC, &ctx->head.magic, err);
339371
__put_user_error(sizeof(*ctx), &ctx->head.size, err);
340-
__put_user_error(ua_state->por_el0, &ctx->por_el0, err);
372+
__put_user_error(por_el0, &ctx->por_el0, err);
341373

342374
return err;
343375
}
@@ -353,7 +385,7 @@ static int restore_poe_context(struct user_ctxs *user,
353385

354386
__get_user_error(por_el0, &(user->poe->por_el0), err);
355387
if (!err)
356-
ua_state->por_el0 = por_el0;
388+
set_ua_state_por_el0(ua_state, por_el0);
357389

358390
return err;
359391
}
@@ -1095,7 +1127,7 @@ SYSCALL_DEFINE0(rt_sigreturn)
10951127
{
10961128
struct pt_regs *regs = current_pt_regs();
10971129
struct rt_sigframe __user *frame;
1098-
struct user_access_state ua_state;
1130+
struct user_access_state ua_state = {};
10991131

11001132
/* Always make any pending restarted system calls return -EINTR */
11011133
current->restart_block.fn = do_no_restart_syscall;
@@ -1507,7 +1539,7 @@ static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,
15071539
{
15081540
struct rt_sigframe_user_layout user;
15091541
struct rt_sigframe __user *frame;
1510-
struct user_access_state ua_state;
1542+
struct user_access_state ua_state = {};
15111543
int err = 0;
15121544

15131545
fpsimd_save_and_flush_current_state();

drivers/acpi/arm64/cpuidle.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
static int psci_acpi_cpu_init_idle(unsigned int cpu)
1818
{
19-
int i, count;
19+
int i;
2020
struct acpi_lpi_state *lpi;
2121
struct acpi_processor *pr = per_cpu(processors, cpu);
2222

@@ -30,14 +30,10 @@ static int psci_acpi_cpu_init_idle(unsigned int cpu)
3030
if (!psci_ops.cpu_suspend)
3131
return -EOPNOTSUPP;
3232

33-
count = pr->power.count - 1;
34-
if (count <= 0)
35-
return -ENODEV;
36-
37-
for (i = 0; i < count; i++) {
33+
for (i = 1; i < pr->power.count; i++) {
3834
u32 state;
3935

40-
lpi = &pr->power.lpi_states[i + 1];
36+
lpi = &pr->power.lpi_states[i];
4137
/*
4238
* Only bits[31:0] represent a PSCI power_state while
4339
* bits[63:32] must be 0x0 as per ARM ACPI FFH Specification

tools/testing/selftests/arm64/gcs/gcs-util.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,6 @@
1818

1919
#ifndef NT_ARM_GCS
2020
#define NT_ARM_GCS 0x410
21-
22-
struct user_gcs {
23-
__u64 features_enabled;
24-
__u64 features_locked;
25-
__u64 gcspr_el0;
26-
};
2721
#endif
2822

2923
/* Shadow Stack/Guarded Control Stack interface */

tools/testing/selftests/arm64/gcs/libc-gcs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include <asm/hwcap.h>
1818
#include <asm/mman.h>
19+
#include <asm/ptrace.h>
1920

2021
#include <linux/compiler.h>
2122

0 commit comments

Comments
 (0)