Skip to content

Commit 48a8ab4

Browse files
kvaneeshmpe
authored andcommitted
powerpc/book3s64/pkeys: Don't update SPRN_AMR when in kernel mode.
Now that kernel correctly store/restore userspace AMR/IAMR values, avoid manipulating AMR and IAMR from the kernel on behalf of userspace. Signed-off-by: Aneesh Kumar K.V <[email protected]> Reviewed-by: Sandipan Das <[email protected]> Signed-off-by: Michael Ellerman <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent edc541e commit 48a8ab4

File tree

5 files changed

+31
-61
lines changed

5 files changed

+31
-61
lines changed

arch/powerpc/include/asm/book3s/64/kup.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,27 @@ DECLARE_STATIC_KEY_FALSE(uaccess_flush_key);
177177
#include <asm/mmu.h>
178178
#include <asm/ptrace.h>
179179

180+
/*
181+
* For kernel thread that doesn't have thread.regs return
182+
* default AMR/IAMR values.
183+
*/
184+
static inline u64 current_thread_amr(void)
185+
{
186+
if (current->thread.regs)
187+
return current->thread.regs->amr;
188+
return AMR_KUAP_BLOCKED;
189+
}
190+
191+
static inline u64 current_thread_iamr(void)
192+
{
193+
if (current->thread.regs)
194+
return current->thread.regs->iamr;
195+
return AMR_KUEP_BLOCKED;
196+
}
197+
#endif /* CONFIG_PPC_PKEY */
198+
199+
#ifdef CONFIG_PPC_KUAP
200+
180201
static inline void kuap_user_restore(struct pt_regs *regs)
181202
{
182203
if (!mmu_has_feature(MMU_FTR_PKEY))

arch/powerpc/include/asm/processor.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -226,10 +226,6 @@ struct thread_struct {
226226
struct thread_vr_state ckvr_state; /* Checkpointed VR state */
227227
unsigned long ckvrsave; /* Checkpointed VRSAVE */
228228
#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
229-
#ifdef CONFIG_PPC_MEM_KEYS
230-
unsigned long amr;
231-
unsigned long iamr;
232-
#endif
233229
#ifdef CONFIG_KVM_BOOK3S_32_HANDLER
234230
void* kvm_shadow_vcpu; /* KVM internal data */
235231
#endif /* CONFIG_KVM_BOOK3S_32_HANDLER */

arch/powerpc/kernel/process.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -589,7 +589,6 @@ static void save_all(struct task_struct *tsk)
589589
__giveup_spe(tsk);
590590

591591
msr_check_and_clear(msr_all_available);
592-
thread_pkey_regs_save(&tsk->thread);
593592
}
594593

595594
void flush_all_to_thread(struct task_struct *tsk)
@@ -1160,8 +1159,6 @@ static inline void save_sprs(struct thread_struct *t)
11601159
t->tar = mfspr(SPRN_TAR);
11611160
}
11621161
#endif
1163-
1164-
thread_pkey_regs_save(t);
11651162
}
11661163

