File: s390_pci_mmio_read_write.c

package info (click to toggle)
strace 6.13%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 71,488 kB
  • sloc: ansic: 176,497; sh: 9,675; makefile: 4,133; cpp: 885; awk: 353; perl: 267; exp: 62; sed: 9
file content (137 lines) | stat: -rw-r--r-- 3,011 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*
 * Check decoding of s390_pci_mmio_read and s390_pci_mmio_write syscalls.
 *
 * Copyright (c) 2018-2021 The strace developers.
 * All rights reserved.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

#include "tests.h"
#include "scno.h"

#if defined __NR_s390_pci_mmio_read && defined __NR_s390_pci_mmio_write

# include <errno.h>
# include <stdint.h>
# include <stdio.h>
# include <unistd.h>

static void
do_call(bool wr, kernel_ulong_t mmio_addr, kernel_ulong_t buf,
	kernel_ulong_t len, bool buf_valid, const char *buf_str)
{
	long saved_errno = 0;
	long rc = 0;

	printf("s390_pci_mmio_%s(%#llx, ", wr ? "write" : "read",
	       (unsigned long long) mmio_addr);

	if (!wr) {
		rc = syscall(__NR_s390_pci_mmio_read, mmio_addr, buf, len);
		saved_errno = errno;
	}

	if (buf_valid && !rc) {
		char *buf_ptr = (char *) (uintptr_t) buf;

		print_quoted_hex(buf_ptr,
				 len > DEFAULT_STRLEN ? DEFAULT_STRLEN : len);

		if (len > DEFAULT_STRLEN)
			printf("...");
	} else {
		if (buf_str)
			printf("%s", buf_str);
		else
			printf("%#llx", (unsigned long long) buf);
	}

	printf(", %llu) = ", (unsigned long long) len);

	if (wr)
		rc = syscall(__NR_s390_pci_mmio_write, mmio_addr, buf, len);
	else
		errno = saved_errno;

	puts(sprintrc(rc));
}

int
main(void)
{
	static const size_t buf_size = DEFAULT_STRLEN + 10;

	char *buf = tail_alloc(buf_size);

	bool bools[] = { true, false };

	kernel_ulong_t addrs[] = {
		0,
		(kernel_ulong_t) 0xdeafbeefdeadc0deULL,
	};

	struct {
		kernel_ulong_t buf;
		const char *str;
		size_t size;
	} bufs[] = {
		{ (kernel_ulong_t) ARG_STR(NULL),            0 },
		{ (kernel_ulong_t) (buf + buf_size), NULL,   0 },
		{ (kernel_ulong_t) (buf),            NULL,   buf_size },
		{ (kernel_ulong_t) (buf + 9),        NULL,   buf_size - 9 },
		{ (kernel_ulong_t) (buf + 10),       NULL,   buf_size - 10 },
		{ (kernel_ulong_t) (buf + 16),       NULL,   buf_size - 16 },
		{ (kernel_ulong_t) (buf + 26),       NULL,   buf_size - 26 },
		{ (kernel_ulong_t) (buf + 28),       NULL,   buf_size - 28 },
	};

	kernel_ulong_t sizes[] = {
		0,
		DEFAULT_STRLEN / 2,
		DEFAULT_STRLEN - 10,
		DEFAULT_STRLEN,
		DEFAULT_STRLEN + 1,
		buf_size,
		buf_size + 10,
		(kernel_ulong_t) 0xfacefeedac0ffeedULL,
	};

	unsigned int ctr = 0;

	for (unsigned int i = 0;
	     i < ARRAY_SIZE(addrs); ++i) {
		for (unsigned int j = 0;
		     j < ARRAY_SIZE(bufs); ++j) {
			for (unsigned int k = 0;
			     k < ARRAY_SIZE(sizes); ++k) {
				for (unsigned int l = 0;
				     l < ARRAY_SIZE(bools); ++l) {
					bool valid = bufs[j].buf &&
						bufs[j].size >=
						MIN(sizes[k],
						    DEFAULT_STRLEN + 1);

					if (bufs[j].size && bools[l])
						fill_memory_ex((char *) buf,
							       bufs[j].size,
							       0xC0 + ctr, 255);

					do_call(bools[l], addrs[i], bufs[j].buf,
						sizes[k], valid, bufs[j].str);

					ctr++;
				}
			}
		}
	}

	puts("+++ exited with 0 +++");
	return 0;
}

#else

SKIP_MAIN_UNDEFINED("__NR_s390_pci_mmio_read && __NR_s390_pci_mmio_write");

#endif