Re: [PATCH v1] KVM: s390x: selftests: Add shared zeropage test

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 4/12/24 1:43 PM, David Hildenbrand wrote:
> Let's test that we can have shared zeropages in our process as long as
> storage keys are not getting used, that shared zeropages are properly
> unshared (replaced by anonymous pages) once storage keys are enabled,
> and that no new shared zeropages are populated after storage keys
> were enabled.
> 
> We require the new pagemap interface to detect the shared zeropage.
> 
> On an old kernel (zeropages always disabled):
> 	# ./s390x/shared_zeropage_test
> 	TAP version 13
> 	1..3
> 	not ok 1 Shared zeropages should be enabled
> 	ok 2 Shared zeropage should be gone
> 	ok 3 Shared zeropages should be disabled
> 	# Totals: pass:2 fail:1 xfail:0 xpass:0 skip:0 error:0
> 
> On a fixed kernel:
> 	# ./s390x/shared_zeropage_test
> 	TAP version 13
> 	1..3
> 	ok 1 Shared zeropages should be enabled
> 	ok 2 Shared zeropage should be gone
> 	ok 3 Shared zeropages should be disabled
> 	# Totals: pass:3 fail:0 xfail:0 xpass:0 skip:0 error:0
> 
> Testing of UFFDIO_ZEROPAGE can be added later.
> 
> Cc: Christian Borntraeger <borntraeger@xxxxxxxxxxxxx>
> Cc: Janosch Frank <frankja@xxxxxxxxxxxxx>
> Cc: Claudio Imbrenda <imbrenda@xxxxxxxxxxxxx>
> Cc: Thomas Huth <thuth@xxxxxxxxxx>
> Cc: Alexander Gordeev <agordeev@xxxxxxxxxxxxx>
> Cc: Paolo Bonzini <pbonzini@xxxxxxxxxx>
> Cc: Shuah Khan <shuah@xxxxxxxxxx>
> Signed-off-by: David Hildenbrand <david@xxxxxxxxxx>
Acked-by: Muhammad Usama Anjum <usama.anjum@xxxxxxxxxxxxx>

