Re: [PATCH 3/4] KVM: arm64: selftests: Align VA space allocator with TTBR0

2022-12-08 Thread Andrew Jones
On Thu, Dec 08, 2022 at 01:09:38AM +, Sean Christopherson wrote:
...
> Actually, before we do anything, we should get confirmation from the s390 and
> RISC-V folks on whether they have a canonical hole like x86, i.e. maybe x86 is
> the oddball.

riscv splits like x86.

Thanks,
drew
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


Re: [PATCH 3/4] KVM: arm64: selftests: Align VA space allocator with TTBR0

2022-12-07 Thread Sean Christopherson
On Thu, Dec 08, 2022, Oliver Upton wrote:
> On Thu, Dec 08, 2022 at 12:18:07AM +, Sean Christopherson wrote:
> 
> [...]
> 
> > Together, what about?  The #ifdef is a bit gross, especially around 
> > "hi_start",
> > but it's less duplicate code.  And IMO, having things bundled in the same 
> > place
> > makes it a lot easier for newbies (to arm64 or kernel coding in general) to
> > understand what's going on and why arm64 is different.
> 
> I'd rather we not go this route. We really shouldn't make any attempt to
> de-dupe something that is inherently architecture specific.
> 
> For example:
> 
> > +   /*
> > +* All architectures supports splitting the virtual address space into
> > +* a high and a low half.  Populate both halves, except for arm64 which
> > +* currently uses only TTBR0_EL1 (arbitrary selftests "logic"), i.e.
> > +* only has a valid low half.
> > +*/
> > +   sparsebit_num_t nr_va_bits = (1ULL << (vm->va_bits - 1)) >> 
> > vm->page_shift;
> 
> This is still wrong for arm64. When we say the VA space is 48 bits, we
> really do mean that TTBR0 is able to address a full 48 bits. So this
> truncates the MSB for the addressing mode.

Ah, I missed the lack of a "-1" in the arm64 code.

> With the code living in the arm64 side of the shop, I can also tailor
> the comment to directly match the architecture to provide breadcrumbs
> tying it back to the Arm ARM.

The main reason why I don't like splitting the code this way is that it makes it
harder for non-arm64 folks to understand what makes arm64 different.  Case in
point, my overlooking of the "-1".  I read the changelog and the comment and
still missed that small-but-important detail, largely because I am completely
unfamiliar with how TTBR{0,1}_EL1 works.

Actually, before we do anything, we should get confirmation from the s390 and
RISC-V folks on whether they have a canonical hole like x86, i.e. maybe x86 is
the oddball.

Anyways, assuming one architecture is the oddball (I'm betting it's x86), I have
no objection to bleeding some of the details into the common code, including a
large comment to document the gory details.  If every architecture manges to be
different, then yeah, a hook is probably warranted.

That said, I also don't mind shoving a bit of abstraction into arch code if that
avoids some #ifdef ugliness or allows for better documentation, flexibility, 
etc.
What I don't like is duplicating the logic of turning "VA bits" into the bitmap.

E.g. something like this would also be an option.  Readers would obviously need
to track down has_split_va_space, but that should be fairly easy and can come
with a big arch-specific comment, and meanwhile the core logic of how selftests
populate the va bitmaps is common.

Or if arm64 is the only arch without a split, invert the flag and have arm64 set
the vm->has_combined_va_space or whatever.

static void vm_vaddr_populate_bitmap(struct kvm_vm *vm)
{
unsigned int eff_va_bits = vm->va_bits;
sparsebit_num_t nr_bits;

/* blah blah blah */
if (vm->has_split_va_space)
eff_va_bits--;

nr_bits = (1ULL << eff_va_bits) >> vm->page_shift;

sparsebit_set_num(vm->vpages_valid, 0, nr_va_bits);

if (vm->has_split_va_space)
sparsebit_set_num(vm->vpages_valid,
  (~((1ULL << eff_va_bits) - 1)) >> 
vm->page_shift,
  nr_bits);
}
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


Re: [PATCH 3/4] KVM: arm64: selftests: Align VA space allocator with TTBR0

2022-12-07 Thread Oliver Upton
On Thu, Dec 08, 2022 at 12:18:07AM +, Sean Christopherson wrote:

[...]

> Together, what about?  The #ifdef is a bit gross, especially around 
> "hi_start",
> but it's less duplicate code.  And IMO, having things bundled in the same 
> place
> makes it a lot easier for newbies (to arm64 or kernel coding in general) to
> understand what's going on and why arm64 is different.

I'd rather we not go this route. We really shouldn't make any attempt to
de-dupe something that is inherently architecture specific.

For example:

> + /*
> +  * All architectures supports splitting the virtual address space into
> +  * a high and a low half.  Populate both halves, except for arm64 which
> +  * currently uses only TTBR0_EL1 (arbitrary selftests "logic"), i.e.
> +  * only has a valid low half.
> +  */
> + sparsebit_num_t nr_va_bits = (1ULL << (vm->va_bits - 1)) >> 
> vm->page_shift;

This is still wrong for arm64. When we say the VA space is 48 bits, we
really do mean that TTBR0 is able to address a full 48 bits. So this
truncates the MSB for the addressing mode.

With the code living in the arm64 side of the shop, I can also tailor
the comment to directly match the architecture to provide breadcrumbs
tying it back to the Arm ARM.

--
Thanks,
Oliver
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


