#include <errno.h>
#include <fcntl.h>
#include <signal.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static size_t page_sz;
static unsigned long ksm_sysfs[5];
+static bool has_merge_across_nodes;
+
+static bool merge_across_nodes_available(void)
+{
+ const char *path = PATH_KSM "merge_across_nodes";
+
+ if (!access(path, R_OK | W_OK))
+ return true;
+ if (errno == ENOENT)
+ return false;
+
+ ksft_exit_skip("Unable to read and write %s: %s\n", path,
+ strerror(errno));
+}
static unsigned long read_sysfs(char *str)
{
static void mte_ksm_setup(void)
{
- ksm_sysfs[0] = read_sysfs(PATH_KSM "merge_across_nodes");
- write_sysfs(PATH_KSM "merge_across_nodes", 1);
+ if (has_merge_across_nodes) {
+ ksm_sysfs[0] = read_sysfs(PATH_KSM "merge_across_nodes");
+ write_sysfs(PATH_KSM "merge_across_nodes", 1);
+ }
ksm_sysfs[1] = read_sysfs(PATH_KSM "sleep_millisecs");
write_sysfs(PATH_KSM "sleep_millisecs", 0);
ksm_sysfs[2] = read_sysfs(PATH_KSM "run");
static void mte_ksm_restore(void)
{
- write_sysfs(PATH_KSM "merge_across_nodes", ksm_sysfs[0]);
+ if (has_merge_across_nodes)
+ write_sysfs(PATH_KSM "merge_across_nodes", ksm_sysfs[0]);
write_sysfs(PATH_KSM "sleep_millisecs", ksm_sysfs[1]);
write_sysfs(PATH_KSM "run", ksm_sysfs[2]);
write_sysfs(PATH_KSM "max_page_sharing", ksm_sysfs[3]);
err = mte_default_setup();
if (err)
return err;
+
+ if (geteuid() != 0)
+ ksft_exit_skip("Please run the test as root\n");
+
+ has_merge_across_nodes = merge_across_nodes_available();
page_sz = getpagesize();
if (!page_sz) {
ksft_print_msg("ERR: Unable to get page size\n");