162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci
362306a36Sopenharmony_ci#include <errno.h>
462306a36Sopenharmony_ci#include <fcntl.h>
562306a36Sopenharmony_ci#include <signal.h>
662306a36Sopenharmony_ci#include <stdio.h>
762306a36Sopenharmony_ci#include <string.h>
862306a36Sopenharmony_ci#include <sys/ioctl.h>
962306a36Sopenharmony_ci#include <sys/mman.h>
1062306a36Sopenharmony_ci#include <sys/stat.h>
1162306a36Sopenharmony_ci#include <sys/types.h>
1262306a36Sopenharmony_ci#include <unistd.h>
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#include "vas-api.h"
1562306a36Sopenharmony_ci#include "utils.h"
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_cistatic bool faulted;
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_cistatic void sigbus_handler(int n, siginfo_t *info, void *ctxt_v)
2062306a36Sopenharmony_ci{
2162306a36Sopenharmony_ci	ucontext_t *ctxt = (ucontext_t *)ctxt_v;
2262306a36Sopenharmony_ci	struct pt_regs *regs = ctxt->uc_mcontext.regs;
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci	faulted = true;
2562306a36Sopenharmony_ci	regs->nip += 4;
2662306a36Sopenharmony_ci}
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_cistatic int test_ra_error(void)
2962306a36Sopenharmony_ci{
3062306a36Sopenharmony_ci	struct vas_tx_win_open_attr attr;
3162306a36Sopenharmony_ci	int fd, *paste_addr;
3262306a36Sopenharmony_ci	char *devname = "/dev/crypto/nx-gzip";
3362306a36Sopenharmony_ci	struct sigaction act = {
3462306a36Sopenharmony_ci		.sa_sigaction = sigbus_handler,
3562306a36Sopenharmony_ci		.sa_flags = SA_SIGINFO,
3662306a36Sopenharmony_ci	};
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci	memset(&attr, 0, sizeof(attr));
3962306a36Sopenharmony_ci	attr.version = 1;
4062306a36Sopenharmony_ci	attr.vas_id = 0;
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci	SKIP_IF(access(devname, F_OK));
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci	fd = open(devname, O_RDWR);
4562306a36Sopenharmony_ci	FAIL_IF(fd < 0);
4662306a36Sopenharmony_ci	FAIL_IF(ioctl(fd, VAS_TX_WIN_OPEN, &attr) < 0);
4762306a36Sopenharmony_ci	FAIL_IF(sigaction(SIGBUS, &act, NULL) != 0);
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci	paste_addr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0ULL);
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci	/* The following assignment triggers exception */
5262306a36Sopenharmony_ci	mb();
5362306a36Sopenharmony_ci	*paste_addr = 1;
5462306a36Sopenharmony_ci	mb();
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci	FAIL_IF(!faulted);
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci	return 0;
5962306a36Sopenharmony_ci}
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ciint main(void)
6262306a36Sopenharmony_ci{
6362306a36Sopenharmony_ci	return test_harness(test_ra_error, "inject-ra-err");
6462306a36Sopenharmony_ci}
6562306a36Sopenharmony_ci
66