diff mbox series

[09/11] KVM: selftests: Make vm_create_default common

Message ID 20201104212357.171559-10-drjones@redhat.com (mailing list archive)
State New, archived
Headers show
Series KVM: selftests: Cleanups | expand

Commit Message

Andrew Jones Nov. 4, 2020, 9:23 p.m. UTC
The code is almost 100% the same anyway. Just move it to common
and add a few arch-specific helpers.

Signed-off-by: Andrew Jones <drjones@redhat.com>
---
 .../selftests/kvm/include/aarch64/processor.h |  3 ++
 .../selftests/kvm/include/s390x/processor.h   |  4 +++
 .../selftests/kvm/include/x86_64/processor.h  |  4 +++
 .../selftests/kvm/lib/aarch64/processor.c     | 17 ----------
 tools/testing/selftests/kvm/lib/kvm_util.c    | 26 +++++++++++++++
 .../selftests/kvm/lib/s390x/processor.c       | 22 -------------
 .../selftests/kvm/lib/x86_64/processor.c      | 32 -------------------
 7 files changed, 37 insertions(+), 71 deletions(-)

Comments

Andrew Jones Nov. 4, 2020, 9:36 p.m. UTC | #1
On Wed, Nov 04, 2020 at 10:23:55PM +0100, Andrew Jones wrote:
> The code is almost 100% the same anyway. Just move it to common
> and add a few arch-specific helpers.
> 
> Signed-off-by: Andrew Jones <drjones@redhat.com>
> ---
>  .../selftests/kvm/include/aarch64/processor.h |  3 ++
>  .../selftests/kvm/include/s390x/processor.h   |  4 +++
>  .../selftests/kvm/include/x86_64/processor.h  |  4 +++
>  .../selftests/kvm/lib/aarch64/processor.c     | 17 ----------
>  tools/testing/selftests/kvm/lib/kvm_util.c    | 26 +++++++++++++++
>  .../selftests/kvm/lib/s390x/processor.c       | 22 -------------
>  .../selftests/kvm/lib/x86_64/processor.c      | 32 -------------------
>  7 files changed, 37 insertions(+), 71 deletions(-)
> 
> diff --git a/tools/testing/selftests/kvm/include/aarch64/processor.h b/tools/testing/selftests/kvm/include/aarch64/processor.h
> index b7fa0c8551db..5e5849cdd115 100644
> --- a/tools/testing/selftests/kvm/include/aarch64/processor.h
> +++ b/tools/testing/selftests/kvm/include/aarch64/processor.h
> @@ -9,6 +9,9 @@
>  
>  #include "kvm_util.h"
>  
> +#define PTRS_PER_PAGE(page_size)	((page_size) / 8)
> +#define min_page_size()			(4096)
> +#define min_page_shift()		(12)
>  
>  #define ARM64_CORE_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \
>  			   KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x))
> diff --git a/tools/testing/selftests/kvm/include/s390x/processor.h b/tools/testing/selftests/kvm/include/s390x/processor.h
> index e0e96a5f608c..0952f53c538b 100644
> --- a/tools/testing/selftests/kvm/include/s390x/processor.h
> +++ b/tools/testing/selftests/kvm/include/s390x/processor.h
> @@ -5,6 +5,10 @@
>  #ifndef SELFTEST_KVM_PROCESSOR_H
>  #define SELFTEST_KVM_PROCESSOR_H
>  
> +#define PTRS_PER_PAGE(page_size)	((page_size) / 8)

Doh. I think this 8 is supposed to be a 16 for s390x, considering it
was dividing by 256 in its version of vm_create_default. I need
guidance from s390x gurus as to whether or not I should respin though.

Thanks,
drew

