forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
powerpc/selftests: add test for papr-sysparm
Consistently testing system parameter access is a bit difficult by nature -- the set of parameters available depends on the model and system configuration, and updating a parameter should be considered a destructive operation reserved for the admin. So we validate some of the error paths and retrieve the SPLPAR characteristics string, but not much else. Signed-off-by: Nathan Lynch <[email protected]>
- Loading branch information
1 parent
aa06898
commit 4787873
Showing
4 changed files
with
178 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,6 +33,7 @@ SUB_DIRS = alignment \ | |
math \ | ||
papr_attributes \ | ||
papr_vpd \ | ||
papr_sysparm \ | ||
ptrace \ | ||
security \ | ||
mce | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/papr_sysparm |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# SPDX-License-Identifier: GPL-2.0 | ||
noarg: | ||
$(MAKE) -C ../ | ||
|
||
TEST_GEN_PROGS := papr_sysparm | ||
|
||
top_srcdir = ../../../../.. | ||
include ../../lib.mk | ||
|
||
$(TEST_GEN_PROGS): ../harness.c ../utils.c | ||
|
||
$(OUTPUT)/papr_sysparm: CFLAGS += $(KHDR_INCLUDES) |
164 changes: 164 additions & 0 deletions
164
tools/testing/selftests/powerpc/papr_sysparm/papr_sysparm.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
// SPDX-License-Identifier: GPL-2.0-only | ||
#include <errno.h> | ||
#include <fcntl.h> | ||
#include <stdlib.h> | ||
#include <sys/ioctl.h> | ||
#include <unistd.h> | ||
#include <asm/papr-sysparm.h> | ||
|
||
#include "utils.h" | ||
|
||
#define DEVPATH "/dev/papr-sysparm" | ||
|
||
static int open_close(void) | ||
{ | ||
const int devfd = open(DEVPATH, O_RDONLY); | ||
|
||
SKIP_IF_MSG(devfd < 0 && errno == ENOENT, | ||
DEVPATH " not present"); | ||
|
||
FAIL_IF(devfd < 0); | ||
FAIL_IF(close(devfd) != 0); | ||
|
||
return 0; | ||
} | ||
|
||
static int get_splpar(void) | ||
{ | ||
struct papr_sysparm_io_block sp = { | ||
.parameter = 20, // SPLPAR characteristics | ||
}; | ||
const int devfd = open(DEVPATH, O_RDONLY); | ||
|
||
SKIP_IF_MSG(devfd < 0 && errno == ENOENT, | ||
DEVPATH " not present"); | ||
|
||
FAIL_IF(devfd < 0); | ||
FAIL_IF(ioctl(devfd, PAPR_SYSPARM_IOC_GET, &sp) != 0); | ||
FAIL_IF(sp.length == 0); | ||
FAIL_IF(sp.length > sizeof(sp.data)); | ||
FAIL_IF(close(devfd) != 0); | ||
|
||
return 0; | ||
} | ||
|
||
static int get_bad_parameter(void) | ||
{ | ||
struct papr_sysparm_io_block sp = { | ||
.parameter = UINT32_MAX, // there are only ~60 specified parameters | ||
}; | ||
const int devfd = open(DEVPATH, O_RDONLY); | ||
|
||
SKIP_IF_MSG(devfd < 0 && errno == ENOENT, | ||
DEVPATH " not present"); | ||
|
||
FAIL_IF(devfd < 0); | ||
|
||
// Ensure expected error | ||
FAIL_IF(ioctl(devfd, PAPR_SYSPARM_IOC_GET, &sp) != -1); | ||
FAIL_IF(errno != EOPNOTSUPP); | ||
|
||
// Ensure the buffer is unchanged | ||
FAIL_IF(sp.length != 0); | ||
for (size_t i = 0; i < ARRAY_SIZE(sp.data); ++i) | ||
FAIL_IF(sp.data[i] != 0); | ||
|
||
FAIL_IF(close(devfd) != 0); | ||
|
||
return 0; | ||
} | ||
|
||
static int check_efault_common(unsigned long cmd) | ||
{ | ||
const int devfd = open(DEVPATH, O_RDONLY); | ||
|
||
SKIP_IF_MSG(devfd < 0 && errno == ENOENT, | ||
DEVPATH " not present"); | ||
|
||
FAIL_IF(devfd < 0); | ||
|
||
// Ensure expected error | ||
FAIL_IF(ioctl(devfd, cmd, NULL) != -1); | ||
FAIL_IF(errno != EFAULT); | ||
|
||
FAIL_IF(close(devfd) != 0); | ||
|
||
return 0; | ||
} | ||
|
||
static int check_efault_get(void) | ||
{ | ||
return check_efault_common(PAPR_SYSPARM_IOC_GET); | ||
} | ||
|
||
static int check_efault_set(void) | ||
{ | ||
return check_efault_common(PAPR_SYSPARM_IOC_SET); | ||
} | ||
|
||
static int set_hmc0(void) | ||
{ | ||
struct papr_sysparm_io_block sp = { | ||
.parameter = 0, // HMC0, not a settable parameter | ||
}; | ||
const int devfd = open(DEVPATH, O_RDONLY); | ||
|
||
SKIP_IF_MSG(devfd < 0 && errno == ENOENT, | ||
DEVPATH " not present"); | ||
|
||
FAIL_IF(devfd < 0); | ||
|
||
// Ensure expected error | ||
FAIL_IF(ioctl(devfd, PAPR_SYSPARM_IOC_SET, &sp) != -1); | ||
FAIL_IF(errno != EPERM); | ||
|
||
FAIL_IF(close(devfd) != 0); | ||
|
||
return 0; | ||
} | ||
|
||
struct sysparm_test { | ||
int (*function)(void); | ||
const char *description; | ||
}; | ||
|
||
static const struct sysparm_test sysparm_tests[] = { | ||
{ | ||
.function = open_close, | ||
.description = "open and close " DEVPATH " without issuing commands", | ||
}, | ||
{ | ||
.function = get_splpar, | ||
.description = "retrieve SPLPAR characteristics", | ||
}, | ||
{ | ||
.function = get_bad_parameter, | ||
.description = "verify EOPNOTSUPP for known-bad parameter", | ||
}, | ||
{ | ||
.function = check_efault_get, | ||
.description = "PAPR_SYSPARM_IOC_GET returns EFAULT on bad address", | ||
}, | ||
{ | ||
.function = check_efault_set, | ||
.description = "PAPR_SYSPARM_IOC_SET returns EFAULT on bad address", | ||
}, | ||
{ | ||
.function = set_hmc0, | ||
.description = "ensure EPERM on attempt to update HMC0", | ||
}, | ||
}; | ||
|
||
int main(void) | ||
{ | ||
size_t fails = 0; | ||
|
||
for (size_t i = 0; i < ARRAY_SIZE(sysparm_tests); ++i) { | ||
const struct sysparm_test *t = &sysparm_tests[i]; | ||
|
||
if (test_harness(t->function, t->description)) | ||
++fails; | ||
} | ||
|
||
return fails == 0 ? EXIT_SUCCESS : EXIT_FAILURE; | ||
} |