brintos

brintos / linux-shallow public Read only

0
0
Text · 4.2 KiB · f56c15a Raw
197 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2#include <errno.h>3#include <fcntl.h>4#include <stdlib.h>5#include <sys/ioctl.h>6#include <unistd.h>7#include <asm/papr-sysparm.h>8 9#include "utils.h"10 11#define DEVPATH "/dev/papr-sysparm"12 13static int open_close(void)14{15	const int devfd = open(DEVPATH, O_RDONLY);16 17	SKIP_IF_MSG(devfd < 0 && errno == ENOENT,18		    DEVPATH " not present");19 20	FAIL_IF(devfd < 0);21	FAIL_IF(close(devfd) != 0);22 23	return 0;24}25 26static int get_splpar(void)27{28	struct papr_sysparm_io_block sp = {29		.parameter = 20, // SPLPAR characteristics30	};31	const int devfd = open(DEVPATH, O_RDONLY);32 33	SKIP_IF_MSG(devfd < 0 && errno == ENOENT,34		    DEVPATH " not present");35 36	FAIL_IF(devfd < 0);37	FAIL_IF(ioctl(devfd, PAPR_SYSPARM_IOC_GET, &sp) != 0);38	FAIL_IF(sp.length == 0);39	FAIL_IF(sp.length > sizeof(sp.data));40	FAIL_IF(close(devfd) != 0);41 42	return 0;43}44 45static int get_bad_parameter(void)46{47	struct papr_sysparm_io_block sp = {48		.parameter = UINT32_MAX, // there are only ~60 specified parameters49	};50	const int devfd = open(DEVPATH, O_RDONLY);51 52	SKIP_IF_MSG(devfd < 0 && errno == ENOENT,53		    DEVPATH " not present");54 55	FAIL_IF(devfd < 0);56 57	// Ensure expected error58	FAIL_IF(ioctl(devfd, PAPR_SYSPARM_IOC_GET, &sp) != -1);59	FAIL_IF(errno != EOPNOTSUPP);60 61	// Ensure the buffer is unchanged62	FAIL_IF(sp.length != 0);63	for (size_t i = 0; i < ARRAY_SIZE(sp.data); ++i)64		FAIL_IF(sp.data[i] != 0);65 66	FAIL_IF(close(devfd) != 0);67 68	return 0;69}70 71static int check_efault_common(unsigned long cmd)72{73	const int devfd = open(DEVPATH, O_RDWR);74 75	SKIP_IF_MSG(devfd < 0 && errno == ENOENT,76		    DEVPATH " not present");77 78	FAIL_IF(devfd < 0);79 80	// Ensure expected error81	FAIL_IF(ioctl(devfd, cmd, NULL) != -1);82	FAIL_IF(errno != EFAULT);83 84	FAIL_IF(close(devfd) != 0);85 86	return 0;87}88 89static int check_efault_get(void)90{91	return check_efault_common(PAPR_SYSPARM_IOC_GET);92}93 94static int check_efault_set(void)95{96	return check_efault_common(PAPR_SYSPARM_IOC_SET);97}98 99static int set_hmc0(void)100{101	struct papr_sysparm_io_block sp = {102		.parameter = 0, // HMC0, not a settable parameter103	};104	const int devfd = open(DEVPATH, O_RDWR);105 106	SKIP_IF_MSG(devfd < 0 && errno == ENOENT,107		    DEVPATH " not present");108 109	FAIL_IF(devfd < 0);110 111	// Ensure expected error112	FAIL_IF(ioctl(devfd, PAPR_SYSPARM_IOC_SET, &sp) != -1);113	SKIP_IF_MSG(errno == EOPNOTSUPP, "operation not supported");114	FAIL_IF(errno != EPERM);115 116	FAIL_IF(close(devfd) != 0);117 118	return 0;119}120 121static int set_with_ro_fd(void)122{123	struct papr_sysparm_io_block sp = {124		.parameter = 0, // HMC0, not a settable parameter.125	};126	const int devfd = open(DEVPATH, O_RDONLY);127 128	SKIP_IF_MSG(devfd < 0 && errno == ENOENT,129		    DEVPATH " not present");130 131	FAIL_IF(devfd < 0);132 133	// Ensure expected error134	FAIL_IF(ioctl(devfd, PAPR_SYSPARM_IOC_SET, &sp) != -1);135	SKIP_IF_MSG(errno == EOPNOTSUPP, "operation not supported");136 137	// HMC0 isn't a settable parameter and we would normally138	// expect to get EPERM on attempts to modify it. However, when139	// the file is open read-only, we expect the driver to prevent140	// the attempt with a distinct error.141	FAIL_IF(errno != EBADF);142 143	FAIL_IF(close(devfd) != 0);144 145	return 0;146}147 148struct sysparm_test {149	int (*function)(void);150	const char *description;151};152 153static const struct sysparm_test sysparm_tests[] = {154	{155		.function = open_close,156		.description = "open and close " DEVPATH " without issuing commands",157	},158	{159		.function = get_splpar,160		.description = "retrieve SPLPAR characteristics",161	},162	{163		.function = get_bad_parameter,164		.description = "verify EOPNOTSUPP for known-bad parameter",165	},166	{167		.function = check_efault_get,168		.description = "PAPR_SYSPARM_IOC_GET returns EFAULT on bad address",169	},170	{171		.function = check_efault_set,172		.description = "PAPR_SYSPARM_IOC_SET returns EFAULT on bad address",173	},174	{175		.function = set_hmc0,176		.description = "ensure EPERM on attempt to update HMC0",177	},178	{179		.function = set_with_ro_fd,180		.description = "PAPR_IOC_SYSPARM_SET returns EACCES on read-only fd",181	},182};183 184int main(void)185{186	size_t fails = 0;187 188	for (size_t i = 0; i < ARRAY_SIZE(sysparm_tests); ++i) {189		const struct sysparm_test *t = &sysparm_tests[i];190 191		if (test_harness(t->function, t->description))192			++fails;193	}194 195	return fails == 0 ? EXIT_SUCCESS : EXIT_FAILURE;196}197