[PATCH] selftests/powerpc: Test cp_abort during context switch

Cyril Bur cyrilbur at gmail.com
Mon May 2 19:13:44 AEST 2016


On Mon, 2 May 2016 13:51:38 +1000
Chris Smart <chris at distroguy.com> wrote:

> Test that performing a copy paste sequence in userspace on P9 does not
> result in a leak of the copy into the paste of another process.
> 
> This is based on Anton Blanchard's context_switch benchmarking code. It
> sets up two processes tied to the same CPU, one which copies and one
> which pastes.
> 
> The paste should never succeed and the test fails if it does.
> 
> This is a test for commit, "8a64904 powerpc: Add support for userspace
> P9 copy paste."
> 

Hi Chris,

I must admit I didn't run on it on real hardware ;).

Looks good.

> Patch created with much assistance from Michael Neuling
> <mikey at neuling.org>
> 
> Signed-off-by: Chris Smart <chris at distroguy.com>

Reviewed-by: Cyril Bur <cyrilbur at gmail.com>

> ---
>  tools/testing/selftests/powerpc/Makefile           |   1 +
>  .../selftests/powerpc/context_switch/.gitignore    |   1 +
>  .../selftests/powerpc/context_switch/Makefile      |  10 ++
>  .../selftests/powerpc/context_switch/cp_abort.c    | 110 +++++++++++++++++++++
>  tools/testing/selftests/powerpc/utils.h            |   7 ++
>  5 files changed, 129 insertions(+)
>  create mode 100644 tools/testing/selftests/powerpc/context_switch/.gitignore
>  create mode 100644 tools/testing/selftests/powerpc/context_switch/Makefile
>  create mode 100644 tools/testing/selftests/powerpc/context_switch/cp_abort.c
> 
> diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile
> index b08f77cbe31b..4ca83fe80654 100644
> --- a/tools/testing/selftests/powerpc/Makefile
> +++ b/tools/testing/selftests/powerpc/Makefile
> @@ -14,6 +14,7 @@ export CFLAGS
>  
>  SUB_DIRS = benchmarks 		\
>  	   copyloops		\
> +	   context_switch	\
>  	   dscr			\
>  	   mm			\
>  	   pmu			\
> diff --git a/tools/testing/selftests/powerpc/context_switch/.gitignore b/tools/testing/selftests/powerpc/context_switch/.gitignore
> new file mode 100644
> index 000000000000..c1431af7b51c
> --- /dev/null
> +++ b/tools/testing/selftests/powerpc/context_switch/.gitignore
> @@ -0,0 +1 @@
> +cp_abort
> diff --git a/tools/testing/selftests/powerpc/context_switch/Makefile b/tools/testing/selftests/powerpc/context_switch/Makefile
> new file mode 100644
> index 000000000000..e164d1466466
> --- /dev/null
> +++ b/tools/testing/selftests/powerpc/context_switch/Makefile
> @@ -0,0 +1,10 @@
> +TEST_PROGS := cp_abort
> +
> +all: $(TEST_PROGS)
> +
> +$(TEST_PROGS): ../harness.c ../utils.c
> +
> +include ../../lib.mk
> +
> +clean:
> +	rm -f $(TEST_PROGS)
> diff --git a/tools/testing/selftests/powerpc/context_switch/cp_abort.c b/tools/testing/selftests/powerpc/context_switch/cp_abort.c
> new file mode 100644
> index 000000000000..5a5b55afda0e
> --- /dev/null
> +++ b/tools/testing/selftests/powerpc/context_switch/cp_abort.c
> @@ -0,0 +1,110 @@
> +/*
> + * Adapted from Anton Blanchard's context switch microbenchmark.
> + *
> + * Copyright 2009, Anton Blanchard, IBM Corporation.
> + * Copyright 2016, Mikey Neuling, Chris Smart, IBM Corporation.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or (at your option) any later version.
> + *
> + * This program tests the copy paste abort functionality of a P9
> + * (or later) by setting up two processes on the same CPU, one
> + * which executes the copy instruction and the other which
> + * executes paste.
> + *
> + * The paste instruction should never succeed, as the cp_abort
> + * instruction is called by the kernel during a context switch.
> + *
> + */
> +
> +#define _GNU_SOURCE
> +
> +#include <stdio.h>
> +#include <unistd.h>
> +#include <stdlib.h>
> +#include "utils.h"
> +#include <sched.h>
> +
> +#define READ_FD 0
> +#define WRITE_FD 1
> +
> +#define NUM_LOOPS 1000
> +
> +/* This defines the "paste" instruction from Power ISA 3.0 Book II, section 4.4. */
> +#define PASTE(RA, RB, L, RC) \
> +	.long (0x7c00070c | (RA) << (31-15) | (RB) << (31-20) | (L) << (31-10) | (RC) << (31-31))
> +
> +int paste(void *i)
> +{
> +	int cr;
> +
> +	asm volatile(str(PASTE(0, %1, 1, 1))";"
> +			"mfcr %0;"
> +			: "=r" (cr)
> +			: "b" (i)
> +			: "memory"
> +		    );
> +	return cr;
> +}
> +
> +/* This defines the "copy" instruction from Power ISA 3.0 Book II, section 4.4. */
> +#define COPY(RA, RB, L) \
> +	.long (0x7c00060c | (RA) << (31-15) | (RB) << (31-20) | (L) << (31-10))
> +
> +void copy(void *i)
> +{
> +	asm volatile(str(COPY(0, %0, 1))";"
> +			:
> +			: "b" (i)
> +			: "memory"
> +		    );
> +}
> +
> +int test_cp_abort(void)
> +{
> +	/* 128 bytes for a full cache line */
> +	char buf[128] __cacheline_aligned;
> +	cpu_set_t cpuset;
> +	int fd1[2], fd2[2], pid;
> +	char c;
> +
> +	/* only run this test on a P9 or later */
> +	SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_00));
> +
> +	/*
> +	 * Run both processes on the same CPU, so that copy is more likely
> +	 * to leak into a paste.
> +	 */
> +	CPU_ZERO(&cpuset);
> +	CPU_SET(pick_online_cpu(), &cpuset);
> +	FAIL_IF(sched_setaffinity(0, sizeof(cpuset), &cpuset));
> +
> +	FAIL_IF(pipe(fd1) || pipe(fd2));
> +
> +	pid = fork();
> +	FAIL_IF(pid < 0);
> +
> +	if (!pid) {
> +		for (int i = 0; i < NUM_LOOPS; i++) {
> +			FAIL_IF((write(fd1[WRITE_FD], &c, 1)) != 1);
> +			FAIL_IF((read(fd2[READ_FD], &c, 1)) != 1);
> +			/* A paste succeeds if CR0 EQ bit is set */
> +			FAIL_IF(paste(buf) & 0x20000000);
> +		}
> +	} else {
> +		for (int i = 0; i < NUM_LOOPS; i++) {
> +			FAIL_IF((read(fd1[READ_FD], &c, 1)) != 1);
> +			copy(buf);
> +			FAIL_IF((write(fd2[WRITE_FD], &c, 1) != 1));
> +		}
> +	}
> +	return 0;
> +
> +}
> +
> +int main(int argc, char *argv[])
> +{
> +	return test_harness(test_cp_abort, "cp_abort");
> +}
> diff --git a/tools/testing/selftests/powerpc/utils.h b/tools/testing/selftests/powerpc/utils.h
> index 175ac6ad10dd..3b370deafb62 100644
> --- a/tools/testing/selftests/powerpc/utils.h
> +++ b/tools/testing/selftests/powerpc/utils.h
> @@ -6,6 +6,8 @@
>  #ifndef _SELFTESTS_POWERPC_UTILS_H
>  #define _SELFTESTS_POWERPC_UTILS_H
>  
> +#define __cacheline_aligned __attribute__((aligned(128)))
> +
>  #include <stdint.h>
>  #include <stdbool.h>
>  #include <linux/auxvec.h>
> @@ -54,4 +56,9 @@ do {								\
>  #define _str(s) #s
>  #define str(s) _str(s)
>  
> +/* POWER9 feature */
> +#ifndef PPC_FEATURE2_ARCH_3_00
> +#define PPC_FEATURE2_ARCH_3_00 0x00800000
> +#endif
> +
>  #endif /* _SELFTESTS_POWERPC_UTILS_H */



More information about the Linuxppc-dev mailing list