> +#define min_page_size()			(4096)
> +#define min_page_shift()		(12)
> +
>  /* Bits in the region/segment table entry */
>  #define REGION_ENTRY_ORIGIN	~0xfffUL /* region/segment table origin	   */
>  #define REGION_ENTRY_PROTECT	0x200	 /* region protection bit	   */
> diff --git a/tools/testing/selftests/kvm/include/x86_64/processor.h b/tools/testing/selftests/kvm/include/x86_64/processor.h
> index 82b7fe16a824..7f1fc597ed54 100644
> --- a/tools/testing/selftests/kvm/include/x86_64/processor.h
> +++ b/tools/testing/selftests/kvm/include/x86_64/processor.h
> @@ -13,6 +13,10 @@
>  
>  #include <asm/msr-index.h>
>  
> +#define PTRS_PER_PAGE(page_size)	((page_size) / 8)
> +#define min_page_size()			(4096)
> +#define min_page_shift()		(12)
> +
>  #define X86_EFLAGS_FIXED	 (1u << 1)
>  
>  #define X86_CR4_VME		(1ul << 0)
> diff --git a/tools/testing/selftests/kvm/lib/aarch64/processor.c b/tools/testing/selftests/kvm/lib/aarch64/processor.c
> index 2afa6618b396..da90e5a17d3a 100644
> --- a/tools/testing/selftests/kvm/lib/aarch64/processor.c
> +++ b/tools/testing/selftests/kvm/lib/aarch64/processor.c
> @@ -5,8 +5,6 @@
>   * Copyright (C) 2018, Red Hat, Inc.
>   */
>  
> -#define _GNU_SOURCE /* for program_invocation_name */
> -
>  #include <linux/compiler.h>
>  
>  #include "kvm_util.h"
> @@ -219,21 +217,6 @@ void virt_dump(FILE *stream, struct kvm_vm *vm, uint8_t indent)
>  	}
>  }
>  
> -struct kvm_vm *vm_create_default(uint32_t vcpuid, uint64_t extra_mem_pages,
> -				 void *guest_code)
> -{
> -	uint64_t ptrs_per_4k_pte = 512;
> -	uint64_t extra_pg_pages = (extra_mem_pages / ptrs_per_4k_pte) * 2;
> -	struct kvm_vm *vm;
> -
> -	vm = vm_create(VM_MODE_DEFAULT, DEFAULT_GUEST_PHY_PAGES + extra_pg_pages, O_RDWR);
> -
> -	kvm_vm_elf_load(vm, program_invocation_name, 0, 0);
> -	vm_vcpu_add_default(vm, vcpuid, guest_code);
> -
> -	return vm;
> -}
> -
>  void aarch64_vcpu_setup(struct kvm_vm *vm, int vcpuid, struct kvm_vcpu_init *init)
>  {
>  	struct kvm_vcpu_init default_init = { .target = -1, };
> diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
> index b9943e935dc7..0d9d2242af2e 100644
> --- a/tools/testing/selftests/kvm/lib/kvm_util.c
> +++ b/tools/testing/selftests/kvm/lib/kvm_util.c
> @@ -5,6 +5,7 @@
>   * Copyright (C) 2018, Google LLC.
>   */
>  
> +#define _GNU_SOURCE /* for program_invocation_name */
>  #include "test_util.h"
>  #include "kvm_util.h"
>  #include "kvm_util_internal.h"
> @@ -243,6 +244,31 @@ struct kvm_vm *vm_create(enum vm_guest_mode mode, uint64_t phy_pages, int perm)
>  	return vm;
>  }
>  
> +struct kvm_vm *vm_create_default(uint32_t vcpuid, uint64_t extra_mem_pages,
> +				 void *guest_code)
> +{
> +	/* The maximum page table size for a memory region will be when the
> +	 * smallest pages are used. Considering each page contains x page
> +	 * table descriptors, the total extra size for page tables (for extra
> +	 * N pages) will be: N/x+N/x^2+N/x^3+... which is definitely smaller
> +	 * than N/x*2.
> +	 */
> +	uint64_t extra_pg_pages = (extra_mem_pages / PTRS_PER_PAGE(min_page_size())) * 2;
> +	struct kvm_vm *vm;
> +
> +	vm = vm_create(VM_MODE_DEFAULT, DEFAULT_GUEST_PHY_PAGES + extra_pg_pages, O_RDWR);
> +
> +	kvm_vm_elf_load(vm, program_invocation_name, 0, 0);
> +
> +#ifdef __x86_64__
> +	vm_create_irqchip(vm);
> +#endif
> +
> +	vm_vcpu_add_default(vm, vcpuid, guest_code);
> +
> +	return vm;
> +}
> +
>  /*
>   * VM Restart
>   *
> diff --git a/tools/testing/selftests/kvm/lib/s390x/processor.c b/tools/testing/selftests/kvm/lib/s390x/processor.c
> index a88c5d665725..1c28e0ee75f2 100644
> --- a/tools/testing/selftests/kvm/lib/s390x/processor.c
> +++ b/tools/testing/selftests/kvm/lib/s390x/processor.c
> @@ -5,8 +5,6 @@
>   * Copyright (C) 2019, Red Hat, Inc.
>   */
>  
> -#define _GNU_SOURCE /* for program_invocation_name */
> -
>  #include "processor.h"
>  #include "kvm_util.h"
>  #include "../kvm_util_internal.h"
> @@ -160,26 +158,6 @@ void virt_dump(FILE *stream, struct kvm_vm *vm, uint8_t indent)
>  	virt_dump_region(stream, vm, indent, vm->pgd);
>  }
>  
> -struct kvm_vm *vm_create_default(uint32_t vcpuid, uint64_t extra_mem_pages,
> -				 void *guest_code)
> -{
> -	/*
> -	 * The additional amount of pages required for the page tables is:
> -	 * 1 * n / 256 + 4 * (n / 256) / 2048 + 4 * (n / 256) / 2048^2 + ...
> -	 * which is definitely smaller than (n / 256) * 2.
> -	 */
> -	uint64_t extra_pg_pages = extra_mem_pages / 256 * 2;
> -	struct kvm_vm *vm;
> -
> -	vm = vm_create(VM_MODE_DEFAULT,
> -		       DEFAULT_GUEST_PHY_PAGES + extra_pg_pages, O_RDWR);
> -
> -	kvm_vm_elf_load(vm, program_invocation_name, 0, 0);
> -	vm_vcpu_add_default(vm, vcpuid, guest_code);
> -
> -	return vm;
> -}
> -
>  void vm_vcpu_add_default(struct kvm_vm *vm, uint32_t vcpuid, void *guest_code)
>  {
>  	size_t stack_size =  DEFAULT_STACK_PGS * getpagesize();
> diff --git a/tools/testing/selftests/kvm/lib/x86_64/processor.c b/tools/testing/selftests/kvm/lib/x86_64/processor.c
> index f6eb34eaa0d2..835909b6038e 100644
> --- a/tools/testing/selftests/kvm/lib/x86_64/processor.c
> +++ b/tools/testing/selftests/kvm/lib/x86_64/processor.c
> @@ -5,8 +5,6 @@
>   * Copyright (C) 2018, Google LLC.
>   */
>  
> -#define _GNU_SOURCE /* for program_invocation_name */
> -
>  #include "test_util.h"
>  #include "kvm_util.h"
>  #include "../kvm_util_internal.h"
> @@ -721,36 +719,6 @@ void vcpu_set_cpuid(struct kvm_vm *vm,
>  
>  }
>  
> -struct kvm_vm *vm_create_default(uint32_t vcpuid, uint64_t extra_mem_pages,
> -				 void *guest_code)
> -{
> -	struct kvm_vm *vm;
> -	/*
> -	 * For x86 the maximum page table size for a memory region
> -	 * will be when only 4K pages are used.  In that case the
> -	 * total extra size for page tables (for extra N pages) will
> -	 * be: N/512+N/512^2+N/512^3+... which is definitely smaller
> -	 * than N/512*2.
> -	 */
> -	uint64_t extra_pg_pages = extra_mem_pages / 512 * 2;
> -
> -	/* Create VM */
> -	vm = vm_create(VM_MODE_DEFAULT,
> -		       DEFAULT_GUEST_PHY_PAGES + extra_pg_pages,
> -		       O_RDWR);
> -
> -	/* Setup guest code */
> -	kvm_vm_elf_load(vm, program_invocation_name, 0, 0);
> -
> -	/* Setup IRQ Chip */
> -	vm_create_irqchip(vm);
> -
> -	/* Add the first vCPU. */
> -	vm_vcpu_add_default(vm, vcpuid, guest_code);
> -
> -	return vm;
> -}
> -
>  /*
>   * VCPU Get MSR
>   *
> -- 
> 2.26.2
>
Christian Borntraeger Nov. 5, 2020, 7:18 a.m. UTC | #2
On 04.11.20 22:36, Andrew Jones wrote:
> On Wed, Nov 04, 2020 at 10:23:55PM +0100, Andrew Jones wrote:
>> The code is almost 100% the same anyway. Just move it to common
>> and add a few arch-specific helpers.
>>
>> Signed-off-by: Andrew Jones <drjones@redhat.com>
>> ---
>>  .../selftests/kvm/include/aarch64/processor.h |  3 ++
>>  .../selftests/kvm/include/s390x/processor.h   |  4 +++
>>  .../selftests/kvm/include/x86_64/processor.h  |  4 +++
>>  .../selftests/kvm/lib/aarch64/processor.c     | 17 ----------
>>  tools/testing/selftests/kvm/lib/kvm_util.c    | 26 +++++++++++++++
>>  .../selftests/kvm/lib/s390x/processor.c       | 22 -------------
>>  .../selftests/kvm/lib/x86_64/processor.c      | 32 -------------------
>>  7 files changed, 37 insertions(+), 71 deletions(-)
>>
>> diff --git a/tools/testing/selftests/kvm/include/aarch64/processor.h b/tools/testing/selftests/kvm/include/aarch64/processor.h
>> index b7fa0c8551db..5e5849cdd115 100644
>> --- a/tools/testing/selftests/kvm/include/aarch64/processor.h
>> +++ b/tools/testing/selftests/kvm/include/aarch64/processor.h
>> @@ -9,6 +9,9 @@
>>  
>>  #include "kvm_util.h"
>>  
>> +#define PTRS_PER_PAGE(page_size)	((page_size) / 8)
>> +#define min_page_size()			(4096)
>> +#define min_page_shift()		(12)
>>  
>>  #define ARM64_CORE_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \
>>  			   KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x))
>> diff --git a/tools/testing/selftests/kvm/include/s390x/processor.h b/tools/testing/selftests/kvm/include/s390x/processor.h
>> index e0e96a5f608c..0952f53c538b 100644
>> --- a/tools/testing/selftests/kvm/include/s390x/processor.h
>> +++ b/tools/testing/selftests/kvm/include/s390x/processor.h
>> @@ -5,6 +5,10 @@
>>  #ifndef SELFTEST_KVM_PROCESSOR_H
>>  #define SELFTEST_KVM_PROCESSOR_H
>>  
>> +#define PTRS_PER_PAGE(page_size)	((page_size) / 8)
> 
> Doh. I think this 8 is supposed to be a 16 for s390x, considering it
> was dividing by 256 in its version of vm_create_default. I need
> guidance from s390x gurus as to whether or not I should respin though.
> 
> Thanks,
> drew
> 

This is kind of tricky. The last level page table is only 2kb (256 entries = 1MB range).
Depending on whether the page table allocation is clever or not (you can have 2 page
tables in one page) this means that indeed 16 might be better. But then you actually 
want to change the macro name to PTES_PER_PAGE?
Andrew Jones Nov. 5, 2020, 9:59 a.m. UTC | #3
On Thu, Nov 05, 2020 at 08:18:37AM +0100, Christian Borntraeger wrote:
> 
> 
> On 04.11.20 22:36, Andrew Jones wrote:
> > On Wed, Nov 04, 2020 at 10:23:55PM +0100, Andrew Jones wrote:
> >> The code is almost 100% the same anyway. Just move it to common
> >> and add a few arch-specific helpers.
> >>
> >> Signed-off-by: Andrew Jones <drjones@redhat.com>
> >> ---
> >>  .../selftests/kvm/include/aarch64/processor.h |  3 ++
> >>  .../selftests/kvm/include/s390x/processor.h   |  4 +++
> >>  .../selftests/kvm/include/x86_64/processor.h  |  4 +++
> >>  .../selftests/kvm/lib/aarch64/processor.c     | 17 ----------
> >>  tools/testing/selftests/kvm/lib/kvm_util.c    | 26 +++++++++++++++
> >>  .../selftests/kvm/lib/s390x/processor.c       | 22 -------------
> >>  .../selftests/kvm/lib/x86_64/processor.c      | 32 -------------------
> >>  7 files changed, 37 insertions(+), 71 deletions(-)
> >>
> >> diff --git a/tools/testing/selftests/kvm/include/aarch64/processor.h b/tools/testing/selftests/kvm/include/aarch64/processor.h
> >> index b7fa0c8551db..5e5849cdd115 100644
> >> --- a/tools/testing/selftests/kvm/include/aarch64/processor.h
> >> +++ b/tools/testing/selftests/kvm/include/aarch64/processor.h
> >> @@ -9,6 +9,9 @@
> >>  
> >>  #include "kvm_util.h"
> >>  
> >> +#define PTRS_PER_PAGE(page_size)	((page_size) / 8)
> >> +#define min_page_size()			(4096)
> >> +#define min_page_shift()		(12)
> >>  
> >>  #define ARM64_CORE_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \
> >>  			   KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x))
> >> diff --git a/tools/testing/selftests/kvm/include/s390x/processor.h b/tools/testing/selftests/kvm/include/s390x/processor.h
> >> index e0e96a5f608c..0952f53c538b 100644
> >> --- a/tools/testing/selftests/kvm/include/s390x/processor.h
> >> +++ b/tools/testing/selftests/kvm/include/s390x/processor.h
> >> @@ -5,6 +5,10 @@
> >>  #ifndef SELFTEST_KVM_PROCESSOR_H
> >>  #define SELFTEST_KVM_PROCESSOR_H
> >>  
> >> +#define PTRS_PER_PAGE(page_size)	((page_size) / 8)
> > 
> > Doh. I think this 8 is supposed to be a 16 for s390x, considering it
> > was dividing by 256 in its version of vm_create_default. I need
> > guidance from s390x gurus as to whether or not I should respin though.
> > 
> > Thanks,
> > drew
> > 
> 
> This is kind of tricky. The last level page table is only 2kb (256 entries = 1MB range).
> Depending on whether the page table allocation is clever or not (you can have 2 page
> tables in one page) this means that indeed 16 might be better. But then you actually 
> want to change the macro name to PTES_PER_PAGE?

Thanks Christian,

I'll respin with the macro name change and 16 for s390.

drew
Peter Xu Nov. 5, 2020, 6:45 p.m. UTC | #4
On Thu, Nov 05, 2020 at 10:59:30AM +0100, Andrew Jones wrote:
> > >> +#define PTRS_PER_PAGE(page_size)	((page_size) / 8)
> > > 
> > > Doh. I think this 8 is supposed to be a 16 for s390x, considering it
> > > was dividing by 256 in its version of vm_create_default. I need
> > > guidance from s390x gurus as to whether or not I should respin though.
> > > 
> > > Thanks,
> > > drew
> > > 
> > 
> > This is kind of tricky. The last level page table is only 2kb (256 entries = 1MB range).
> > Depending on whether the page table allocation is clever or not (you can have 2 page
> > tables in one page) this means that indeed 16 might be better. But then you actually 
> > want to change the macro name to PTES_PER_PAGE?
> 
> Thanks Christian,
> 
> I'll respin with the macro name change and 16 for s390.

Maybe it can also be moved to common header, but instead define PTR_SIZE for
per-arch?  I'm also curious whether PTR_SIZE will equals to "sizeof(void *)",
but seems not for s390x..  Thanks,
Christian Borntraeger Nov. 5, 2020, 6:54 p.m. UTC | #5
On 05.11.20 19:45, Peter Xu wrote:
> On Thu, Nov 05, 2020 at 10:59:30AM +0100, Andrew Jones wrote:
>>>>> +#define PTRS_PER_PAGE(page_size)	((page_size) / 8)
>>>>
>>>> Doh. I think this 8 is supposed to be a 16 for s390x, considering it
>>>> was dividing by 256 in its version of vm_create_default. I need
>>>> guidance from s390x gurus as to whether or not I should respin though.
>>>>
>>>> Thanks,
>>>> drew
>>>>
>>>
>>> This is kind of tricky. The last level page table is only 2kb (256 entries = 1MB range).
>>> Depending on whether the page table allocation is clever or not (you can have 2 page
>>> tables in one page) this means that indeed 16 might be better. But then you actually 
>>> want to change the macro name to PTES_PER_PAGE?
>>
>> Thanks Christian,
>>
>> I'll respin with the macro name change and 16 for s390.
> 
> Maybe it can also be moved to common header, but instead define PTR_SIZE for
> per-arch?  I'm also curious whether PTR_SIZE will equals to "sizeof(void *)",
> but seems not for s390x..  Thanks,

Thats why I want to change the name. It is not about the ptr size. It is about
number of page table entries in a page. And as a page table is just 2kb on s390
there is a mismatch. So instead of

#define PTRS_PER_PAGE(page_size)	((page_size) / 8)

let us just to
#define PTES_PER_PAGETABLE 256
for s390
and
#define PTES_PER_PAGETABLE 512
for the others
diff mbox series

Patch

diff --git a/tools/testing/selftests/kvm/include/aarch64/processor.h b/tools/testing/selftests/kvm/include/aarch64/processor.h
index b7fa0c8551db..5e5849cdd115 100644
--- a/tools/testing/selftests/kvm/include/aarch64/processor.h
+++ b/tools/testing/selftests/kvm/include/aarch64/processor.h
@@ -9,6 +9,9 @@ 
 
 #include "kvm_util.h"
 
+#define PTRS_PER_PAGE(page_size)	((page_size) / 8)
+#define min_page_size()			(4096)
+#define min_page_shift()		(12)
 
 #define ARM64_CORE_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \
 			   KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x))
diff --git a/tools/testing/selftests/kvm/include/s390x/processor.h b/tools/testing/selftests/kvm/include/s390x/processor.h
index e0e96a5f608c..0952f53c538b 100644
--- a/tools/testing/selftests/kvm/include/s390x/processor.h
+++ b/tools/testing/selftests/kvm/include/s390x/processor.h
@@ -5,6 +5,10 @@ 
 #ifndef SELFTEST_KVM_PROCESSOR_H
 #define SELFTEST_KVM_PROCESSOR_H
 
+#define PTRS_PER_PAGE(page_size)	((page_size) / 8)
+#define min_page_size()			(4096)
+#define min_page_shift()		(12)
+
 /* Bits in the region/segment table entry */
 #define REGION_ENTRY_ORIGIN	~0xfffUL /* region/segment table origin	   */
 #define REGION_ENTRY_PROTECT	0x200	 /* region protection bit	   */
diff --git a/tools/testing/selftests/kvm/include/x86_64/processor.h b/tools/testing/selftests/kvm/include/x86_64/processor.h
index 82b7fe16a824..7f1fc597ed54 100644
--- a/tools/testing/selftests/kvm/include/x86_64/processor.h
+++ b/tools/testing/selftests/kvm/include/x86_64/processor.h
@@ -13,6 +13,10 @@ 
 
 #include <asm/msr-index.h>
 
+#define PTRS_PER_PAGE(page_size)	((page_size) / 8)
+#define min_page_size()			(4096)
+#define min_page_shift()		(12)
+
 #define X86_EFLAGS_FIXED	 (1u << 1)
 
 #define X86_CR4_VME		(1ul << 0)
diff --git a/tools/testing/selftests/kvm/lib/aarch64/processor.c b/tools/testing/selftests/kvm/lib/aarch64/processor.c
index 2afa6618b396..da90e5a17d3a 100644
--- a/tools/testing/selftests/kvm/lib/aarch64/processor.c
+++ b/tools/testing/selftests/kvm/lib/aarch64/processor.c
@@ -5,8 +5,6 @@ 
  * Copyright (C) 2018, Red Hat, Inc.
  */
 
-#define _GNU_SOURCE /* for program_invocation_name */
-
 #include <linux/compiler.h>
 
 #include "kvm_util.h"
@@ -219,21 +217,6 @@  void virt_dump(FILE *stream, struct kvm_vm *vm, uint8_t indent)
 	}
 }
 
