106 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright 2015, Michael Neuling, IBM Corp.4 *5 * Original: Michael Neuling 4/12/20136 * Edited: Rashmica Gupta 4/12/20157 *8 * See if the altivec state is leaked out of an aborted transaction due to9 * kernel vmx copy loops.10 *11 * When the transaction aborts, VSR values should rollback to the values12 * they held before the transaction commenced. Using VSRs while transaction13 * is suspended should not affect the checkpointed values.14 *15 * (1) write A to a VSR16 * (2) start transaction17 * (3) suspend transaction18 * (4) change the VSR to B19 * (5) trigger kernel vmx copy loop20 * (6) abort transaction21 * (7) check that the VSR value is A22 */23 24#include <inttypes.h>25#include <stdio.h>26#include <stdlib.h>27#include <unistd.h>28#include <sys/mman.h>29#include <string.h>30#include <assert.h>31 32#include "tm.h"33#include "utils.h"34 35int test_vmxcopy()36{37 long double vecin = 1.3;38 long double vecout;39 unsigned long pgsize = getpagesize();40 int i;41 int fd;42 int size = pgsize*16;43 char tmpfile[] = "/tmp/page_faultXXXXXX";44 char buf[pgsize];45 char *a;46 uint64_t aborted = 0;47 48 SKIP_IF(!have_htm());49 SKIP_IF(htm_is_synthetic());50 SKIP_IF(!is_ppc64le());51 52 fd = mkstemp(tmpfile);53 assert(fd >= 0);54 55 memset(buf, 0, pgsize);56 for (i = 0; i < size; i += pgsize)57 assert(write(fd, buf, pgsize) == pgsize);58 59 unlink(tmpfile);60 61 a = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);62 assert(a != MAP_FAILED);63 64 asm __volatile__(65 "lxvd2x 40,0,%[vecinptr];" /* set 40 to initial value*/66 "tbegin.;"67 "beq 3f;"68 "tsuspend.;"69 "xxlxor 40,40,40;" /* set 40 to 0 */70 "std 5, 0(%[map]);" /* cause kernel vmx copy page */71 "tabort. 0;"72 "tresume.;"73 "tend.;"74 "li %[res], 0;"75 "b 5f;"76 77 /* Abort handler */78 "3:;"79 "li %[res], 1;"80 81 "5:;"82 "stxvd2x 40,0,%[vecoutptr];"83 : [res]"=&r"(aborted)84 : [vecinptr]"r"(&vecin),85 [vecoutptr]"r"(&vecout),86 [map]"r"(a)87 : "memory", "r0", "r3", "r4", "r5", "r6", "r7");88 89 if (aborted && (vecin != vecout)){90 printf("FAILED: vector state leaked on abort %f != %f\n",91 (double)vecin, (double)vecout);92 return 1;93 }94 95 munmap(a, size);96 97 close(fd);98 99 return 0;100}101 102int main(void)103{104 return test_harness(test_vmxcopy, "tm_vmxcopy");105}106