mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-20 13:41:30 +00:00
powerpc updates for 4.1
- Numerous minor fixes, cleanups etc. - More EEH work from Gavin to remove its dependency on device_nodes. - Memory hotplug implemented entirely in the kernel from Nathan Fontenot. - Removal of redundant CONFIG_PPC_OF by Kevin Hao. - Rewrite of VPHN parsing logic & tests from Greg Kurz. - A fix from Nish Aravamudan to reduce memory usage by clamping nodes_possible_map. - Support for pstore on powernv from Hari Bathini. - Removal of old powerpc specific byte swap routines by David Gibson. - Fix from Vasant Hegde to prevent the flash driver telling you it was flashing your firmware when it wasn't. - Patch from Ben Herrenschmidt to add an OPAL heartbeat driver. - Fix for an oops causing get/put_cpu_var() imbalance in perf by Jan Stancek. - Some fixes for migration from Tyrel Datwyler. - A new syscall to switch the cpu endian by Michael Ellerman. - Large series from Wei Yang to implement SRIOV, reviewed and acked by Bjorn. - A fix for the OPAL sensor driver from Cédric Le Goater. - Fixes to get STRICT_MM_TYPECHECKS building again by Michael Ellerman. - Large series from Daniel Axtens to make our PCI hooks per PHB rather than per machine. - Small patch from Sam Bobroff to explicitly abort non-suspended transactions on syscalls, plus a test to exercise it. - Numerous reworks and fixes for the 24x7 PMU from Sukadev Bhattiprolu. - Small patch to enable the hard lockup detector from Anton Blanchard. - Fix from Dave Olson for missing L2 cache information on some CPUs. - Some fixes from Michael Ellerman to get Cell machines booting again. - Freescale updates from Scott: Highlights include BMan device tree nodes, an MSI erratum workaround, a couple minor performance improvements, config updates, and misc fixes/cleanup. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJVL2cxAAoJEFHr6jzI4aWAR8cP/19VTo/CzCE4ffPSx7qR464n F+WFZcbNjIMXu6+B0YLuJZEsuWtKKrCit/MCg3+mSgE4iqvxmtI+HDD0445Buszj UD4E4HMdPrXQ+KUSUDORvRjv/FFUXIa94LSv/0g2UeMsPz/HeZlhMxEu7AkXw9Nf rTxsmRTsOWME85Y/c9ss7XHuWKXT3DJV7fOoK9roSaN3dJAuWTtG3WaKS0nUu0ok 0M81D6ZczoD6ybwh2DUMPD9K6SGxLdQ4OzQwtW6vWzcQIBDfy5Pdeo0iAFhGPvXf T4LLPkv4cF4AwHsAC4rKDPHQNa+oZBoLlScrHClaebAlDiv+XYKNdMogawUObvSh h7avKmQr0Ygp1OvvZAaXLhuDJI9FJJ8lf6AOIeULgHsDR9SyKMjZWxRzPe11uarO Fyi0qj3oJaQu6LjazZraApu8mo+JBtQuD3z3o5GhLxeFtBBF60JXj6zAXJikufnl kk1/BUF10nKUhtKcDX767AMUCtMH3fp5hx8K/z9T5v+pobJB26Wup1bbdT68pNBT NjdKUppV6QTjZvCsA6U2/ECu6E9KeIaFtFSL2IRRoiI0dWBN5/5eYn3RGkO2ZFoL 1NdwKA2XJcchwTPkpSRrUG70sYH0uM2AldNYyaLfjzrQqza7Y6lF699ilxWmCN/H OplzJAE5cQ8Am078veTW =03Yh -----END PGP SIGNATURE----- Merge tag 'powerpc-4.1-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mpe/linux Pull powerpc updates from Michael Ellerman: - Numerous minor fixes, cleanups etc. - More EEH work from Gavin to remove its dependency on device_nodes. - Memory hotplug implemented entirely in the kernel from Nathan Fontenot. - Removal of redundant CONFIG_PPC_OF by Kevin Hao. - Rewrite of VPHN parsing logic & tests from Greg Kurz. - A fix from Nish Aravamudan to reduce memory usage by clamping nodes_possible_map. - Support for pstore on powernv from Hari Bathini. - Removal of old powerpc specific byte swap routines by David Gibson. - Fix from Vasant Hegde to prevent the flash driver telling you it was flashing your firmware when it wasn't. - Patch from Ben Herrenschmidt to add an OPAL heartbeat driver. - Fix for an oops causing get/put_cpu_var() imbalance in perf by Jan Stancek. - Some fixes for migration from Tyrel Datwyler. - A new syscall to switch the cpu endian by Michael Ellerman. - Large series from Wei Yang to implement SRIOV, reviewed and acked by Bjorn. - A fix for the OPAL sensor driver from Cédric Le Goater. - Fixes to get STRICT_MM_TYPECHECKS building again by Michael Ellerman. - Large series from Daniel Axtens to make our PCI hooks per PHB rather than per machine. - Small patch from Sam Bobroff to explicitly abort non-suspended transactions on syscalls, plus a test to exercise it. - Numerous reworks and fixes for the 24x7 PMU from Sukadev Bhattiprolu. - Small patch to enable the hard lockup detector from Anton Blanchard. - Fix from Dave Olson for missing L2 cache information on some CPUs. - Some fixes from Michael Ellerman to get Cell machines booting again. - Freescale updates from Scott: Highlights include BMan device tree nodes, an MSI erratum workaround, a couple minor performance improvements, config updates, and misc fixes/cleanup. * tag 'powerpc-4.1-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mpe/linux: (196 commits) powerpc/powermac: Fix build error seen with powermac smp builds powerpc/pseries: Fix compile of memory hotplug without CONFIG_MEMORY_HOTREMOVE powerpc: Remove PPC32 code from pseries specific find_and_init_phbs() powerpc/cell: Fix iommu breakage caused by controller_ops change powerpc/eeh: Fix crash in eeh_add_device_early() on Cell powerpc/perf: Cap 64bit userspace backtraces to PERF_MAX_STACK_DEPTH powerpc/perf/hv-24x7: Fail 24x7 initcall if create_events_from_catalog() fails powerpc/pseries: Correct memory hotplug locking powerpc: Fix missing L2 cache size in /sys/devices/system/cpu powerpc: Add ppc64 hard lockup detector support oprofile: Disable oprofile NMI timer on ppc64 powerpc/perf/hv-24x7: Add missing put_cpu_var() powerpc/perf/hv-24x7: Break up single_24x7_request powerpc/perf/hv-24x7: Define update_event_count() powerpc/perf/hv-24x7: Whitespace cleanup powerpc/perf/hv-24x7: Define add_event_to_24x7_request() powerpc/perf/hv-24x7: Rename hv_24x7_event_update powerpc/perf/hv-24x7: Move debug prints to separate function powerpc/perf/hv-24x7: Drop event_24x7_request() powerpc/perf/hv-24x7: Use pr_devel() to log message ... Conflicts: tools/testing/selftests/powerpc/Makefile tools/testing/selftests/powerpc/tm/Makefile
This commit is contained in:
commit
d19d5efd8c
299 changed files with 8765 additions and 9770 deletions
|
@ -12,37 +12,37 @@ CFLAGS := -Wall -O2 -flto -Wall -Werror -DGIT_VERSION='"$(GIT_VERSION)"' -I$(CUR
|
|||
|
||||
export CFLAGS
|
||||
|
||||
TARGETS = pmu copyloops mm tm primitives stringloops
|
||||
SUB_DIRS = pmu copyloops mm tm primitives stringloops vphn switch_endian
|
||||
|
||||
endif
|
||||
|
||||
all: $(TARGETS)
|
||||
all: $(SUB_DIRS)
|
||||
|
||||
$(TARGETS):
|
||||
$(SUB_DIRS):
|
||||
$(MAKE) -k -C $@ all
|
||||
|
||||
include ../lib.mk
|
||||
|
||||
override define RUN_TESTS
|
||||
@for TARGET in $(TARGETS); do \
|
||||
@for TARGET in $(SUB_DIRS); do \
|
||||
$(MAKE) -C $$TARGET run_tests; \
|
||||
done;
|
||||
endef
|
||||
|
||||
override define INSTALL_RULE
|
||||
@for TARGET in $(TARGETS); do \
|
||||
@for TARGET in $(SUB_DIRS); do \
|
||||
$(MAKE) -C $$TARGET install; \
|
||||
done;
|
||||
endef
|
||||
|
||||
override define EMIT_TESTS
|
||||
@for TARGET in $(TARGETS); do \
|
||||
@for TARGET in $(SUB_DIRS); do \
|
||||
$(MAKE) -s -C $$TARGET emit_tests; \
|
||||
done;
|
||||
endef
|
||||
|
||||
clean:
|
||||
@for TARGET in $(TARGETS); do \
|
||||
@for TARGET in $(SUB_DIRS); do \
|
||||
$(MAKE) -C $$TARGET clean; \
|
||||
done;
|
||||
rm -f tags
|
||||
|
@ -50,4 +50,4 @@ clean:
|
|||
tags:
|
||||
find . -name '*.c' -o -name '*.h' | xargs ctags
|
||||
|
||||
.PHONY: tags $(TARGETS)
|
||||
.PHONY: tags $(SUB_DIRS)
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
CFLAGS += -m64
|
||||
CFLAGS += -I$(CURDIR)
|
||||
CFLAGS += -D SELFTEST
|
||||
CFLAGS += -maltivec
|
||||
|
||||
# Use our CFLAGS for the implicit .S rule
|
||||
ASFLAGS = $(CFLAGS)
|
||||
|
|
|
@ -4,39 +4,6 @@
|
|||
|
||||
#define r1 1
|
||||
|
||||
#define vr0 0
|
||||
#define vr1 1
|
||||
#define vr2 2
|
||||
#define vr3 3
|
||||
#define vr4 4
|
||||
#define vr5 5
|
||||
#define vr6 6
|
||||
#define vr7 7
|
||||
#define vr8 8
|
||||
#define vr9 9
|
||||
#define vr10 10
|
||||
#define vr11 11
|
||||
#define vr12 12
|
||||
#define vr13 13
|
||||
#define vr14 14
|
||||
#define vr15 15
|
||||
#define vr16 16
|
||||
#define vr17 17
|
||||
#define vr18 18
|
||||
#define vr19 19
|
||||
#define vr20 20
|
||||
#define vr21 21
|
||||
#define vr22 22
|
||||
#define vr23 23
|
||||
#define vr24 24
|
||||
#define vr25 25
|
||||
#define vr26 26
|
||||
#define vr27 27
|
||||
#define vr28 28
|
||||
#define vr29 29
|
||||
#define vr30 30
|
||||
#define vr31 31
|
||||
|
||||
#define R14 r14
|
||||
#define R15 r15
|
||||
#define R16 r16
|
||||
|
|
|
@ -11,6 +11,10 @@
|
|||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#include <elf.h>
|
||||
#include <fcntl.h>
|
||||
#include <link.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "subunit.h"
|
||||
#include "utils.h"
|
||||
|
@ -112,3 +116,46 @@ int test_harness(int (test_function)(void), char *name)
|
|||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static char auxv[4096];
|
||||
|
||||
void *get_auxv_entry(int type)
|
||||
{
|
||||
ElfW(auxv_t) *p;
|
||||
void *result;
|
||||
ssize_t num;
|
||||
int fd;
|
||||
|
||||
fd = open("/proc/self/auxv", O_RDONLY);
|
||||
if (fd == -1) {
|
||||
perror("open");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = NULL;
|
||||
|
||||
num = read(fd, auxv, sizeof(auxv));
|
||||
if (num < 0) {
|
||||
perror("read");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (num > sizeof(auxv)) {
|
||||
printf("Overflowed auxv buffer\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
p = (ElfW(auxv_t) *)auxv;
|
||||
|
||||
while (p->a_type != AT_NULL) {
|
||||
if (p->a_type == type) {
|
||||
result = (void *)p->a_un.a_val;
|
||||
break;
|
||||
}
|
||||
|
||||
p++;
|
||||
}
|
||||
out:
|
||||
close(fd);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -5,15 +5,10 @@
|
|||
|
||||
#define _GNU_SOURCE /* For CPU_ZERO etc. */
|
||||
|
||||
#include <elf.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <link.h>
|
||||
#include <sched.h>
|
||||
#include <setjmp.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
@ -256,45 +251,3 @@ out:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static char auxv[4096];
|
||||
|
||||
void *get_auxv_entry(int type)
|
||||
{
|
||||
ElfW(auxv_t) *p;
|
||||
void *result;
|
||||
ssize_t num;
|
||||
int fd;
|
||||
|
||||
fd = open("/proc/self/auxv", O_RDONLY);
|
||||
if (fd == -1) {
|
||||
perror("open");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = NULL;
|
||||
|
||||
num = read(fd, auxv, sizeof(auxv));
|
||||
if (num < 0) {
|
||||
perror("read");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (num > sizeof(auxv)) {
|
||||
printf("Overflowed auxv buffer\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
p = (ElfW(auxv_t) *)auxv;
|
||||
|
||||
while (p->a_type != AT_NULL) {
|
||||
if (p->a_type == type) {
|
||||
result = (void *)p->a_un.a_val;
|
||||
break;
|
||||
}
|
||||
|
||||
p++;
|
||||
}
|
||||
out:
|
||||
close(fd);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@ extern int notify_parent(union pipe write_pipe);
|
|||
extern int notify_parent_of_error(union pipe write_pipe);
|
||||
extern pid_t eat_cpu(int (test_function)(void));
|
||||
extern bool require_paranoia_below(int level);
|
||||
extern void *get_auxv_entry(int type);
|
||||
|
||||
struct addr_range {
|
||||
uint64_t first, last;
|
||||
|
|
2
tools/testing/selftests/powerpc/switch_endian/.gitignore
vendored
Normal file
2
tools/testing/selftests/powerpc/switch_endian/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
switch_endian_test
|
||||
check-reversed.S
|
24
tools/testing/selftests/powerpc/switch_endian/Makefile
Normal file
24
tools/testing/selftests/powerpc/switch_endian/Makefile
Normal file
|
@ -0,0 +1,24 @@
|
|||
CC := $(CROSS_COMPILE)gcc
|
||||
PROGS := switch_endian_test
|
||||
|
||||
ASFLAGS += -O2 -Wall -g -nostdlib -m64
|
||||
|
||||
all: $(PROGS)
|
||||
|
||||
switch_endian_test: check-reversed.S
|
||||
|
||||
check-reversed.o: check.o
|
||||
$(CROSS_COMPILE)objcopy -j .text --reverse-bytes=4 -O binary $< $@
|
||||
|
||||
check-reversed.S: check-reversed.o
|
||||
hexdump -v -e '/1 ".byte 0x%02X\n"' $< > $@
|
||||
|
||||
run_tests: all
|
||||
@-for PROG in $(PROGS); do \
|
||||
./$$PROG; \
|
||||
done;
|
||||
|
||||
clean:
|
||||
rm -f $(PROGS) *.o check-reversed.S
|
||||
|
||||
.PHONY: all run_tests clean
|
100
tools/testing/selftests/powerpc/switch_endian/check.S
Normal file
100
tools/testing/selftests/powerpc/switch_endian/check.S
Normal file
|
@ -0,0 +1,100 @@
|
|||
#include "common.h"
|
||||
|
||||
/*
|
||||
* Checks that registers contain what we expect, ie. they were not clobbered by
|
||||
* the syscall.
|
||||
*
|
||||
* r15: pattern to check registers against.
|
||||
*
|
||||
* At the end r3 == 0 if everything's OK.
|
||||
*/
|
||||
nop # guaranteed to be illegal in reverse-endian
|
||||
mr r9,r15
|
||||
cmpd r9,r3 # check r3
|
||||
bne 1f
|
||||
addi r9,r15,4 # check r4
|
||||
cmpd r9,r4
|
||||
bne 1f
|
||||
lis r9,0x00FF # check CR
|
||||
ori r9,r9,0xF000
|
||||
mfcr r10
|
||||
and r10,r10,r9
|
||||
cmpw r9,r10
|
||||
addi r9,r15,34
|
||||
bne 1f
|
||||
addi r9,r15,32 # check LR
|
||||
mflr r10
|
||||
cmpd r9,r10
|
||||
bne 1f
|
||||
addi r9,r15,5 # check r5
|
||||
cmpd r9,r5
|
||||
bne 1f
|
||||
addi r9,r15,6 # check r6
|
||||
cmpd r9,r6
|
||||
bne 1f
|
||||
addi r9,r15,7 # check r7
|
||||
cmpd r9,r7
|
||||
bne 1f
|
||||
addi r9,r15,8 # check r8
|
||||
cmpd r9,r8
|
||||
bne 1f
|
||||
addi r9,r15,13 # check r13
|
||||
cmpd r9,r13
|
||||
bne 1f
|
||||
addi r9,r15,14 # check r14
|
||||
cmpd r9,r14
|
||||
bne 1f
|
||||
addi r9,r15,16 # check r16
|
||||
cmpd r9,r16
|
||||
bne 1f
|
||||
addi r9,r15,17 # check r17
|
||||
cmpd r9,r17
|
||||
bne 1f
|
||||
addi r9,r15,18 # check r18
|
||||
cmpd r9,r18
|
||||
bne 1f
|
||||
addi r9,r15,19 # check r19
|
||||
cmpd r9,r19
|
||||
bne 1f
|
||||
addi r9,r15,20 # check r20
|
||||
cmpd r9,r20
|
||||
bne 1f
|
||||
addi r9,r15,21 # check r21
|
||||
cmpd r9,r21
|
||||
bne 1f
|
||||
addi r9,r15,22 # check r22
|
||||
cmpd r9,r22
|
||||
bne 1f
|
||||
addi r9,r15,23 # check r23
|
||||
cmpd r9,r23
|
||||
bne 1f
|
||||
addi r9,r15,24 # check r24
|
||||
cmpd r9,r24
|
||||
bne 1f
|
||||
addi r9,r15,25 # check r25
|
||||
cmpd r9,r25
|
||||
bne 1f
|
||||
addi r9,r15,26 # check r26
|
||||
cmpd r9,r26
|
||||
bne 1f
|
||||
addi r9,r15,27 # check r27
|
||||
cmpd r9,r27
|
||||
bne 1f
|
||||
addi r9,r15,28 # check r28
|
||||
cmpd r9,r28
|
||||
bne 1f
|
||||
addi r9,r15,29 # check r29
|
||||
cmpd r9,r29
|
||||
bne 1f
|
||||
addi r9,r15,30 # check r30
|
||||
cmpd r9,r30
|
||||
bne 1f
|
||||
addi r9,r15,31 # check r31
|
||||
cmpd r9,r31
|
||||
bne 1f
|
||||
b 2f
|
||||
1: mr r3, r9
|
||||
li r0, __NR_exit
|
||||
sc
|
||||
2: li r0, __NR_switch_endian
|
||||
nop
|
6
tools/testing/selftests/powerpc/switch_endian/common.h
Normal file
6
tools/testing/selftests/powerpc/switch_endian/common.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#include <ppc-asm.h>
|
||||
#include <asm/unistd.h>
|
||||
|
||||
#ifndef __NR_switch_endian
|
||||
#define __NR_switch_endian 363
|
||||
#endif
|
|
@ -0,0 +1,81 @@
|
|||
#include "common.h"
|
||||
|
||||
.data
|
||||
.balign 8
|
||||
message:
|
||||
.ascii "success: switch_endian_test\n\0"
|
||||
|
||||
.section ".toc"
|
||||
.balign 8
|
||||
pattern:
|
||||
.llong 0x5555AAAA5555AAAA
|
||||
|
||||
.text
|
||||
FUNC_START(_start)
|
||||
/* Load the pattern */
|
||||
ld r15, pattern@TOC(%r2)
|
||||
|
||||
/* Setup CR, only CR2-CR4 are maintained */
|
||||
lis r3, 0x00FF
|
||||
ori r3, r3, 0xF000
|
||||
mtcr r3
|
||||
|
||||
/* Load the pattern slightly modified into the registers */
|
||||
mr r3, r15
|
||||
addi r4, r15, 4
|
||||
|
||||
addi r5, r15, 32
|
||||
mtlr r5
|
||||
|
||||
addi r5, r15, 5
|
||||
addi r6, r15, 6
|
||||
addi r7, r15, 7
|
||||
addi r8, r15, 8
|
||||
|
||||
/* r9 - r12 are clobbered */
|
||||
|
||||
addi r13, r15, 13
|
||||
addi r14, r15, 14
|
||||
|
||||
/* Skip r15 we're using it */
|
||||
|
||||
addi r16, r15, 16
|
||||
addi r17, r15, 17
|
||||
addi r18, r15, 18
|
||||
addi r19, r15, 19
|
||||
addi r20, r15, 20
|
||||
addi r21, r15, 21
|
||||
addi r22, r15, 22
|
||||
addi r23, r15, 23
|
||||
addi r24, r15, 24
|
||||
addi r25, r15, 25
|
||||
addi r26, r15, 26
|
||||
addi r27, r15, 27
|
||||
addi r28, r15, 28
|
||||
addi r29, r15, 29
|
||||
addi r30, r15, 30
|
||||
addi r31, r15, 31
|
||||
|
||||
/*
|
||||
* Call the syscall to switch endian.
|
||||
* It clobbers r9-r12, XER, CTR and CR0-1,5-7.
|
||||
*/
|
||||
li r0, __NR_switch_endian
|
||||
sc
|
||||
|
||||
#include "check-reversed.S"
|
||||
|
||||
/* Flip back, r0 already has the switch syscall number */
|
||||
.long 0x02000044 /* sc */
|
||||
|
||||
#include "check.S"
|
||||
|
||||
li r0, __NR_write
|
||||
li r3, 1 /* stdout */
|
||||
ld r4, message@got(%r2)
|
||||
li r5, 28 /* strlen(message3) */
|
||||
sc
|
||||
li r0, __NR_exit
|
||||
li r3, 0
|
||||
sc
|
||||
b .
|
|
@ -1 +1,2 @@
|
|||
tm-resched-dscr
|
||||
tm-syscall
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
TEST_PROGS := tm-resched-dscr
|
||||
TEST_PROGS := tm-resched-dscr tm-syscall
|
||||
|
||||
all: $(TEST_PROGS)
|
||||
|
||||
$(TEST_PROGS): ../harness.c
|
||||
|
||||
tm-syscall: tm-syscall-asm.S
|
||||
tm-syscall: CFLAGS += -mhtm
|
||||
|
||||
include ../../lib.mk
|
||||
|
||||
clean:
|
||||
|
|
27
tools/testing/selftests/powerpc/tm/tm-syscall-asm.S
Normal file
27
tools/testing/selftests/powerpc/tm/tm-syscall-asm.S
Normal file
|
@ -0,0 +1,27 @@
|
|||
#include <ppc-asm.h>
|
||||
#include <asm/unistd.h>
|
||||
|
||||
.text
|
||||
FUNC_START(getppid_tm_active)
|
||||
tbegin.
|
||||
beq 1f
|
||||
li r0, __NR_getppid
|
||||
sc
|
||||
tend.
|
||||
blr
|
||||
1:
|
||||
li r3, -1
|
||||
blr
|
||||
|
||||
FUNC_START(getppid_tm_suspended)
|
||||
tbegin.
|
||||
beq 1f
|
||||
li r0, __NR_getppid
|
||||
tsuspend.
|
||||
sc
|
||||
tresume.
|
||||
tend.
|
||||
blr
|
||||
1:
|
||||
li r3, -1
|
||||
blr
|
121
tools/testing/selftests/powerpc/tm/tm-syscall.c
Normal file
121
tools/testing/selftests/powerpc/tm/tm-syscall.c
Normal file
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* Copyright 2015, Sam Bobroff, IBM Corp.
|
||||
* Licensed under GPLv2.
|
||||
*
|
||||
* Test the kernel's system call code to ensure that a system call
|
||||
* made from within an active HTM transaction is aborted with the
|
||||
* correct failure code.
|
||||
* Conversely, ensure that a system call made from within a
|
||||
* suspended transaction can succeed.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <asm/tm.h>
|
||||
#include <asm/cputable.h>
|
||||
#include <linux/auxvec.h>
|
||||
#include <sys/time.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
extern int getppid_tm_active(void);
|
||||
extern int getppid_tm_suspended(void);
|
||||
|
||||
unsigned retries = 0;
|
||||
|
||||
#define TEST_DURATION 10 /* seconds */
|
||||
#define TM_RETRIES 100
|
||||
|
||||
long failure_code(void)
|
||||
{
|
||||
return __builtin_get_texasru() >> 24;
|
||||
}
|
||||
|
||||
bool failure_is_persistent(void)
|
||||
{
|
||||
return (failure_code() & TM_CAUSE_PERSISTENT) == TM_CAUSE_PERSISTENT;
|
||||
}
|
||||
|
||||
bool failure_is_syscall(void)
|
||||
{
|
||||
return (failure_code() & TM_CAUSE_SYSCALL) == TM_CAUSE_SYSCALL;
|
||||
}
|
||||
|
||||
pid_t getppid_tm(bool suspend)
|
||||
{
|
||||
int i;
|
||||
pid_t pid;
|
||||
|
||||
for (i = 0; i < TM_RETRIES; i++) {
|
||||
if (suspend)
|
||||
pid = getppid_tm_suspended();
|
||||
else
|
||||
pid = getppid_tm_active();
|
||||
|
||||
if (pid >= 0)
|
||||
return pid;
|
||||
|
||||
if (failure_is_persistent()) {
|
||||
if (failure_is_syscall())
|
||||
return -1;
|
||||
|
||||
printf("Unexpected persistent transaction failure.\n");
|
||||
printf("TEXASR 0x%016lx, TFIAR 0x%016lx.\n",
|
||||
__builtin_get_texasr(), __builtin_get_tfiar());
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
retries++;
|
||||
}
|
||||
|
||||
printf("Exceeded limit of %d temporary transaction failures.\n", TM_RETRIES);
|
||||
printf("TEXASR 0x%016lx, TFIAR 0x%016lx.\n",
|
||||
__builtin_get_texasr(), __builtin_get_tfiar());
|
||||
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
int tm_syscall(void)
|
||||
{
|
||||
unsigned count = 0;
|
||||
struct timeval end, now;
|
||||
|
||||
SKIP_IF(!((long)get_auxv_entry(AT_HWCAP2) & PPC_FEATURE2_HTM));
|
||||
setbuf(stdout, NULL);
|
||||
|
||||
printf("Testing transactional syscalls for %d seconds...\n", TEST_DURATION);
|
||||
|
||||
gettimeofday(&end, NULL);
|
||||
now.tv_sec = TEST_DURATION;
|
||||
now.tv_usec = 0;
|
||||
timeradd(&end, &now, &end);
|
||||
|
||||
for (count = 0; timercmp(&now, &end, <); count++) {
|
||||
/*
|
||||
* Test a syscall within a suspended transaction and verify
|
||||
* that it succeeds.
|
||||
*/
|
||||
FAIL_IF(getppid_tm(true) == -1); /* Should succeed. */
|
||||
|
||||
/*
|
||||
* Test a syscall within an active transaction and verify that
|
||||
* it fails with the correct failure code.
|
||||
*/
|
||||
FAIL_IF(getppid_tm(false) != -1); /* Should fail... */
|
||||
FAIL_IF(!failure_is_persistent()); /* ...persistently... */
|
||||
FAIL_IF(!failure_is_syscall()); /* ...with code syscall. */
|
||||
gettimeofday(&now, 0);
|
||||
}
|
||||
|
||||
printf("%d active and suspended transactions behaved correctly.\n", count);
|
||||
printf("(There were %d transaction retries.)\n", retries);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return test_harness(tm_syscall, "tm_syscall");
|
||||
}
|
|
@ -15,11 +15,12 @@ typedef signed long long s64;
|
|||
|
||||
/* Just for familiarity */
|
||||
typedef uint32_t u32;
|
||||
typedef uint16_t u16;
|
||||
typedef uint8_t u8;
|
||||
|
||||
|
||||
int test_harness(int (test_function)(void), char *name);
|
||||
|
||||
extern void *get_auxv_entry(int type);
|
||||
|
||||
/* Yes, this is evil */
|
||||
#define FAIL_IF(x) \
|
||||
|
|
1
tools/testing/selftests/powerpc/vphn/.gitignore
vendored
Normal file
1
tools/testing/selftests/powerpc/vphn/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
test-vphn
|
15
tools/testing/selftests/powerpc/vphn/Makefile
Normal file
15
tools/testing/selftests/powerpc/vphn/Makefile
Normal file
|
@ -0,0 +1,15 @@
|
|||
PROG := test-vphn
|
||||
|
||||
CFLAGS += -m64
|
||||
|
||||
all: $(PROG)
|
||||
|
||||
$(PROG): ../harness.c
|
||||
|
||||
run_tests: all
|
||||
./$(PROG)
|
||||
|
||||
clean:
|
||||
rm -f $(PROG)
|
||||
|
||||
.PHONY: all run_tests clean
|
410
tools/testing/selftests/powerpc/vphn/test-vphn.c
Normal file
410
tools/testing/selftests/powerpc/vphn/test-vphn.c
Normal file
|
@ -0,0 +1,410 @@
|
|||
#include <stdio.h>
|
||||
#include <byteswap.h>
|
||||
#include "utils.h"
|
||||
#include "subunit.h"
|
||||
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
#define cpu_to_be32(x) bswap_32(x)
|
||||
#define be32_to_cpu(x) bswap_32(x)
|
||||
#define be16_to_cpup(x) bswap_16(*x)
|
||||
#define cpu_to_be64(x) bswap_64(x)
|
||||
#else
|
||||
#define cpu_to_be32(x) (x)
|
||||
#define be32_to_cpu(x) (x)
|
||||
#define be16_to_cpup(x) (*x)
|
||||
#define cpu_to_be64(x) (x)
|
||||
#endif
|
||||
|
||||
#include "vphn.c"
|
||||
|
||||
static struct test {
|
||||
char *descr;
|
||||
long input[VPHN_REGISTER_COUNT];
|
||||
u32 expected[VPHN_ASSOC_BUFSIZE];
|
||||
} all_tests[] = {
|
||||
{
|
||||
"vphn: no data",
|
||||
{
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
},
|
||||
{
|
||||
0x00000000
|
||||
}
|
||||
},
|
||||
{
|
||||
"vphn: 1 x 16-bit value",
|
||||
{
|
||||
0x8001ffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
},
|
||||
{
|
||||
0x00000001,
|
||||
0x00000001
|
||||
}
|
||||
},
|
||||
{
|
||||
"vphn: 2 x 16-bit values",
|
||||
{
|
||||
0x80018002ffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
},
|
||||
{
|
||||
0x00000002,
|
||||
0x00000001,
|
||||
0x00000002
|
||||
}
|
||||
},
|
||||
{
|
||||
"vphn: 3 x 16-bit values",
|
||||
{
|
||||
0x800180028003ffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
},
|
||||
{
|
||||
0x00000003,
|
||||
0x00000001,
|
||||
0x00000002,
|
||||
0x00000003
|
||||
}
|
||||
},
|
||||
{
|
||||
"vphn: 4 x 16-bit values",
|
||||
{
|
||||
0x8001800280038004,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
},
|
||||
{
|
||||
0x00000004,
|
||||
0x00000001,
|
||||
0x00000002,
|
||||
0x00000003,
|
||||
0x00000004
|
||||
}
|
||||
},
|
||||
{
|
||||
/* Parsing the next 16-bit value out of the next 64-bit input
|
||||
* value.
|
||||
*/
|
||||
"vphn: 5 x 16-bit values",
|
||||
{
|
||||
0x8001800280038004,
|
||||
0x8005ffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
},
|
||||
{
|
||||
0x00000005,
|
||||
0x00000001,
|
||||
0x00000002,
|
||||
0x00000003,
|
||||
0x00000004,
|
||||
0x00000005
|
||||
}
|
||||
},
|
||||
{
|
||||
/* Parse at most 6 x 64-bit input values */
|
||||
"vphn: 24 x 16-bit values",
|
||||
{
|
||||
0x8001800280038004,
|
||||
0x8005800680078008,
|
||||
0x8009800a800b800c,
|
||||
0x800d800e800f8010,
|
||||
0x8011801280138014,
|
||||
0x8015801680178018
|
||||
},
|
||||
{
|
||||
0x00000018,
|
||||
0x00000001,
|
||||
0x00000002,
|
||||
0x00000003,
|
||||
0x00000004,
|
||||
0x00000005,
|
||||
0x00000006,
|
||||
0x00000007,
|
||||
0x00000008,
|
||||
0x00000009,
|
||||
0x0000000a,
|
||||
0x0000000b,
|
||||
0x0000000c,
|
||||
0x0000000d,
|
||||
0x0000000e,
|
||||
0x0000000f,
|
||||
0x00000010,
|
||||
0x00000011,
|
||||
0x00000012,
|
||||
0x00000013,
|
||||
0x00000014,
|
||||
0x00000015,
|
||||
0x00000016,
|
||||
0x00000017,
|
||||
0x00000018
|
||||
}
|
||||
},
|
||||
{
|
||||
"vphn: 1 x 32-bit value",
|
||||
{
|
||||
0x00000001ffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff
|
||||
},
|
||||
{
|
||||
0x00000001,
|
||||
0x00000001
|
||||
}
|
||||
},
|
||||
{
|
||||
"vphn: 2 x 32-bit values",
|
||||
{
|
||||
0x0000000100000002,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff
|
||||
},
|
||||
{
|
||||
0x00000002,
|
||||
0x00000001,
|
||||
0x00000002
|
||||
}
|
||||
},
|
||||
{
|
||||
/* Parsing the next 32-bit value out of the next 64-bit input
|
||||
* value.
|
||||
*/
|
||||
"vphn: 3 x 32-bit values",
|
||||
{
|
||||
0x0000000100000002,
|
||||
0x00000003ffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff
|
||||
},
|
||||
{
|
||||
0x00000003,
|
||||
0x00000001,
|
||||
0x00000002,
|
||||
0x00000003
|
||||
}
|
||||
},
|
||||
{
|
||||
/* Parse at most 6 x 64-bit input values */
|
||||
"vphn: 12 x 32-bit values",
|
||||
{
|
||||
0x0000000100000002,
|
||||
0x0000000300000004,
|
||||
0x0000000500000006,
|
||||
0x0000000700000008,
|
||||
0x000000090000000a,
|
||||
0x0000000b0000000c
|
||||
},
|
||||
{
|
||||
0x0000000c,
|
||||
0x00000001,
|
||||
0x00000002,
|
||||
0x00000003,
|
||||
0x00000004,
|
||||
0x00000005,
|
||||
0x00000006,
|
||||
0x00000007,
|
||||
0x00000008,
|
||||
0x00000009,
|
||||
0x0000000a,
|
||||
0x0000000b,
|
||||
0x0000000c
|
||||
}
|
||||
},
|
||||
{
|
||||
"vphn: 16-bit value followed by 32-bit value",
|
||||
{
|
||||
0x800100000002ffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff
|
||||
},
|
||||
{
|
||||
0x00000002,
|
||||
0x00000001,
|
||||
0x00000002
|
||||
}
|
||||
},
|
||||
{
|
||||
"vphn: 32-bit value followed by 16-bit value",
|
||||
{
|
||||
0x000000018002ffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff
|
||||
},
|
||||
{
|
||||
0x00000002,
|
||||
0x00000001,
|
||||
0x00000002
|
||||
}
|
||||
},
|
||||
{
|
||||
/* Parse a 32-bit value split accross two consecutives 64-bit
|
||||
* input values.
|
||||
*/
|
||||
"vphn: 16-bit value followed by 2 x 32-bit values",
|
||||
{
|
||||
0x8001000000020000,
|
||||
0x0003ffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff
|
||||
},
|
||||
{
|
||||
0x00000003,
|
||||
0x00000001,
|
||||
0x00000002,
|
||||
0x00000003,
|
||||
0x00000004,
|
||||
0x00000005
|
||||
}
|
||||
},
|
||||
{
|
||||
/* The lower bits in 0x0001ffff don't get mixed up with the
|
||||
* 0xffff terminator.
|
||||
*/
|
||||
"vphn: 32-bit value has all ones in 16 lower bits",
|
||||
{
|
||||
0x0001ffff80028003,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff
|
||||
},
|
||||
{
|
||||
0x00000003,
|
||||
0x0001ffff,
|
||||
0x00000002,
|
||||
0x00000003
|
||||
}
|
||||
},
|
||||
{
|
||||
/* The following input doesn't follow the specification.
|
||||
*/
|
||||
"vphn: last 32-bit value is truncated",
|
||||
{
|
||||
0x0000000100000002,
|
||||
0x0000000300000004,
|
||||
0x0000000500000006,
|
||||
0x0000000700000008,
|
||||
0x000000090000000a,
|
||||
0x0000000b800c2bad
|
||||
},
|
||||
{
|
||||
0x0000000c,
|
||||
0x00000001,
|
||||
0x00000002,
|
||||
0x00000003,
|
||||
0x00000004,
|
||||
0x00000005,
|
||||
0x00000006,
|
||||
0x00000007,
|
||||
0x00000008,
|
||||
0x00000009,
|
||||
0x0000000a,
|
||||
0x0000000b,
|
||||
0x0000000c
|
||||
}
|
||||
},
|
||||
{
|
||||
"vphn: garbage after terminator",
|
||||
{
|
||||
0xffff2bad2bad2bad,
|
||||
0x2bad2bad2bad2bad,
|
||||
0x2bad2bad2bad2bad,
|
||||
0x2bad2bad2bad2bad,
|
||||
0x2bad2bad2bad2bad,
|
||||
0x2bad2bad2bad2bad
|
||||
},
|
||||
{
|
||||
0x00000000
|
||||
}
|
||||
},
|
||||
{
|
||||
NULL
|
||||
}
|
||||
};
|
||||
|
||||
static int test_one(struct test *test)
|
||||
{
|
||||
__be32 output[VPHN_ASSOC_BUFSIZE] = { 0 };
|
||||
int i, len;
|
||||
|
||||
vphn_unpack_associativity(test->input, output);
|
||||
|
||||
len = be32_to_cpu(output[0]);
|
||||
if (len != test->expected[0]) {
|
||||
printf("expected %d elements, got %d\n", test->expected[0],
|
||||
len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 1; i < len; i++) {
|
||||
u32 val = be32_to_cpu(output[i]);
|
||||
if (val != test->expected[i]) {
|
||||
printf("element #%d is 0x%x, should be 0x%x\n", i, val,
|
||||
test->expected[i]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_vphn(void)
|
||||
{
|
||||
static struct test *test;
|
||||
|
||||
for (test = all_tests; test->descr; test++) {
|
||||
int ret;
|
||||
|
||||
ret = test_one(test);
|
||||
test_finish(test->descr, ret);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
return test_harness(test_vphn, "test-vphn");
|
||||
}
|
1
tools/testing/selftests/powerpc/vphn/vphn.c
Symbolic link
1
tools/testing/selftests/powerpc/vphn/vphn.c
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../../../../arch/powerpc/mm/vphn.c
|
1
tools/testing/selftests/powerpc/vphn/vphn.h
Symbolic link
1
tools/testing/selftests/powerpc/vphn/vphn.h
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../../../../arch/powerpc/mm/vphn.h
|
Loading…
Add table
Add a link
Reference in a new issue