-struct kvm_vm *vm_create_default(uint32_t vcpuid, uint64_t extra_mem_pages,
-				 void *guest_code)
-{
-	uint64_t ptrs_per_4k_pte = 512;
-	uint64_t extra_pg_pages = (extra_mem_pages / ptrs_per_4k_pte) * 2;
-	struct kvm_vm *vm;
-
-	vm = vm_create(VM_MODE_DEFAULT, DEFAULT_GUEST_PHY_PAGES + extra_pg_pages, O_RDWR);
-
-	kvm_vm_elf_load(vm, program_invocation_name, 0, 0);
-	vm_vcpu_add_default(vm, vcpuid, guest_code);
-
-	return vm;
-}
-
 void aarch64_vcpu_setup(struct kvm_vm *vm, int vcpuid, struct kvm_vcpu_init *init)
 {
 	struct kvm_vcpu_init default_init = { .target = -1, };
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index b9943e935dc7..0d9d2242af2e 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -5,6 +5,7 @@ 
  * Copyright (C) 2018, Google LLC.
  */
 
+#define _GNU_SOURCE /* for program_invocation_name */
 #include "test_util.h"
 #include "kvm_util.h"
 #include "kvm_util_internal.h"
@@ -243,6 +244,31 @@  struct kvm_vm *vm_create(enum vm_guest_mode mode, uint64_t phy_pages, int perm)
 	return vm;
 }
 
+struct kvm_vm *vm_create_default(uint32_t vcpuid, uint64_t extra_mem_pages,
+				 void *guest_code)
+{
+	/* The maximum page table size for a memory region will be when the
+	 * smallest pages are used. Considering each page contains x page
+	 * table descriptors, the total extra size for page tables (for extra
+	 * N pages) will be: N/x+N/x^2+N/x^3+... which is definitely smaller
+	 * than N/x*2.
+	 */
+	uint64_t extra_pg_pages = (extra_mem_pages / PTRS_PER_PAGE(min_page_size())) * 2;
+	struct kvm_vm *vm;
+
+	vm = vm_create(VM_MODE_DEFAULT, DEFAULT_GUEST_PHY_PAGES + extra_pg_pages, O_RDWR);
+
+	kvm_vm_elf_load(vm, program_invocation_name, 0, 0);
+
+#ifdef __x86_64__
+	vm_create_irqchip(vm);
+#endif
+
+	vm_vcpu_add_default(vm, vcpuid, guest_code);
+
+	return vm;
+}
+
 /*
  * VM Restart
  *
diff --git a/tools/testing/selftests/kvm/lib/s390x/processor.c b/tools/testing/selftests/kvm/lib/s390x/processor.c
index a88c5d665725..1c28e0ee75f2 100644
--- a/tools/testing/selftests/kvm/lib/s390x/processor.c
+++ b/tools/testing/selftests/kvm/lib/s390x/processor.c
@@ -5,8 +5,6 @@ 
  * Copyright (C) 2019, Red Hat, Inc.
  */
 