Re: [PATCH 3/4] KVM: arm64: selftests: Align VA space allocator with TTBR0

2022-12-07 Thread Sean Christopherson
On Wed, Dec 07, 2022, Oliver Upton wrote:
> diff --git a/tools/testing/selftests/kvm/lib/aarch64/processor.c 
> b/tools/testing/selftests/kvm/lib/aarch64/processor.c
> index 316de70db91d..5972a23b2765 100644
> --- a/tools/testing/selftests/kvm/lib/aarch64/processor.c
> +++ b/tools/testing/selftests/kvm/lib/aarch64/processor.c
> @@ -541,3 +541,13 @@ void kvm_selftest_arch_init(void)
>*/
>   guest_modes_append_default();
>  }
> +
> +void vm_vaddr_populate_bitmap(struct kvm_vm *vm)

Add "arch" so that it's obvious this can be overidden?  The "__weak" conveys 
that
for the implementation, but not for the call site.  E.g. 
vm_arch_vaddr_populate_bitmap().

Actually, IIUC, the issue is that the high half isn't mapped (probably the wrong
terminology).  I.e. the calculation for the low half stays the same, and the 
high
half just goes away.

> +{
> + /*
> +  * arm64 selftests use only TTBR0_EL1, meaning that the valid VA space
> +  * is [0, 2^(64 - TCR_EL1.T0SZ)).
> +  */
> + sparsebit_set_num(vm->vpages_valid, 0,
> +   (1ULL << vm->va_bits) >> vm->page_shift);
> +}
> diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c 
> b/tools/testing/selftests/kvm/lib/kvm_util.c
> index e9607eb089be..c88c3ace16d2 100644
> --- a/tools/testing/selftests/kvm/lib/kvm_util.c
> +++ b/tools/testing/selftests/kvm/lib/kvm_util.c
> @@ -186,6 +186,15 @@ const struct vm_guest_mode_params vm_guest_mode_params[] 
> = {
>  _Static_assert(sizeof(vm_guest_mode_params)/sizeof(struct 
> vm_guest_mode_params) == NUM_VM_MODES,
>  "Missing new mode params?");
>  
> +__weak void vm_vaddr_populate_bitmap(struct kvm_vm *vm)
> +{
> + sparsebit_set_num(vm->vpages_valid,
> + 0, (1ULL << (vm->va_bits - 1)) >> vm->page_shift);
> + sparsebit_set_num(vm->vpages_valid,
> + (~((1ULL << (vm->va_bits - 1)) - 1)) >> vm->page_shift,
> + (1ULL << (vm->va_bits - 1)) >> vm->page_shift);

Any objection to fixing up the formatting?  Actually, we can do more than just
fix the indentation, e.g. the number of bits is identical, and documenting that
this does a high/low split would be helpful.

Together, what about?  The #ifdef is a bit gross, especially around "hi_start",
but it's less duplicate code.  And IMO, having things bundled in the same place
makes it a lot easier for newbies (to arm64 or kernel coding in general) to
understand what's going on and why arm64 is different.

---
 tools/testing/selftests/kvm/lib/kvm_util.c | 23 +-
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c 
b/tools/testing/selftests/kvm/lib/kvm_util.c
index e9607eb089be..d6f2c17e3d40 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -186,6 +186,23 @@ const struct vm_guest_mode_params vm_guest_mode_params[] = 
{
 _Static_assert(sizeof(vm_guest_mode_params)/sizeof(struct 
vm_guest_mode_params) == NUM_VM_MODES,
   "Missing new mode params?");
 
+static void vm_vaddr_populate_bitmap(struct kvm_vm *vm)
+{
+   /*
+* All architectures supports splitting the virtual address space into
+* a high and a low half.  Populate both halves, except for arm64 which
+* currently uses only TTBR0_EL1 (arbitrary selftests "logic"), i.e.
+* only has a valid low half.
+*/
+   sparsebit_num_t nr_va_bits = (1ULL << (vm->va_bits - 1)) >> 
vm->page_shift;
+#ifndef __aarch64__
+   sparsebit_num_t hi_start = (~((1ULL << (vm->va_bits - 1)) - 1)) >> 
vm->page_shift
+
+   sparsebit_set_num(vm->vpages_valid, hi_start, nr_bits);
+#endif
+   sparsebit_set_num(vm->vpages_valid, 0, nr_va_bits);
+}
+
 struct kvm_vm *vm_create(enum vm_guest_mode mode)
 {
struct kvm_vm *vm;
@@ -274,11 +291,7 @@ struct kvm_vm *vm_create(enum vm_guest_mode mode)
 
/* Limit to VA-bit canonical virtual addresses. */
vm->vpages_valid = sparsebit_alloc();
-   sparsebit_set_num(vm->vpages_valid,
-   0, (1ULL << (vm->va_bits - 1)) >> vm->page_shift);
-   sparsebit_set_num(vm->vpages_valid,
-   (~((1ULL << (vm->va_bits - 1)) - 1)) >> vm->page_shift,
-   (1ULL << (vm->va_bits - 1)) >> vm->page_shift);
+   vm_vaddr_populate_bitmap(vm);
 
/* Limit physical addresses to PA-bits. */
vm->max_gfn = vm_compute_max_gfn(vm);

base-commit: 35aecc3289eebf193fd70a067ea448ae2f0bb9b9
-- 

___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm