#define VALIDATION_NO_THRESHOLD 0      /* Verify the entire region */
 
 #define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
+#define SIZE_MB(m) ((size_t)m * (1024 * 1024))
 
 struct config {
        unsigned long long src_alignment;
                ksft_test_result_fail("%s\n", test_name);
 }
 
+/*
+ * Verify that an mremap within a range does not cause corruption
+ * of unrelated part of range.
+ *
+ * Consider the following range which is 2MB aligned and is
+ * a part of a larger 20MB range which is not shown. Each
+ * character is 256KB below making the source and destination
+ * 2MB each. The lower case letters are moved (s to d) and the
+ * upper case letters are not moved. The below test verifies
+ * that the upper case S letters are not corrupted by the
+ * adjacent mremap.
+ *
+ * |DDDDddddSSSSssss|
+ */
+static void mremap_move_within_range(char pattern_seed)
+{
+       char *test_name = "mremap mremap move within range";
+       void *src, *dest;
+       int i, success = 1;
+
+       size_t size = SIZE_MB(20);
+       void *ptr = mmap(NULL, size, PROT_READ | PROT_WRITE,
+                        MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+       if (ptr == MAP_FAILED) {
+               perror("mmap");
+               success = 0;
+               goto out;
+       }
+       memset(ptr, 0, size);
+
+       src = ptr + SIZE_MB(6);
+       src = (void *)((unsigned long)src & ~(SIZE_MB(2) - 1));
+
+       /* Set byte pattern for source block. */
+       srand(pattern_seed);
+       for (i = 0; i < SIZE_MB(2); i++) {
+               ((char *)src)[i] = (char) rand();
+       }
+
+       dest = src - SIZE_MB(2);
+
+       void *new_ptr = mremap(src + SIZE_MB(1), SIZE_MB(1), SIZE_MB(1),
+                                                  MREMAP_MAYMOVE | MREMAP_FIXED, dest + SIZE_MB(1));
+       if (new_ptr == MAP_FAILED) {
+               perror("mremap");
+               success = 0;
+               goto out;
+       }
+
+       /* Verify byte pattern after remapping */
+       srand(pattern_seed);
+       for (i = 0; i < SIZE_MB(1); i++) {
+               char c = (char) rand();
+
+               if (((char *)src)[i] != c) {
+                       ksft_print_msg("Data at src at %d got corrupted due to unrelated mremap\n",
+                                      i);
+                       ksft_print_msg("Expected: %#x\t Got: %#x\n", c & 0xff,
+                                       ((char *) src)[i] & 0xff);
+                       success = 0;
+               }
+       }
+
+out:
+       if (munmap(ptr, size) == -1)
+               perror("munmap");
+
+       if (success)
+               ksft_test_result_pass("%s\n", test_name);
+       else
+               ksft_test_result_fail("%s\n", test_name);
+}
+
 /*
  * Returns the start address of the mapping on success, else returns
  * NULL on failure.
        unsigned int threshold_mb = VALIDATION_DEFAULT_THRESHOLD;
        unsigned int pattern_seed;
        int num_expand_tests = 2;
+       int num_misc_tests = 1;
        struct test test_cases[MAX_TEST] = {};
        struct test perf_test_cases[MAX_PERF_TEST];
        int page_size;
                                (threshold_mb * _1MB >= _1GB);
 
        ksft_set_plan(ARRAY_SIZE(test_cases) + (run_perf_tests ?
-                     ARRAY_SIZE(perf_test_cases) : 0) + num_expand_tests);
+                     ARRAY_SIZE(perf_test_cases) : 0) + num_expand_tests + num_misc_tests);
 
        for (i = 0; i < ARRAY_SIZE(test_cases); i++)
                run_mremap_test_case(test_cases[i], &failures, threshold_mb,
 
        fclose(maps_fp);
 
+       mremap_move_within_range(pattern_seed);
+
        if (run_perf_tests) {
                ksft_print_msg("\n%s\n",
                 "mremap HAVE_MOVE_PMD/PUD optimization time comparison for 1GB region:");