-#define _GNU_SOURCE /* for program_invocation_name */
-
 #include "processor.h"
 #include "kvm_util.h"
 #include "../kvm_util_internal.h"
@@ -160,26 +158,6 @@  void virt_dump(FILE *stream, struct kvm_vm *vm, uint8_t indent)
 	virt_dump_region(stream, vm, indent, vm->pgd);
 }
 
-struct kvm_vm *vm_create_default(uint32_t vcpuid, uint64_t extra_mem_pages,
-				 void *guest_code)
-{
-	/*
-	 * The additional amount of pages required for the page tables is:
-	 * 1 * n / 256 + 4 * (n / 256) / 2048 + 4 * (n / 256) / 2048^2 + ...
-	 * which is definitely smaller than (n / 256) * 2.
-	 */
-	uint64_t extra_pg_pages = extra_mem_pages / 256 * 2;
-	struct kvm_vm *vm;
-
-	vm = vm_create(VM_MODE_DEFAULT,
-		       DEFAULT_GUEST_PHY_PAGES + extra_pg_pages, O_RDWR);
-
-	kvm_vm_elf_load(vm, program_invocation_name, 0, 0);
-	vm_vcpu_add_default(vm, vcpuid, guest_code);
-
-	return vm;
-}
-
 void vm_vcpu_add_default(struct kvm_vm *vm, uint32_t vcpuid, void *guest_code)
 {
 	size_t stack_size =  DEFAULT_STACK_PGS * getpagesize();
diff --git a/tools/testing/selftests/kvm/lib/x86_64/processor.c b/tools/testing/selftests/kvm/lib/x86_64/processor.c
index f6eb34eaa0d2..835909b6038e 100644
--- a/tools/testing/selftests/kvm/lib/x86_64/processor.c
+++ b/tools/testing/selftests/kvm/lib/x86_64/processor.c
@@ -5,8 +5,6 @@ 
  * Copyright (C) 2018, Google LLC.
  */
 
-#define _GNU_SOURCE /* for program_invocation_name */
-
 #include "test_util.h"
 #include "kvm_util.h"
 #include "../kvm_util_internal.h"
@@ -721,36 +719,6 @@  void vcpu_set_cpuid(struct kvm_vm *vm,
 
 }
 
-struct kvm_vm *vm_create_default(uint32_t vcpuid, uint64_t extra_mem_pages,
-				 void *guest_code)
-{
-	struct kvm_vm *vm;
-	/*
-	 * For x86 the maximum page table size for a memory region
-	 * will be when only 4K pages are used.  In that case the
-	 * total extra size for page tables (for extra N pages) will
-	 * be: N/512+N/512^2+N/512^3+... which is definitely smaller
-	 * than N/512*2.
-	 */
-	uint64_t extra_pg_pages = extra_mem_pages / 512 * 2;
-
-	/* Create VM */
-	vm = vm_create(VM_MODE_DEFAULT,
-		       DEFAULT_GUEST_PHY_PAGES + extra_pg_pages,
-		       O_RDWR);
-
-	/* Setup guest code */
-	kvm_vm_elf_load(vm, program_invocation_name, 0, 0);
-
-	/* Setup IRQ Chip */
-	vm_create_irqchip(vm);
-
-	/* Add the first vCPU. */
-	vm_vcpu_add_default(vm, vcpuid, guest_code);
-
-	return vm;
-}
-
 /*
  * VCPU Get MSR
  *