> ---
> 
> To get it right this time, test the relevant cases.
> 
> v3 of fixes are at:
>  https://lore.kernel.org/all/20240411161441.910170-1-david@xxxxxxxxxx/T/#u
> 
> ---
>  tools/testing/selftests/kvm/Makefile          |   1 +
>  .../kvm/s390x/shared_zeropage_test.c          | 110 ++++++++++++++++++
>  2 files changed, 111 insertions(+)
>  create mode 100644 tools/testing/selftests/kvm/s390x/shared_zeropage_test.c
> 
> diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
> index 741c7dc16afc..ed4ad591f193 100644
> --- a/tools/testing/selftests/kvm/Makefile
> +++ b/tools/testing/selftests/kvm/Makefile
> @@ -180,6 +180,7 @@ TEST_GEN_PROGS_s390x += s390x/sync_regs_test
>  TEST_GEN_PROGS_s390x += s390x/tprot
>  TEST_GEN_PROGS_s390x += s390x/cmma_test
>  TEST_GEN_PROGS_s390x += s390x/debug_test
> +TEST_GEN_PROGS_s390x += s390x/shared_zeropage_test
>  TEST_GEN_PROGS_s390x += demand_paging_test
>  TEST_GEN_PROGS_s390x += dirty_log_test
>  TEST_GEN_PROGS_s390x += guest_print_test
> diff --git a/tools/testing/selftests/kvm/s390x/shared_zeropage_test.c b/tools/testing/selftests/kvm/s390x/shared_zeropage_test.c
> new file mode 100644
> index 000000000000..74e829748fb1
> --- /dev/null
> +++ b/tools/testing/selftests/kvm/s390x/shared_zeropage_test.c
> @@ -0,0 +1,110 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Test shared zeropage handling (with/without storage keys)
> + *
> + * Copyright (C) 2024, Red Hat, Inc.
> + */
> +#include <sys/mman.h>
> +
> +#include <linux/fs.h>
> +
> +#include "test_util.h"
> +#include "kvm_util.h"
> +#include "kselftest.h"
> +
> +static void set_storage_key(void *addr, uint8_t skey)
> +{
> +	asm volatile("sske %0,%1" : : "d" (skey), "a" (addr));
> +}
> +
> +static void guest_code(void)
> +{
> +	/* Issue some storage key instruction. */
> +	set_storage_key((void *)0, 0x98);
> +	GUEST_DONE();
> +}
> +
> +/*
> + * Returns 1 if the shared zeropage is mapped, 0 if something else is mapped.
> + * Returns < 0 on error or if nothing is mapped.
> + */
> +static int maps_shared_zeropage(int pagemap_fd, void *addr)
> +{
> +	struct page_region region;
> +	struct pm_scan_arg arg = {
> +		.start = (uintptr_t)addr,
> +		.end = (uintptr_t)addr + 4096,
> +		.vec = (uintptr_t)&region,
> +		.vec_len = 1,
> +		.size = sizeof(struct pm_scan_arg),
> +		.category_mask = PAGE_IS_PFNZERO,
> +		.category_anyof_mask = PAGE_IS_PRESENT,
> +		.return_mask = PAGE_IS_PFNZERO,
> +	};
> +	return ioctl(pagemap_fd, PAGEMAP_SCAN, &arg);Its good to see more users for it.

> +}
> +
> +int main(int argc, char *argv[])
> +{
> +	char *mem, *page0, *page1, *page2, tmp;
> +	const size_t pagesize = getpagesize();
> +	struct kvm_vcpu *vcpu;
> +	struct kvm_vm *vm;
> +	struct ucall uc;
> +	int pagemap_fd;
> +
> +	ksft_print_header();
> +	ksft_set_plan(3);
> +
> +	/*
> +	 * We'll use memory that is not mapped into the VM for simplicity.
> +	 * Shared zeropages are enabled/disabled per-process.
> +	 */
> +	mem = mmap(0, 3 * pagesize, PROT_READ, MAP_PRIVATE|MAP_ANON, -1, 0);
> +	TEST_ASSERT(mem != MAP_FAILED, "mmap() failed");
> +
> +	/* Disable THP. Ignore errors on older kernels. */
> +	madvise(mem, 3 * pagesize, MADV_NOHUGEPAGE);
> +
> +	page0 = mem;
> +	page1 = page0 + pagesize;
> +	page2 = page1 + pagesize;
> +
> +	/* Can we even detect shared zeropages? */
> +	pagemap_fd = open("/proc/self/pagemap", O_RDONLY);
> +	TEST_REQUIRE(pagemap_fd >= 0);
> +
> +	tmp = *page0;
> +	asm volatile("" : "+r" (tmp));
> +	TEST_REQUIRE(maps_shared_zeropage(pagemap_fd, page0) == 1);
> +
> +	vm = vm_create_with_one_vcpu(&vcpu, guest_code);
> +
> +	/* Verify that we get the shared zeropage after VM creation. */
> +	tmp = *page1;
> +	asm volatile("" : "+r" (tmp));
> +	ksft_test_result(maps_shared_zeropage(pagemap_fd, page1) == 1,
> +			 "Shared zeropages should be enabled\n");
> +
> +	/*
> +	 * Let our VM execute a storage key instruction that should
> +	 * unshare all shared zeropages.
> +	 */
> +	vcpu_run(vcpu);
> +	get_ucall(vcpu, &uc);
> +	TEST_ASSERT_EQ(uc.cmd, UCALL_DONE);
> +
> +	/* Verify that we don't have a shared zeropage anymore. */
> +	ksft_test_result(!maps_shared_zeropage(pagemap_fd, page1),
> +			 "Shared zeropage should be gone\n");
> +
> +	/* Verify that we don't get any new shared zeropages. */
> +	tmp = *page2;
> +	asm volatile("" : "+r" (tmp));
> +	ksft_test_result(!maps_shared_zeropage(pagemap_fd, page2),
> +			 "Shared zeropages should be disabled\n");
> +
> +	kvm_vm_free(vm);
> +
> +	ksft_finished();
> +}

-- 
BR,
Muhammad Usama Anjum




[Index of Archives]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Share Photos]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux