aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTony Luck <tony.luck@intel.com>2021-11-16 10:32:26 -0800
committerTony Luck <tony.luck@intel.com>2021-11-16 10:44:13 -0800
commit6f2cde4f206f8f52a6d7363853cfe70b3f2ebb83 (patch)
tree0d865b2fc4124e568b6d683220ef044cbfc598c4
parent82002d1d1472a42dbfc1007614b3ca6c001b3121 (diff)
downloadmce-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.c9
-rw-r--r--cases/function/hwpoison/tprctl.c10
-rw-r--r--cases/function/hwpoison/tsimpleinj.c9
-rw-r--r--cases/function/hwpoison/ttranshuge.c10
-rw-r--r--cases/stress/hwpoison/tools/page-poisoning/page-poisoning.c9
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);