diff options
author | Tony Luck <tony.luck@intel.com> | 2021-11-16 10:32:26 -0800 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2021-11-16 10:44:13 -0800 |
commit | 6f2cde4f206f8f52a6d7363853cfe70b3f2ebb83 (patch) | |
tree | 0d865b2fc4124e568b6d683220ef044cbfc598c4 | |
parent | 82002d1d1472a42dbfc1007614b3ca6c001b3121 (diff) | |
download | mce-test-6f2cde4f206f8f52a6d7363853cfe70b3f2ebb83.tar.gz |
Add wrapper to madvise() calls to handle new kernel error code
Upstream kernel changed the return value from madvise(2) in the case
where a page is already poisoned in v5.13 with
commit 47af12bae17f ("mm,hwpoison: return -EHWPOISON to denote that the page has already been poisoned")
Check for the EHWPOISON error code and treat the same as success.
Signed-off-by: Tony Luck <tony.luck@intel.com>
-rw-r--r-- | cases/function/hwpoison/tinjpage.c | 9 | ||||
-rw-r--r-- | cases/function/hwpoison/tprctl.c | 10 | ||||
-rw-r--r-- | cases/function/hwpoison/tsimpleinj.c | 9 | ||||
-rw-r--r-- | cases/function/hwpoison/ttranshuge.c | 10 | ||||
-rw-r--r-- | cases/stress/hwpoison/tools/page-poisoning/page-poisoning.c | 9 |
5 files changed, 42 insertions, 5 deletions
diff --git a/cases/function/hwpoison/tinjpage.c b/cases/function/hwpoison/tinjpage.c index ec6dd66..4d5c064 100644 --- a/cases/function/hwpoison/tinjpage.c +++ b/cases/function/hwpoison/tinjpage.c @@ -42,6 +42,13 @@ #define MADV_POISON 100 +static int madvise_poison(void *addr, size_t length, int advice) +{ + int ret = madvise(addr, length, advice); + + return (ret == -1 && errno == EHWPOISON) ? 0 : ret; +} + #define TMPDIR "./" #define PATHBUFLEN 100 @@ -165,7 +172,7 @@ enum rmode { void inject_madvise(char *page) { - if (madvise(page, PS, MADV_POISON) != 0) { + if (madvise_poison(page, PS, MADV_POISON) != 0) { if (errno == EINVAL) { printf("Kernel doesn't support poison injection\n"); exit(0); diff --git a/cases/function/hwpoison/tprctl.c b/cases/function/hwpoison/tprctl.c index bcc1e49..d07e9d2 100644 --- a/cases/function/hwpoison/tprctl.c +++ b/cases/function/hwpoison/tprctl.c @@ -7,6 +7,7 @@ #include <sys/prctl.h> #include <setjmp.h> #include <signal.h> +#include <errno.h> #define err(x) perror("FAILURE: " x), exit(1) #define fail(x) printf("FAILURE: " x "\n"), exit(1) @@ -14,6 +15,13 @@ #define MADV_POISON 100 +static int madvise_poison(void *addr, size_t length, int advice) +{ + int ret = madvise(addr, length, advice); + + return (ret == -1 && errno == EHWPOISON) ? 0 : ret; +} + /* * Set early/late kill mode for hwpoison memory corruption. * This influences when the process gets killed on a memory corruption. @@ -48,7 +56,7 @@ void test(int early) if (sigsetjmp(recover_ctx, 1) == 0) { seq = 0; printf("injection\n"); - if (madvise(ptr, PS, MADV_POISON) < 0) + if (madvise_poison(ptr, PS, MADV_POISON) < 0) err("MADV_POISON"); /* early kill should kill here */ seq++; diff --git a/cases/function/hwpoison/tsimpleinj.c b/cases/function/hwpoison/tsimpleinj.c index 164ee50..04a57d9 100644 --- a/cases/function/hwpoison/tsimpleinj.c +++ b/cases/function/hwpoison/tsimpleinj.c @@ -18,6 +18,13 @@ #define MADV_POISON 100 +static int madvise_poison(void *addr, size_t length, int advice) +{ + int ret = madvise(addr, length, advice); + + return (ret == -1 && errno == EHWPOISON) ? 0 : ret; +} + #define err(x) perror(x),exit(1) int count = 20; @@ -41,7 +48,7 @@ void testmem(char *msg, char *page, int write) printf("%s page %p\n", msg, page); total_cases++; if (sigsetjmp(recover,1) == 0) { - if (madvise(page, PS, MADV_POISON) != 0) { + if (madvise_poison(page, PS, MADV_POISON) != 0) { failure++; perror("madvise"); } diff --git a/cases/function/hwpoison/ttranshuge.c b/cases/function/hwpoison/ttranshuge.c index 7d77b7c..411cb6c 100644 --- a/cases/function/hwpoison/ttranshuge.c +++ b/cases/function/hwpoison/ttranshuge.c @@ -53,6 +53,7 @@ #include <unistd.h> #include <getopt.h> #include <signal.h> +#include <errno.h> #include <sys/prctl.h> #include <sys/mman.h> @@ -74,6 +75,13 @@ #define MADV_POISON 100 #define MADV_HUGEPAGE 14 +static int madvise_poison(void *addr, size_t length, int advice) +{ + int ret = madvise(addr, length, advice); + + return (ret == -1 && errno == EHWPOISON) ? 0 : ret; +} + #define PR_MCE_KILL 33 #define PR_MCE_KILL_SET 1 #define PR_MCE_KILL_EARLY 1 @@ -249,7 +257,7 @@ static int prep_injection(void) static int do_injection(void) { /* Early Kill */ - if (madvise((void *)corrupt_page_addr, DEFAULT_PS, MADV_POISON) != 0) { + if (madvise_poison((void *)corrupt_page_addr, DEFAULT_PS, MADV_POISON) != 0) { print_err("Failed to poison at 0x%p.\n", corrupt_page_addr); printf("[INFO] Please check the authority of current user.\n"); return THP_FAILURE; diff --git a/cases/stress/hwpoison/tools/page-poisoning/page-poisoning.c b/cases/stress/hwpoison/tools/page-poisoning/page-poisoning.c index 153a452..56ff232 100644 --- a/cases/stress/hwpoison/tools/page-poisoning/page-poisoning.c +++ b/cases/stress/hwpoison/tools/page-poisoning/page-poisoning.c @@ -44,6 +44,13 @@ #define MADV_POISON 100 +static int madvise_poison(void *addr, size_t length, int advice) +{ + int ret = madvise(addr, length, advice); + + return (ret == -1 && errno == EHWPOISON) ? 0 : ret; +} + #define PAGE_SIZE 4 * 1024 #define SHM_SIZE 1 // in page_size. #define SHM_MODE 0600 @@ -249,7 +256,7 @@ static void poison(char *msg, char *page, enum rmode mode, enum test_case tc) recovercount = 5; if (sigsetjmp(early_recover_ctx, 1) == 0) { - if (madvise(page, PS, MADV_POISON) != 0) { + if (madvise_poison(page, PS, MADV_POISON) != 0) { if (errno == EINVAL) { result("failed: Kernel doesn't support poison injection\n"); exit(0); |