diff --git a/runtest/hugetlb b/runtest/hugetlb
index 348a7dc5f..238ce6498 100644
--- a/runtest/hugetlb
+++ b/runtest/hugetlb
@@ -26,6 +26,7 @@ hugemmap20 hugemmap20
 hugemmap21 hugemmap21
 hugemmap22 hugemmap22
 hugemmap23 hugemmap23
+hugemmap23 hugemmap24
 hugemmap25 hugemmap25
 hugemmap26 hugemmap26
 hugemmap27 hugemmap27
diff --git a/testcases/kernel/mem/.gitignore b/testcases/kernel/mem/.gitignore
index 0c1311303..06e125d03 100644
--- a/testcases/kernel/mem/.gitignore
+++ b/testcases/kernel/mem/.gitignore
@@ -25,6 +25,7 @@
 /hugetlb/hugemmap/hugemmap21
 /hugetlb/hugemmap/hugemmap22
 /hugetlb/hugemmap/hugemmap23
+/hugetlb/hugemmap/hugemmap24
 /hugetlb/hugemmap/hugemmap25
 /hugetlb/hugemmap/hugemmap26
 /hugetlb/hugemmap/hugemmap27
diff --git a/testcases/kernel/mem/hugetlb/hugemmap/hugemmap24.c b/testcases/kernel/mem/hugetlb/hugemmap/hugemmap24.c
new file mode 100644
index 000000000..7e986a471
--- /dev/null
+++ b/testcases/kernel/mem/hugetlb/hugemmap/hugemmap24.c
@@ -0,0 +1,212 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+/*
+ * Copyright (C) 2009 IBM Corporation.
+ * Author: David Gibson
+ */
+
+/*\
+ * [Description]
+ *
+ * Kernel has bug in mremap for some architecture. mremap() can cause
+ * crashes on architectures with holes in the address space (like ia64)
+ * and on powerpc with it's distict page size slices.
+ *
+ * This test perform mremap() with normal and hugepages around powerpc
+ * slice boundary.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/mount.h>
+#include <limits.h>
+#include <sys/param.h>
+#include <sys/types.h>
+
+#include "tst_test.h"
+
+#define RANDOM_CONSTANT	0x1234ABCD
+#define MNTPOINT "hugetlbfs/"
+
+static int  fd = -1;
+static unsigned long slice_boundary;
+static long hpage_size, page_size;
+
+static int init_slice_boundary(int fd)
+{
+	unsigned long slice_size;
+	void *p, *heap;
+	int i;
+#if defined(__LP64__) && !defined(__aarch64__)
+	/* powerpc: 1TB slices starting at 1 TB */
+	slice_boundary = 0x10000000000;
+	slice_size = 0x10000000000;
+#else
+	/* powerpc: 256MB slices up to 4GB */
+	slice_boundary = 0x00000000;
+	slice_size = 0x10000000;
+#endif
+
+	/* dummy malloc so we know where is heap */
+	heap = malloc(1);
+	free(heap);
+
+	/* Find 2 neighbour slices with couple huge pages free
+	 * around slice boundary.
+	 * 16 is the maximum number of slices (low/high)
+	 */
+	for (i = 0; i < 16-1; i++) {
+		slice_boundary += slice_size;
+		p = mmap((void *)(slice_boundary-2*hpage_size), 4*hpage_size,
+			PROT_READ, MAP_SHARED | MAP_FIXED, fd, 0);
+		if (p == MAP_FAILED) {
+			tst_res(TINFO|TERRNO, "can't use slice_boundary: 0x%lx",
+					slice_boundary);
+		} else {
+			SAFE_MUNMAP(p, 4*hpage_size);
+			break;
+		}
+	}
+
+	if (p == MAP_FAILED) {
+		tst_res(TFAIL|TERRNO, "couldn't find 2 free neighbour slices");
+		return -1;
+	}
+	tst_res(TINFO, "using slice_boundary: 0x%lx", slice_boundary);
+	return 0;
+}
+
+static int do_readback(void *p, size_t size, const char *stage)
+{
+	unsigned int *q = p;
+	size_t i;
+
+	for (i = 0; i < (size / sizeof(*q)); i++)
+		q[i] = RANDOM_CONSTANT ^ i;
+
+	for (i = 0; i < (size / sizeof(*q)); i++) {
+		if (q[i] != (RANDOM_CONSTANT ^ i)) {
+			tst_res(TFAIL, "Stage \"%s\": Mismatch at offset 0x%lx: 0x%x instead of 0x%lx",
+			     stage, i, q[i], RANDOM_CONSTANT ^ i);
+			return -1;
+		}
+	}
+	return 0;
+}
+
+static void run_test(void)
+{
+	void *p = NULL, *q = NULL, *r;
+	long p_size, q_size;
+	int ret;
+
+	fd = tst_creat_unlinked(MNTPOINT, 0);
+	ret = init_slice_boundary(fd);
+	if (ret)
+		goto cleanup;
+
+	/* First, hugepages above, normal below */
+	tst_res(TINFO, "Testing with hpage above & normal below the slice_boundary");
+	p_size = hpage_size;
+	p = SAFE_MMAP((void *)(slice_boundary + hpage_size), p_size,
+		 PROT_READ | PROT_WRITE,
+		 MAP_SHARED | MAP_FIXED, fd, 0);
+
+	ret = do_readback(p, p_size, "huge above");
+	if (ret)
+		goto cleanup;
+
+	q_size = page_size;
+	q = SAFE_MMAP((void *)(slice_boundary - page_size), q_size,
+		 PROT_READ | PROT_WRITE,
+		 MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
+
+	ret = do_readback(q, q_size, "normal below");
+	if (ret)
+		goto cleanup;
+
+	r = mremap(q, page_size, 2*page_size, 0);
+	if (r == MAP_FAILED) {
+		tst_res(TINFO, "mremap(%p, %lu, %lu, 0) disallowed",
+				q, page_size, 2*page_size);
+	} else {
+		q_size = 2*page_size;
+		if (r != q) {
+			tst_res(TFAIL, "mremap() moved without MREMAP_MAYMOVE!?");
+			ret = -1;
+		} else
+			ret = do_readback(q, 2*page_size, "normal below expanded");
+	}
+
+	SAFE_MUNMAP(p, p_size);
+	SAFE_MUNMAP(q, q_size);
+	if (ret)
+		goto cleanup_fd;
+
+	/* Next, normal pages above, huge below */
+	tst_res(TINFO, "Testing with normal above & hpage below the slice_boundary");
+	p_size = page_size;
+	p = SAFE_MMAP((void *)(slice_boundary + hpage_size), p_size,
+		 PROT_READ|PROT_WRITE,
+		 MAP_SHARED | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
+
+	ret = do_readback(p, p_size, "normal above");
+	if (ret)
+		goto cleanup;
+
+	q_size = hpage_size;
+	q = SAFE_MMAP((void *)(slice_boundary - hpage_size),
+		 q_size, PROT_READ | PROT_WRITE,
+		 MAP_SHARED | MAP_FIXED, fd, 0);
+
+	ret = do_readback(q, q_size, "huge below");
+	if (ret)
+		goto cleanup;
+
+	r = mremap(q, hpage_size, 2*hpage_size, 0);
+	if (r == MAP_FAILED) {
+		tst_res(TINFO, "mremap(%p, %lu, %lu, 0) disallowed",
+				q, hpage_size, 2*hpage_size);
+	} else {
+		q_size = 2*hpage_size;
+		if (r != q) {
+			tst_res(TFAIL, "mremap() moved without MREMAP_MAYMOVE!?");
+			ret = -1;
+		} else
+			ret = do_readback(q, 2*hpage_size, "huge below expanded");
+	}
+	if (ret)
+		goto cleanup;
+	tst_res(TPASS, "Successful");
+cleanup:
+	if (p)
+		SAFE_MUNMAP(p, p_size);
+	if (q)
+		SAFE_MUNMAP(q, q_size);
+cleanup_fd:
+	SAFE_CLOSE(fd);
+}
+
+static void setup(void)
+{
+	hpage_size = SAFE_READ_MEMINFO(MEMINFO_HPAGE_SIZE)*1024;
+	page_size = getpagesize();
+}
+
+static void cleanup(void)
+{
+	if (fd >= 0)
+		SAFE_CLOSE(fd);
+}
+
+static struct tst_test test = {
+	.needs_root = 1,
+	.mntpoint = MNTPOINT,
+	.needs_hugetlbfs = 1,
+	.needs_tmpdir = 1,
+	.setup = setup,
+	.cleanup = cleanup,
+	.test_all = run_test,
+	.hugepages = {4, TST_NEEDS},
+};