11671164
static inline void restore_sprs(struct thread_struct *old_thread,
@@ -1202,7 +1199,6 @@ static inline void restore_sprs(struct thread_struct *old_thread,
12021199
mtspr(SPRN_TIDR, new_thread->tidr);
12031200
#endif
12041201

1205-
thread_pkey_regs_restore(new_thread, old_thread);
12061202
}
12071203

12081204
struct task_struct *__switch_to(struct task_struct *prev,

arch/powerpc/kernel/traps.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -347,12 +347,6 @@ static bool exception_common(int signr, struct pt_regs *regs, int code,
347347

348348
current->thread.trap_nr = code;
349349

350-
/*
351-
* Save all the pkey registers AMR/IAMR/UAMOR. Eg: Core dumps need
352-
* to capture the content, if the task gets killed.
353-
*/
354-
thread_pkey_regs_save(&current->thread);
355-
356350
return true;
357351
}
358352

arch/powerpc/mm/book3s64/pkeys.c

Lines changed: 10 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -281,30 +281,17 @@ void __init setup_kuap(bool disabled)
281281
}
282282
#endif
283283

284-
static inline u64 read_amr(void)
284+
static inline void update_current_thread_amr(u64 value)
285285
{
286-
return mfspr(SPRN_AMR);
286+
current->thread.regs->amr = value;
287287
}
288288

289-
static inline void write_amr(u64 value)
290-
{
291-
mtspr(SPRN_AMR, value);
292-
}
293-
294-
static inline u64 read_iamr(void)
295-
{
296-
if (!likely(pkey_execute_disable_supported))
297-
return 0x0UL;
298-
299-
return mfspr(SPRN_IAMR);
300-
}
301-
302-
static inline void write_iamr(u64 value)
289+
static inline void update_current_thread_iamr(u64 value)
303290
{
304291
if (!likely(pkey_execute_disable_supported))
305292
return;
306293

307-
mtspr(SPRN_IAMR, value);
294+
current->thread.regs->iamr = value;
308295
}
309296

310297
#ifdef CONFIG_PPC_MEM_KEYS
@@ -319,17 +306,17 @@ void pkey_mm_init(struct mm_struct *mm)
319306
static inline void init_amr(int pkey, u8 init_bits)
320307
{
321308
u64 new_amr_bits = (((u64)init_bits & 0x3UL) << pkeyshift(pkey));
322-
u64 old_amr = read_amr() & ~((u64)(0x3ul) << pkeyshift(pkey));
309+
u64 old_amr = current_thread_amr() & ~((u64)(0x3ul) << pkeyshift(pkey));
323310

324-
write_amr(old_amr | new_amr_bits);
311+
update_current_thread_amr(old_amr | new_amr_bits);
325312
}
326313

327314
static inline void init_iamr(int pkey, u8 init_bits)
328315
{
329316
u64 new_iamr_bits = (((u64)init_bits & 0x1UL) << pkeyshift(pkey));
330-
u64 old_iamr = read_iamr() & ~((u64)(0x1ul) << pkeyshift(pkey));
317+
u64 old_iamr = current_thread_iamr() & ~((u64)(0x1ul) << pkeyshift(pkey));
331318

332-
write_iamr(old_iamr | new_iamr_bits);
319+
update_current_thread_iamr(old_iamr | new_iamr_bits);
333320
}
334321

335322
/*
@@ -372,30 +359,6 @@ int __arch_set_user_pkey_access(struct task_struct *tsk, int pkey,
372359
return 0;
373360
}
374361

375-
void thread_pkey_regs_save(struct thread_struct *thread)
376-
{
377-
if (!mmu_has_feature(MMU_FTR_PKEY))
378-
return;
379-
380-
/*
381-
* TODO: Skip saving registers if @thread hasn't used any keys yet.
382-
*/
383-
thread->amr = read_amr();
384-
thread->iamr = read_iamr();
385-
}
386-
387-
void thread_pkey_regs_restore(struct thread_struct *new_thread,
388-
struct thread_struct *old_thread)
389-
{
390-
if (!mmu_has_feature(MMU_FTR_PKEY))
391-
return;
392-
393-
if (old_thread->amr != new_thread->amr)
394-
write_amr(new_thread->amr);
395-
if (old_thread->iamr != new_thread->iamr)
396-
write_iamr(new_thread->iamr);
397-
}
398-
399362
int execute_only_pkey(struct mm_struct *mm)
400363
{
401364
return mm->context.execute_only_pkey;
@@ -444,9 +407,9 @@ static bool pkey_access_permitted(int pkey, bool write, bool execute)
444407

445408
pkey_shift = pkeyshift(pkey);
446409
if (execute)
447-
return !(read_iamr() & (IAMR_EX_BIT << pkey_shift));
410+
return !(current_thread_iamr() & (IAMR_EX_BIT << pkey_shift));
448411

449-
amr = read_amr();
412+
amr = current_thread_amr();
450413
if (write)
451414
return !(amr & (AMR_WR_BIT << pkey_shift));
452415

0 commit comments

Comments
 (0)