Skip to content

Commit 9d2a4d7

Browse files
Sukadev Bhattiprolumpe
authored andcommitted
powerpc: Define set_thread_uses_vas()
A CP_ABORT instruction is required in processes that have mapped a VAS "paste address" with the intention of using COPY/PASTE instructions. But since CP_ABORT is expensive, we want to restrict it to only processes that use/intend to use COPY/PASTE. Define an interface, set_thread_uses_vas(), that VAS can use to indicate that the current process opened a send window. During context switch, issue CP_ABORT only for processes that have the flag set. Thanks for input from Nick Piggin, Michael Ellerman. Signed-off-by: Sukadev Bhattiprolu <[email protected]> [mpe: Fix to not use new_thread after _switch() returns] Signed-off-by: Michael Ellerman <[email protected]>
1 parent ec233ed commit 9d2a4d7

File tree

3 files changed

+35
-10
lines changed

3 files changed

+35
-10
lines changed

arch/powerpc/include/asm/processor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,9 @@ struct thread_struct {
341341
unsigned long sier;
342342
unsigned long mmcr2;
343343
unsigned mmcr0;
344+
344345
unsigned used_ebb;
346+
unsigned int used_vas;
345347
#endif
346348
};
347349

arch/powerpc/include/asm/switch_to.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ static inline void clear_task_ebb(struct task_struct *t)
9191
#endif
9292
}
9393

94+
extern int set_thread_uses_vas(void);
95+
9496
extern int set_thread_tidr(struct task_struct *t);
9597
extern void clear_thread_tidr(struct task_struct *t);
9698

arch/powerpc/kernel/process.c

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,17 +1244,17 @@ struct task_struct *__switch_to(struct task_struct *prev,
12441244
* The copy-paste buffer can only store into foreign real
12451245
* addresses, so unprivileged processes can not see the
12461246
* data or use it in any way unless they have foreign real
1247-
* mappings. We don't have a VAS driver that allocates those
1248-
* yet, so no cpabort is required.
1247+
* mappings. If the new process has the foreign real address
1248+
* mappings, we must issue a cp_abort to clear any state and
1249+
* prevent snooping, corruption or a covert channel.
1250+
*
1251+
* DD1 allows paste into normal system memory so we do an
1252+
* unpaired copy, rather than cp_abort, to clear the buffer,
1253+
* since cp_abort is quite expensive.
12491254
*/
1250-
if (cpu_has_feature(CPU_FTR_POWER9_DD1)) {
1251-
/*
1252-
* DD1 allows paste into normal system memory, so we
1253-
* do an unpaired copy here to clear the buffer and
1254-
* prevent a covert channel being set up.
1255-
*
1256-
* cpabort is not used because it is quite expensive.
1257-
*/
1255+
if (current_thread_info()->task->thread.used_vas) {
1256+
asm volatile(PPC_CP_ABORT);
1257+
} else if (cpu_has_feature(CPU_FTR_POWER9_DD1)) {
12581258
asm volatile(PPC_COPY(%0, %1)
12591259
: : "r"(dummy_copy_buffer), "r"(0));
12601260
}
@@ -1455,6 +1455,27 @@ void flush_thread(void)
14551455
#endif /* CONFIG_HAVE_HW_BREAKPOINT */
14561456
}
14571457

1458+
int set_thread_uses_vas(void)
1459+
{
1460+
#ifdef CONFIG_PPC_BOOK3S_64
1461+
if (!cpu_has_feature(CPU_FTR_ARCH_300))
1462+
return -EINVAL;
1463+
1464+
current->thread.used_vas = 1;
1465+
1466+
/*
1467+
* Even a process that has no foreign real address mapping can use
1468+
* an unpaired COPY instruction (to no real effect). Issue CP_ABORT
1469+
* to clear any pending COPY and prevent a covert channel.
1470+
*
1471+
* __switch_to() will issue CP_ABORT on future context switches.
1472+
*/
1473+
asm volatile(PPC_CP_ABORT);
1474+
1475+
#endif /* CONFIG_PPC_BOOK3S_64 */
1476+
return 0;
1477+
}
1478+
14581479
#ifdef CONFIG_PPC64
14591480
static DEFINE_SPINLOCK(vas_thread_id_lock);
14601481
static DEFINE_IDA(vas_thread_ida);

0 commit comments

Comments
 (0)