~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/kvm/s390x/shared_zeropage_test.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 /*
  3  * Test shared zeropage handling (with/without storage keys)
  4  *
  5  * Copyright (C) 2024, Red Hat, Inc.
  6  */
  7 #include <sys/mman.h>
  8 
  9 #include <linux/fs.h>
 10 
 11 #include "test_util.h"
 12 #include "kvm_util.h"
 13 #include "kselftest.h"
 14 #include "ucall_common.h"
 15 
 16 static void set_storage_key(void *addr, uint8_t skey)
 17 {
 18         asm volatile("sske %0,%1" : : "d" (skey), "a" (addr));
 19 }
 20 
 21 static void guest_code(void)
 22 {
 23         /* Issue some storage key instruction. */
 24         set_storage_key((void *)0, 0x98);
 25         GUEST_DONE();
 26 }
 27 
 28 /*
 29  * Returns 1 if the shared zeropage is mapped, 0 if something else is mapped.
 30  * Returns < 0 on error or if nothing is mapped.
 31  */
 32 static int maps_shared_zeropage(int pagemap_fd, void *addr)
 33 {
 34         struct page_region region;
 35         struct pm_scan_arg arg = {
 36                 .start = (uintptr_t)addr,
 37                 .end = (uintptr_t)addr + 4096,
 38                 .vec = (uintptr_t)&region,
 39                 .vec_len = 1,
 40                 .size = sizeof(struct pm_scan_arg),
 41                 .category_mask = PAGE_IS_PFNZERO,
 42                 .category_anyof_mask = PAGE_IS_PRESENT,
 43                 .return_mask = PAGE_IS_PFNZERO,
 44         };
 45         return ioctl(pagemap_fd, PAGEMAP_SCAN, &arg);
 46 }
 47 
 48 int main(int argc, char *argv[])
 49 {
 50         char *mem, *page0, *page1, *page2, tmp;
 51         const size_t pagesize = getpagesize();
 52         struct kvm_vcpu *vcpu;
 53         struct kvm_vm *vm;
 54         struct ucall uc;
 55         int pagemap_fd;
 56 
 57         ksft_print_header();
 58         ksft_set_plan(3);
 59 
 60         /*
 61          * We'll use memory that is not mapped into the VM for simplicity.
 62          * Shared zeropages are enabled/disabled per-process.
 63          */
 64         mem = mmap(0, 3 * pagesize, PROT_READ, MAP_PRIVATE | MAP_ANON, -1, 0);
 65         TEST_ASSERT(mem != MAP_FAILED, "mmap() failed");
 66 
 67         /* Disable THP. Ignore errors on older kernels. */
 68         madvise(mem, 3 * pagesize, MADV_NOHUGEPAGE);
 69 
 70         page0 = mem;
 71         page1 = page0 + pagesize;
 72         page2 = page1 + pagesize;
 73 
 74         /* Can we even detect shared zeropages? */
 75         pagemap_fd = open("/proc/self/pagemap", O_RDONLY);
 76         TEST_REQUIRE(pagemap_fd >= 0);
 77 
 78         tmp = *page0;
 79         asm volatile("" : "+r" (tmp));
 80         TEST_REQUIRE(maps_shared_zeropage(pagemap_fd, page0) == 1);
 81 
 82         vm = vm_create_with_one_vcpu(&vcpu, guest_code);
 83 
 84         /* Verify that we get the shared zeropage after VM creation. */
 85         tmp = *page1;
 86         asm volatile("" : "+r" (tmp));
 87         ksft_test_result(maps_shared_zeropage(pagemap_fd, page1) == 1,
 88                          "Shared zeropages should be enabled\n");
 89 
 90         /*
 91          * Let our VM execute a storage key instruction that should
 92          * unshare all shared zeropages.
 93          */
 94         vcpu_run(vcpu);
 95         get_ucall(vcpu, &uc);
 96         TEST_ASSERT_EQ(uc.cmd, UCALL_DONE);
 97 
 98         /* Verify that we don't have a shared zeropage anymore. */
 99         ksft_test_result(!maps_shared_zeropage(pagemap_fd, page1),
100                          "Shared zeropage should be gone\n");
101 
102         /* Verify that we don't get any new shared zeropages. */
103         tmp = *page2;
104         asm volatile("" : "+r" (tmp));
105         ksft_test_result(!maps_shared_zeropage(pagemap_fd, page2),
106                          "Shared zeropages should be disabled\n");
107 
108         kvm_vm_free(vm);
109 
110         ksft_finished();
111 }
112 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php