x86/mm: Remove preempt_disable/enable() from __native_flush_tlb()
[linux/fpc-iii.git] / tools / testing / selftests / powerpc / context_switch / cp_abort.c
blob5a5b55afda0e535842c4de6c6a80ff7cfa8f6ba0
1 /*
2 * Adapted from Anton Blanchard's context switch microbenchmark.
4 * Copyright 2009, Anton Blanchard, IBM Corporation.
5 * Copyright 2016, Mikey Neuling, Chris Smart, IBM Corporation.
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
12 * This program tests the copy paste abort functionality of a P9
13 * (or later) by setting up two processes on the same CPU, one
14 * which executes the copy instruction and the other which
15 * executes paste.
17 * The paste instruction should never succeed, as the cp_abort
18 * instruction is called by the kernel during a context switch.
22 #define _GNU_SOURCE
24 #include <stdio.h>
25 #include <unistd.h>
26 #include <stdlib.h>
27 #include "utils.h"
28 #include <sched.h>
30 #define READ_FD 0
31 #define WRITE_FD 1
33 #define NUM_LOOPS 1000
35 /* This defines the "paste" instruction from Power ISA 3.0 Book II, section 4.4. */
36 #define PASTE(RA, RB, L, RC) \
37 .long (0x7c00070c | (RA) << (31-15) | (RB) << (31-20) | (L) << (31-10) | (RC) << (31-31))
39 int paste(void *i)
41 int cr;
43 asm volatile(str(PASTE(0, %1, 1, 1))";"
44 "mfcr %0;"
45 : "=r" (cr)
46 : "b" (i)
47 : "memory"
49 return cr;
52 /* This defines the "copy" instruction from Power ISA 3.0 Book II, section 4.4. */
53 #define COPY(RA, RB, L) \
54 .long (0x7c00060c | (RA) << (31-15) | (RB) << (31-20) | (L) << (31-10))
56 void copy(void *i)
58 asm volatile(str(COPY(0, %0, 1))";"
60 : "b" (i)
61 : "memory"
65 int test_cp_abort(void)
67 /* 128 bytes for a full cache line */
68 char buf[128] __cacheline_aligned;
69 cpu_set_t cpuset;
70 int fd1[2], fd2[2], pid;
71 char c;
73 /* only run this test on a P9 or later */
74 SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_00));
77 * Run both processes on the same CPU, so that copy is more likely
78 * to leak into a paste.
80 CPU_ZERO(&cpuset);
81 CPU_SET(pick_online_cpu(), &cpuset);
82 FAIL_IF(sched_setaffinity(0, sizeof(cpuset), &cpuset));
84 FAIL_IF(pipe(fd1) || pipe(fd2));
86 pid = fork();
87 FAIL_IF(pid < 0);
89 if (!pid) {
90 for (int i = 0; i < NUM_LOOPS; i++) {
91 FAIL_IF((write(fd1[WRITE_FD], &c, 1)) != 1);
92 FAIL_IF((read(fd2[READ_FD], &c, 1)) != 1);
93 /* A paste succeeds if CR0 EQ bit is set */
94 FAIL_IF(paste(buf) & 0x20000000);
96 } else {
97 for (int i = 0; i < NUM_LOOPS; i++) {
98 FAIL_IF((read(fd1[READ_FD], &c, 1)) != 1);
99 copy(buf);
100 FAIL_IF((write(fd2[WRITE_FD], &c, 1) != 1));
103 return 0;
107 int main(int argc, char *argv[])
109 return test_harness(test_cp_abort, "cp_abort");