Re: [PATCH v14 16/39] arm64/sme: Implement traps and syscall handling for SME

2022-12-07 Thread Zenghui Yu

On 2022/12/7 22:16, Mark Brown wrote:

On Wed, Dec 07, 2022 at 10:00:17PM +0800, Zenghui Yu wrote:

On 2022/4/19 19:22, Mark Brown wrote:



+   /*
+* If SME is active then exit streaming mode.  If ZA is active
+* then flush the SVE registers but leave userspace access to
+* both SVE and SME enabled, otherwise disable SME for the
+* task and fall through to disabling SVE too.  This means



It looks a bit confusing to me that in the current implementation, if
ZA is *not* active, we don't actually go to disable SME for the task
(which IMHO can be disabled as user-space is not actively using it now).


Unlike SVE there's no overhead from leaving SME enabled, the enable bits
for SM and ZA tell us if there is extra register state to be saved so we
don't have to worry about the costs there like we do with SVE.  The only
reason for not just unconditionally enabling SME is the potentially
large backing storage required for the registers, if a task isn't using
SME there's no need to impose that overhead.  If we disable SME for
userspace after the storage has been allocated then we just require an
additional trip through EL1 to reenable it for any future usage which
would hurt performance but not really gain us anything otherwise.  We
don't want to discurage applications from disabling ZA when not in use
given that there's likely to be physical overheads from keeping it
enabled.


Ah, thanks a lot for the explanations. The comment itself can be
improved though (I think).


+   if (svcr & SYS_SVCR_EL0_SM_MASK)
+   sme_smstop_sm();



As per the SME syscall ABI



| On syscall PSTATE.SM will be cleared and the SVE registers will be
| handled as per the standard SVE ABI.



and the SVE syscall ABI



| On syscall, V0..V31 are preserved (as without SVE).  Thus, bits
| [127:0] of Z0..Z31 are preserved.  All other bits of Z0..Z31, and all
| of P0..P15 and FFR become zero on return from a syscall.



Can we infer from the documentation that V0-V31 should be preserved on
return from a syscall? But with sme_smstop_sm(), all implemented bits of
Z0-Z31 are set to zero by hardware. Is this intentional?



Please fix me up if I've mis-read things here.


No, the intention is to say that we exit streaming mode and then handle
things as per the non-streaming ABI.  Exiting streaming mode has the
effect of clearing the values as you say.


Thanks,
Zenghui
___
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 2/4] KVM: selftests: Setup ucall after loading program into guest memory

2022-12-07 Thread Oliver Upton
On Thu, Dec 08, 2022 at 12:24:20AM +, Sean Christopherson wrote:
> On Thu, Dec 08, 2022, Oliver Upton wrote:
> > On Wed, Dec 07, 2022 at 11:57:27PM +, Sean Christopherson wrote:
> > > > diff --git a/tools/testing/selftests/kvm/aarch64/page_fault_test.c 
> > > > b/tools/testing/selftests/kvm/aarch64/page_fault_test.c
> > > > index 92d3a91153b6..95d22cfb7b41 100644
> > > > --- a/tools/testing/selftests/kvm/aarch64/page_fault_test.c
> > > > +++ b/tools/testing/selftests/kvm/aarch64/page_fault_test.c
> > > > @@ -609,8 +609,13 @@ static void setup_memslots(struct kvm_vm *vm, 
> > > > struct test_params *p)
> > > > data_size / guest_page_size,
> > > > p->test_desc->data_memslot_flags);
> > > > vm->memslots[MEM_REGION_TEST_DATA] = TEST_DATA_MEMSLOT;
> > > > +}
> > > > +
> > > > +static void setup_ucall(struct kvm_vm *vm)
> > > > +{
> > > > +   struct userspace_mem_region *region = vm_get_mem_region(vm, 
> > > > MEM_REGION_TEST_DATA);
> > > >  
> > > > -   ucall_init(vm, data_gpa + data_size);
> > > > +   ucall_init(vm, region->region.guest_phys_addr + 
> > > > region->region.memory_size);
> > > 
> > > Isn't there a hole after CODE_AND_DATA_MEMSLOT?  I.e. after memslot 0?
> > 
> > Sure, but that's only guaranteed in the PA space.
> > 
> > > The reason
> > > I ask is because if so, then we can do the temporarily heinous, but 
> > > hopefully forward
> > > looking thing of adding a helper to wrap kvm_vm_elf_load() + ucall_init().
> > > 
> > > E.g. I think we can do this immediately, and then at some point in the 
> > > 6.2 cycle
> > > add a dedicated region+memslot for the ucall MMIO page.
> > 
> > Even still, that's just a kludge to make ucalls work. We have other
> > MMIO devices (GIC distributor, for example) that work by chance since
> > nothing conflicts with the constant GPAs we've selected in the tests.
> > 
> > I'd rather we go down the route of having an address allocator for the
> > for both the VA and PA spaces to provide carveouts at runtime.
> 
> Aren't those two separate issues?  The PA, a.k.a. memslots space, can be 
> solved
> by allocating a dedicated memslot, i.e. doesn't need a carve.  At worst, 
> collisions
> will yield very explicit asserts, which IMO is better than whatever might go 
> wrong
> with a carve out.

Perhaps the use of the term 'carveout' wasn't right here.

What I'm suggesting is we cannot rely on KVM memslots alone to act as an
allocator for the PA space. KVM can provide devices to the guest that
aren't represented as memslots. If we're trying to fix PA allocations
anyway, why not make it generic enough to suit the needs of things
beyond ucalls?

--
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 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 2/4] KVM: selftests: Setup ucall after loading program into guest memory

2022-12-07 Thread Sean Christopherson
On Thu, Dec 08, 2022, Oliver Upton wrote:
> On Wed, Dec 07, 2022 at 11:57:27PM +, Sean Christopherson wrote:
> > > diff --git a/tools/testing/selftests/kvm/aarch64/page_fault_test.c 
> > > b/tools/testing/selftests/kvm/aarch64/page_fault_test.c
> > > index 92d3a91153b6..95d22cfb7b41 100644
> > > --- a/tools/testing/selftests/kvm/aarch64/page_fault_test.c
> > > +++ b/tools/testing/selftests/kvm/aarch64/page_fault_test.c
> > > @@ -609,8 +609,13 @@ static void setup_memslots(struct kvm_vm *vm, struct 
> > > test_params *p)
> > >   data_size / guest_page_size,
> > >   p->test_desc->data_memslot_flags);
> > >   vm->memslots[MEM_REGION_TEST_DATA] = TEST_DATA_MEMSLOT;
> > > +}
> > > +
> > > +static void setup_ucall(struct kvm_vm *vm)
> > > +{
> > > + struct userspace_mem_region *region = vm_get_mem_region(vm, 
> > > MEM_REGION_TEST_DATA);
> > >  
> > > - ucall_init(vm, data_gpa + data_size);
> > > + ucall_init(vm, region->region.guest_phys_addr + 
> > > region->region.memory_size);
> > 
> > Isn't there a hole after CODE_AND_DATA_MEMSLOT?  I.e. after memslot 0?
> 
> Sure, but that's only guaranteed in the PA space.
> 
> > The reason
> > I ask is because if so, then we can do the temporarily heinous, but 
> > hopefully forward
> > looking thing of adding a helper to wrap kvm_vm_elf_load() + ucall_init().
> > 
> > E.g. I think we can do this immediately, and then at some point in the 6.2 
> > cycle
> > add a dedicated region+memslot for the ucall MMIO page.
> 
> Even still, that's just a kludge to make ucalls work. We have other
> MMIO devices (GIC distributor, for example) that work by chance since
> nothing conflicts with the constant GPAs we've selected in the tests.
> 
> I'd rather we go down the route of having an address allocator for the
> for both the VA and PA spaces to provide carveouts at runtime.

Aren't those two separate issues?  The PA, a.k.a. memslots space, can be solved
by allocating a dedicated memslot, i.e. doesn't need a carve.  At worst, 
collisions
will yield very explicit asserts, which IMO is better than whatever might go 
wrong
with a carve out.

> There's another issue with the new ucall implementation where identity
> mapping could stomp on a program segment that I'm fighting with right now
> which only further highlights the problems with our (mis)management of
> address spaces in selftests.

Oooh, this crud:

virt_pg_map(vm, mmio_gpa, mmio_gpa);

Yeah, that needs to be fixed.  But again, that's a separate issue, e.g. 
selftests
can allocate a virtual address and map the read-only memslot.
___
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


Re: [PATCH 2/4] KVM: selftests: Setup ucall after loading program into guest memory

2022-12-07 Thread Oliver Upton
On Wed, Dec 07, 2022 at 11:57:27PM +, Sean Christopherson wrote:
> On Wed, Dec 07, 2022, Oliver Upton wrote:
> > The new ucall infrastructure needs to update a couple of guest globals
> > to pass through the ucall MMIO addr and pool of ucall structs. A
> > precondition of this actually working is to have the program image
> > already loaded into guest memory.
> 
> Ouch.  Might be worth explicitly stating what goes wrong.  Even though it's 
> super
> obvious in hindsight, it still took me a few seconds to understand what
> precondition you were referring to, e.g. I was trying to figure out how 
> selecting
> the MMIO address depended on the guest code being loaded...
> 
> > 
> > Call ucall_init() after kvm_vm_elf_load(). Continue to park the ucall
> > MMIO addr after MEM_REGION_TEST_DATA.
> > 
> > Signed-off-by: Oliver Upton 
> > ---
> >  tools/testing/selftests/kvm/aarch64/page_fault_test.c | 8 +++-
> >  1 file changed, 7 insertions(+), 1 deletion(-)
> > 
> > diff --git a/tools/testing/selftests/kvm/aarch64/page_fault_test.c 
> > b/tools/testing/selftests/kvm/aarch64/page_fault_test.c
> > index 92d3a91153b6..95d22cfb7b41 100644
> > --- a/tools/testing/selftests/kvm/aarch64/page_fault_test.c
> > +++ b/tools/testing/selftests/kvm/aarch64/page_fault_test.c
> > @@ -609,8 +609,13 @@ static void setup_memslots(struct kvm_vm *vm, struct 
> > test_params *p)
> > data_size / guest_page_size,
> > p->test_desc->data_memslot_flags);
> > vm->memslots[MEM_REGION_TEST_DATA] = TEST_DATA_MEMSLOT;
> > +}
> > +
> > +static void setup_ucall(struct kvm_vm *vm)
> > +{
> > +   struct userspace_mem_region *region = vm_get_mem_region(vm, 
> > MEM_REGION_TEST_DATA);
> >  
> > -   ucall_init(vm, data_gpa + data_size);
> > +   ucall_init(vm, region->region.guest_phys_addr + 
> > region->region.memory_size);
> 
> Isn't there a hole after CODE_AND_DATA_MEMSLOT?  I.e. after memslot 0?

Sure, but that's only guaranteed in the PA space.

> The reason
> I ask is because if so, then we can do the temporarily heinous, but hopefully 
> forward
> looking thing of adding a helper to wrap kvm_vm_elf_load() + ucall_init().
> 
> E.g. I think we can do this immediately, and then at some point in the 6.2 
> cycle
> add a dedicated region+memslot for the ucall MMIO page.

Even still, that's just a kludge to make ucalls work. We have other
MMIO devices (GIC distributor, for example) that work by chance since
nothing conflicts with the constant GPAs we've selected in the tests.

I'd rather we go down the route of having an address allocator for the
for both the VA and PA spaces to provide carveouts at runtime. There's
another issue with the new ucall implementation where identity mapping
could stomp on a program segment that I'm fighting with right now which
only further highlights the problems with our (mis)management of address
spaces in selftests.

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


Re: [PATCH 2/4] KVM: selftests: Setup ucall after loading program into guest memory

2022-12-07 Thread Sean Christopherson
On Wed, Dec 07, 2022, Oliver Upton wrote:
> The new ucall infrastructure needs to update a couple of guest globals
> to pass through the ucall MMIO addr and pool of ucall structs. A
> precondition of this actually working is to have the program image
> already loaded into guest memory.

Ouch.  Might be worth explicitly stating what goes wrong.  Even though it's 
super
obvious in hindsight, it still took me a few seconds to understand what
precondition you were referring to, e.g. I was trying to figure out how 
selecting
the MMIO address depended on the guest code being loaded...

> 
> Call ucall_init() after kvm_vm_elf_load(). Continue to park the ucall
> MMIO addr after MEM_REGION_TEST_DATA.
> 
> Signed-off-by: Oliver Upton 
> ---
>  tools/testing/selftests/kvm/aarch64/page_fault_test.c | 8 +++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/testing/selftests/kvm/aarch64/page_fault_test.c 
> b/tools/testing/selftests/kvm/aarch64/page_fault_test.c
> index 92d3a91153b6..95d22cfb7b41 100644
> --- a/tools/testing/selftests/kvm/aarch64/page_fault_test.c
> +++ b/tools/testing/selftests/kvm/aarch64/page_fault_test.c
> @@ -609,8 +609,13 @@ static void setup_memslots(struct kvm_vm *vm, struct 
> test_params *p)
>   data_size / guest_page_size,
>   p->test_desc->data_memslot_flags);
>   vm->memslots[MEM_REGION_TEST_DATA] = TEST_DATA_MEMSLOT;
> +}
> +
> +static void setup_ucall(struct kvm_vm *vm)
> +{
> + struct userspace_mem_region *region = vm_get_mem_region(vm, 
> MEM_REGION_TEST_DATA);
>  
> - ucall_init(vm, data_gpa + data_size);
> + ucall_init(vm, region->region.guest_phys_addr + 
> region->region.memory_size);

Isn't there a hole after CODE_AND_DATA_MEMSLOT?  I.e. after memslot 0?  The 
reason
I ask is because if so, then we can do the temporarily heinous, but hopefully 
forward
looking thing of adding a helper to wrap kvm_vm_elf_load() + ucall_init().

E.g. I think we can do this immediately, and then at some point in the 6.2 cycle
add a dedicated region+memslot for the ucall MMIO page.

---
 .../selftests/kvm/aarch64/page_fault_test.c   | 10 +--
 .../selftests/kvm/include/kvm_util_base.h |  1 +
 tools/testing/selftests/kvm/lib/kvm_util.c| 28 +++
 3 files changed, 19 insertions(+), 20 deletions(-)

diff --git a/tools/testing/selftests/kvm/aarch64/page_fault_test.c 
b/tools/testing/selftests/kvm/aarch64/page_fault_test.c
index 95d22cfb7b41..68c47db2eb2e 100644
--- a/tools/testing/selftests/kvm/aarch64/page_fault_test.c
+++ b/tools/testing/selftests/kvm/aarch64/page_fault_test.c
@@ -611,13 +611,6 @@ static void setup_memslots(struct kvm_vm *vm, struct 
test_params *p)
vm->memslots[MEM_REGION_TEST_DATA] = TEST_DATA_MEMSLOT;
 }
 
-static void setup_ucall(struct kvm_vm *vm)
-{
-   struct userspace_mem_region *region = vm_get_mem_region(vm, 
MEM_REGION_TEST_DATA);
-
-   ucall_init(vm, region->region.guest_phys_addr + 
region->region.memory_size);
-}
-
 static void setup_default_handlers(struct test_desc *test)
 {
if (!test->mmio_handler)
@@ -706,8 +699,7 @@ static void run_test(enum vm_guest_mode mode, void *arg)
 
vm = vm_create(mode);
setup_memslots(vm, p);
-   kvm_vm_elf_load(vm, program_invocation_name);
-   setup_ucall(vm);
+   vm_init_guest_code_and_data(vm);
vcpu = vm_vcpu_add(vm, 0, guest_code);
 
setup_gva_maps(vm);
diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h 
b/tools/testing/selftests/kvm/include/kvm_util_base.h
index fbc2a79369b8..175b5ca0c061 100644
--- a/tools/testing/selftests/kvm/include/kvm_util_base.h
+++ b/tools/testing/selftests/kvm/include/kvm_util_base.h
@@ -682,6 +682,7 @@ vm_paddr_t vm_phy_page_alloc(struct kvm_vm *vm, vm_paddr_t 
paddr_min,
 vm_paddr_t vm_phy_pages_alloc(struct kvm_vm *vm, size_t num,
  vm_paddr_t paddr_min, uint32_t memslot);
 vm_paddr_t vm_alloc_page_table(struct kvm_vm *vm);
+void vm_init_guest_code_and_data(struct kvm_vm *vm);
 
 /*
  * vm_create() does KVM_CREATE_VM and little else.  __vm_create() also
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c 
b/tools/testing/selftests/kvm/lib/kvm_util.c
index c88c3ace16d2..0eab6b11a6e9 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -329,12 +329,27 @@ static uint64_t vm_nr_pages_required(enum vm_guest_mode 
mode,
return vm_adjust_num_guest_pages(mode, nr_pages);
 }
 
+void vm_init_guest_code_and_data(struct kvm_vm *vm)
+{
+   struct userspace_mem_region *slot;
+
+   kvm_vm_elf_load(vm, program_invocation_name);
+
+   /*
+* TODO: Add a dedicated memory region to carve out MMIO.  KVM treats
+* writes to read-only memslots as MMIO, and creating a read-only
+* memslot for the MMIO region would prevent silently clobbering the
+* MMIO region.
+*/
+ 

Re: [PATCH 4/4] KVM: selftests: Allocate ucall pool from MEM_REGION_DATA

2022-12-07 Thread Oliver Upton
On Wed, Dec 07, 2022 at 11:44:50PM +, Sean Christopherson wrote:
> On Wed, Dec 07, 2022, Oliver Upton wrote:
> > MEM_REGION_TEST_DATA is meant to hold data explicitly used by a
> > selftest, not implicit allocations due to the selftests infrastructure.
> > Allocate the ucall pool from MEM_REGION_DATA much like the rest of the
> > selftests library allocations.
> > 
> > Fixes: 426729b2cf2e ("KVM: selftests: Add ucall pool based implementation")
> 
> Not that it really matters because no one will backport this verbatim, but 
> this
> is the wrong commit to blame.  As of commit 426729b2cf2e, MEM_REGION_DATA 
> does not
> exist.  And similarly, the common ucall code didn't exist when Ricardo's 
> series
> introduced MEM_REGION_DATA.
> 
>   $ git show 426729b2cf2e:tools/testing/selftests/kvm/include/kvm_util_base.h 
> | grep MEM_REGION_DATA
>   $ git show 290c5b54012b7:tools/testing/selftests/kvm/lib/ucall_common.c
>   fatal: path 'tools/testing/selftests/kvm/lib/ucall_common.c' exists on 
> disk, but not in '290c5b54012b7'
> 
> The commit where the two collided is:
> 
> Fixes: cc7544101eec ("Merge tag 'kvmarm-6.2' of 
> https://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into HEAD")

Yeah, this Fixes is garbage, apologies.

I imagine Paolo is going to squash some things into the kvmarm merge, so
the Fixes tag ought to be dropped altogether.

> > Signed-off-by: Oliver Upton 
> > ---
> 
> Fixes nit aside,
> 
> Reviewed-by: Sean Christopherson 

Thanks!

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


Re: [PATCH 4/4] KVM: selftests: Allocate ucall pool from MEM_REGION_DATA

2022-12-07 Thread Sean Christopherson
On Wed, Dec 07, 2022, Oliver Upton wrote:
> MEM_REGION_TEST_DATA is meant to hold data explicitly used by a
> selftest, not implicit allocations due to the selftests infrastructure.
> Allocate the ucall pool from MEM_REGION_DATA much like the rest of the
> selftests library allocations.
> 
> Fixes: 426729b2cf2e ("KVM: selftests: Add ucall pool based implementation")

Not that it really matters because no one will backport this verbatim, but this
is the wrong commit to blame.  As of commit 426729b2cf2e, MEM_REGION_DATA does 
not
exist.  And similarly, the common ucall code didn't exist when Ricardo's series
introduced MEM_REGION_DATA.

  $ git show 426729b2cf2e:tools/testing/selftests/kvm/include/kvm_util_base.h | 
grep MEM_REGION_DATA
  $ git show 290c5b54012b7:tools/testing/selftests/kvm/lib/ucall_common.c
  fatal: path 'tools/testing/selftests/kvm/lib/ucall_common.c' exists on disk, 
but not in '290c5b54012b7'

The commit where the two collided is:

Fixes: cc7544101eec ("Merge tag 'kvmarm-6.2' of 
https://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into HEAD")

> Signed-off-by: Oliver Upton 
> ---

Fixes nit aside,

Reviewed-by: Sean Christopherson 
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


Re: [GIT PULL] KVM/arm64 updates for 6.2

2022-12-07 Thread Oliver Upton
On Tue, Dec 06, 2022 at 06:41:21PM +0100, Paolo Bonzini wrote:
> On 12/5/22 16:58, Marc Zyngier wrote:
> > - There is a lot of selftest conflicts with your own branch, see:
> > 
> >https://lore.kernel.org/r/20221201112432.4cb9a...@canb.auug.org.au
> >https://lore.kernel.org/r/20221201113626.438f1...@canb.auug.org.au
> >https://lore.kernel.org/r/20221201115741.7de32...@canb.auug.org.au
> >https://lore.kernel.org/r/20221201120939.3c19f...@canb.auug.org.au
> >https://lore.kernel.org/r/20221201131623.18ebc...@canb.auug.org.au
> > 
> >for a rather exhaustive collection.
> 
> Yeah, I saw them in Stephen's messages but missed your reply.
> 
> In retrospect, at least Gavin's series for memslot_perf_test should have
> been applied by both of us with a topic branch, but there's so many
> conflicts all over the place that it's hard to single out one series.
> It just happens.
> 
> The only conflict in non-x86 code is the following one, please check
> if I got it right.
> 
> diff --git a/tools/testing/selftests/kvm/aarch64/page_fault_test.c 
> b/tools/testing/selftests/kvm/aarch64/page_fault_test.c
> index 05bb6a6369c2..0cda70bef5d5 100644
> --- a/tools/testing/selftests/kvm/aarch64/page_fault_test.c
> +++ b/tools/testing/selftests/kvm/aarch64/page_fault_test.c
> @@ -609,6 +609,8 @@ static void setup_memslots(struct kvm_vm *vm, struct 
> test_params *p)
>   data_size / guest_page_size,
>   p->test_desc->data_memslot_flags);
>   vm->memslots[MEM_REGION_TEST_DATA] = TEST_DATA_MEMSLOT;
> +
> + ucall_init(vm, data_gpa + data_size);
>  }
>  static void setup_default_handlers(struct test_desc *test)
> @@ -704,8 +706,6 @@ static void run_test(enum vm_guest_mode mode, void *arg)
>   setup_gva_maps(vm);
> - ucall_init(vm, NULL);
> -
>   reset_event_counts();
>   /*
> 
> 
> Special care is needed here because the test uses vm_create().
> 
> I haven't pushed to kvm/next yet to give you time to check, so the
> merge is currently in kvm/queue only.

Have a look at this series, which gets things building and actually
passing again:

https://lore.kernel.org/kvm/20221207214809.489070-1-oliver.up...@linux.dev/

> > - For the 6.3 cycle, we are going to experiment with Oliver taking
> >care of most of the patch herding. I'm sure he'll do a great job,
> >but if there is the odd mistake, please cut him some slack and blame
> >me instead.
> 
> Absolutely - you both have all the slack you need, synchronization
> is harder than it seems.

Appreciated!

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


[PATCH 4/4] KVM: selftests: Allocate ucall pool from MEM_REGION_DATA

2022-12-07 Thread Oliver Upton
MEM_REGION_TEST_DATA is meant to hold data explicitly used by a
selftest, not implicit allocations due to the selftests infrastructure.
Allocate the ucall pool from MEM_REGION_DATA much like the rest of the
selftests library allocations.

Fixes: 426729b2cf2e ("KVM: selftests: Add ucall pool based implementation")
Signed-off-by: Oliver Upton 
---
 tools/testing/selftests/kvm/lib/ucall_common.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/testing/selftests/kvm/lib/ucall_common.c 
b/tools/testing/selftests/kvm/lib/ucall_common.c
index 820ce6c82829..0cc0971ce60e 100644
--- a/tools/testing/selftests/kvm/lib/ucall_common.c
+++ b/tools/testing/selftests/kvm/lib/ucall_common.c
@@ -22,7 +22,7 @@ void ucall_init(struct kvm_vm *vm, vm_paddr_t mmio_gpa)
vm_vaddr_t vaddr;
int i;
 
-   vaddr = vm_vaddr_alloc(vm, sizeof(*hdr), KVM_UTIL_MIN_VADDR);
+   vaddr = __vm_vaddr_alloc(vm, sizeof(*hdr), KVM_UTIL_MIN_VADDR, 
MEM_REGION_DATA);
hdr = (struct ucall_header *)addr_gva2hva(vm, vaddr);
memset(hdr, 0, sizeof(*hdr));
 
-- 
2.39.0.rc0.267.gcb52ba06e7-goog

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


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

2022-12-07 Thread Oliver Upton
An interesting feature of the Arm architecture is that the stage-1 MMU
supports two distinct VA regions, controlled by TTBR{0,1}_EL1. As KVM
selftests on arm64 only uses TTBR0_EL1, the VA space is constrained to
[0, 2^(va_bits-1)). This is different from other architectures that
allow for addressing low and high regions of the VA space from a single
page table.

KVM selftests' VA space allocator presumes the valid address range is
split between low and high memory based the MSB, which of course is a
poor match for arm64's TTBR0 region.

Allow architectures to override the default VA space layout. Make use of
the override to align vpages_valid with the behavior of TTBR0 on arm64.

Signed-off-by: Oliver Upton 
---
 .../testing/selftests/kvm/include/kvm_util_base.h |  1 +
 .../testing/selftests/kvm/lib/aarch64/processor.c | 10 ++
 tools/testing/selftests/kvm/lib/kvm_util.c| 15 ++-
 3 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h 
b/tools/testing/selftests/kvm/include/kvm_util_base.h
index 6cd86da698b3..fbc2a79369b8 100644
--- a/tools/testing/selftests/kvm/include/kvm_util_base.h
+++ b/tools/testing/selftests/kvm/include/kvm_util_base.h
@@ -420,6 +420,7 @@ void vm_mem_region_set_flags(struct kvm_vm *vm, uint32_t 
slot, uint32_t flags);
 void vm_mem_region_move(struct kvm_vm *vm, uint32_t slot, uint64_t new_gpa);
 void vm_mem_region_delete(struct kvm_vm *vm, uint32_t slot);
 struct kvm_vcpu *__vm_vcpu_add(struct kvm_vm *vm, uint32_t vcpu_id);
+void vm_populate_vaddr_bitmap(struct kvm_vm *vm);
 vm_vaddr_t vm_vaddr_unused_gap(struct kvm_vm *vm, size_t sz, vm_vaddr_t 
vaddr_min);
 vm_vaddr_t vm_vaddr_alloc(struct kvm_vm *vm, size_t sz, vm_vaddr_t vaddr_min);
 vm_vaddr_t __vm_vaddr_alloc(struct kvm_vm *vm, size_t sz, vm_vaddr_t vaddr_min,
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)
+{
+   /*
+* 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);
+}
+
 struct kvm_vm *vm_create(enum vm_guest_mode mode)
 {
struct kvm_vm *vm;
@@ -274,11 +283,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);
-- 
2.39.0.rc0.267.gcb52ba06e7-goog

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


[PATCH 2/4] KVM: selftests: Setup ucall after loading program into guest memory

2022-12-07 Thread Oliver Upton
The new ucall infrastructure needs to update a couple of guest globals
to pass through the ucall MMIO addr and pool of ucall structs. A
precondition of this actually working is to have the program image
already loaded into guest memory.

Call ucall_init() after kvm_vm_elf_load(). Continue to park the ucall
MMIO addr after MEM_REGION_TEST_DATA.

Signed-off-by: Oliver Upton 
---
 tools/testing/selftests/kvm/aarch64/page_fault_test.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/kvm/aarch64/page_fault_test.c 
b/tools/testing/selftests/kvm/aarch64/page_fault_test.c
index 92d3a91153b6..95d22cfb7b41 100644
--- a/tools/testing/selftests/kvm/aarch64/page_fault_test.c
+++ b/tools/testing/selftests/kvm/aarch64/page_fault_test.c
@@ -609,8 +609,13 @@ static void setup_memslots(struct kvm_vm *vm, struct 
test_params *p)
data_size / guest_page_size,
p->test_desc->data_memslot_flags);
vm->memslots[MEM_REGION_TEST_DATA] = TEST_DATA_MEMSLOT;
+}
+
+static void setup_ucall(struct kvm_vm *vm)
+{
+   struct userspace_mem_region *region = vm_get_mem_region(vm, 
MEM_REGION_TEST_DATA);
 
-   ucall_init(vm, data_gpa + data_size);
+   ucall_init(vm, region->region.guest_phys_addr + 
region->region.memory_size);
 }
 
 static void setup_default_handlers(struct test_desc *test)
@@ -702,6 +707,7 @@ static void run_test(enum vm_guest_mode mode, void *arg)
vm = vm_create(mode);
setup_memslots(vm, p);
kvm_vm_elf_load(vm, program_invocation_name);
+   setup_ucall(vm);
vcpu = vm_vcpu_add(vm, 0, guest_code);
 
setup_gva_maps(vm);
-- 
2.39.0.rc0.267.gcb52ba06e7-goog

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


[PATCH 1/4] KVM: selftests: Fix build due to ucall_uninit() removal

2022-12-07 Thread Oliver Upton
From: Mark Brown 

Today's -next fails to build on arm64 due to:

In file included from include/kvm_util.h:11,
 from aarch64/page_fault_test.c:15:
include/ucall_common.h:36:47: note: expected ‘vm_paddr_t’ {aka ‘long unsigned 
int’} but argument is of type ‘void *’
   36 | void ucall_init(struct kvm_vm *vm, vm_paddr_t mmio_gpa);
  |~~~^~~~
aarch64/page_fault_test.c:725:2: warning: implicit declaration of function 
‘ucall_uninit’; did you mean ‘ucall_init’? [-Wimplicit-function-declaration]
  725 |  ucall_uninit(vm);
  |  ^~~~
  |  ucall_init

which is caused by commit

interacting poorly with commit

   28a65567acb5 ("KVM: selftests: Drop now-unnecessary ucall_uninit()")

As is done for other ucall_uninit() users remove the call in the newly added
page_fault_test.c.

Fixes: 28a65567acb5 ("KVM: selftests: Drop now-unnecessary ucall_uninit()")
Fixes: 35c581015712 ("KVM: selftests: aarch64: Add aarch64/page_fault_test")
Signed-off-by: Mark Brown 
Cc: Sean Christopherson 
Cc: Ricardo Koller 
Cc: Marc Zyngier 
Signed-off-by: Oliver Upton 
---
 tools/testing/selftests/kvm/aarch64/page_fault_test.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/tools/testing/selftests/kvm/aarch64/page_fault_test.c 
b/tools/testing/selftests/kvm/aarch64/page_fault_test.c
index 0cda70bef5d5..92d3a91153b6 100644
--- a/tools/testing/selftests/kvm/aarch64/page_fault_test.c
+++ b/tools/testing/selftests/kvm/aarch64/page_fault_test.c
@@ -722,7 +722,6 @@ static void run_test(enum vm_guest_mode mode, void *arg)
 
vcpu_run_loop(vm, vcpu, test);
 
-   ucall_uninit(vm);
kvm_vm_free(vm);
free_uffd(test, pt_uffd, data_uffd);
 
-- 
2.39.0.rc0.267.gcb52ba06e7-goog

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


[PATCH 0/4] KVM: selftests: Fixes for ucall pool + page_fault_test

2022-12-07 Thread Oliver Upton
The combination of the pool-based ucall implementation + page_fault_test
resulted in some 'fun' bugs, not the least of which is that our handling
of the VA space on arm64 is completely wrong.

Small series to fix up the issues on kvm/queue. Patches 1-2 can probably
be squashed into Paolo's merge resolution, if desired.

Mark Brown (1):
  KVM: selftests: Fix build due to ucall_uninit() removal

Oliver Upton (3):
  KVM: selftests: Setup ucall after loading program into guest memory
  KVM: arm64: selftests: Align VA space allocator with TTBR0
  KVM: selftests: Allocate ucall pool from MEM_REGION_DATA

 .../selftests/kvm/aarch64/page_fault_test.c   |  9 +++--
 .../testing/selftests/kvm/include/kvm_util_base.h |  1 +
 .../testing/selftests/kvm/lib/aarch64/processor.c | 10 ++
 tools/testing/selftests/kvm/lib/kvm_util.c| 15 ++-
 tools/testing/selftests/kvm/lib/ucall_common.c|  2 +-
 5 files changed, 29 insertions(+), 8 deletions(-)

-- 
2.39.0.rc0.267.gcb52ba06e7-goog

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


Re: [PATCH v3 7/8] perf: Add perf_event_attr::config3

2022-12-07 Thread Rob Herring
On Tue, Dec 6, 2022 at 10:28 AM Mark Rutland  wrote:
>
> Peter, it looks like this series is blocked on the below now; what would you
> prefer out of:
>
> (a) Take this as is, and look add adding additional validation on top.
>
> (b) Add some flag to indicate a PMU driver supports config3, and have the core
> code check that, but leave the existing fields as-is for now (and 
> hopefully
> follow up with further validation later for the existing fields).

That looks something like this:

diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 853f64b6c8c2..845162b152ea 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -286,6 +286,7 @@ struct perf_event;
 #define PERF_PMU_CAP_NO_EXCLUDE0x0080
 #define PERF_PMU_CAP_AUX_OUTPUT0x0100
 #define PERF_PMU_CAP_EXTENDED_HW_TYPE  0x0200
+#define PERF_PMU_CAP_CONFIG3   0x0400

 struct perf_output_handle;

diff --git a/kernel/events/core.c b/kernel/events/core.c
index aefc1e08e015..4414ae64432a 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -11314,6 +11314,9 @@ static int perf_try_init_event(struct pmu
*pmu, struct perf_event *event)
event_has_any_exclude_flag(event))
ret = -EINVAL;

+   if (!(pmu->capabilities & PERF_PMU_CAP_CONFIG3) &&
event->attr.config3)
+   ret = -EINVAL;
+
if (ret && event->destroy)
event->destroy(event);
}
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


Re: [PATCH v14 16/39] arm64/sme: Implement traps and syscall handling for SME

2022-12-07 Thread Mark Brown
On Wed, Dec 07, 2022 at 10:00:17PM +0800, Zenghui Yu wrote:
> On 2022/4/19 19:22, Mark Brown wrote:

> > +   /*
> > +* If SME is active then exit streaming mode.  If ZA is active
> > +* then flush the SVE registers but leave userspace access to
> > +* both SVE and SME enabled, otherwise disable SME for the
> > +* task and fall through to disabling SVE too.  This means

> It looks a bit confusing to me that in the current implementation, if
> ZA is *not* active, we don't actually go to disable SME for the task
> (which IMHO can be disabled as user-space is not actively using it now).

Unlike SVE there's no overhead from leaving SME enabled, the enable bits
for SM and ZA tell us if there is extra register state to be saved so we
don't have to worry about the costs there like we do with SVE.  The only
reason for not just unconditionally enabling SME is the potentially
large backing storage required for the registers, if a task isn't using
SME there's no need to impose that overhead.  If we disable SME for
userspace after the storage has been allocated then we just require an
additional trip through EL1 to reenable it for any future usage which
would hurt performance but not really gain us anything otherwise.  We
don't want to discurage applications from disabling ZA when not in use
given that there's likely to be physical overheads from keeping it
enabled.

> > +   if (svcr & SYS_SVCR_EL0_SM_MASK)
> > +   sme_smstop_sm();

> As per the SME syscall ABI

> | On syscall PSTATE.SM will be cleared and the SVE registers will be
> | handled as per the standard SVE ABI.

> and the SVE syscall ABI

> | On syscall, V0..V31 are preserved (as without SVE).  Thus, bits
> | [127:0] of Z0..Z31 are preserved.  All other bits of Z0..Z31, and all
> | of P0..P15 and FFR become zero on return from a syscall.

> Can we infer from the documentation that V0-V31 should be preserved on
> return from a syscall? But with sme_smstop_sm(), all implemented bits of
> Z0-Z31 are set to zero by hardware. Is this intentional?

> Please fix me up if I've mis-read things here.

No, the intention is to say that we exit streaming mode and then handle
things as per the non-streaming ABI.  Exiting streaming mode has the
effect of clearing the values as you say.


signature.asc
Description: PGP signature
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


Re: [PATCH v14 16/39] arm64/sme: Implement traps and syscall handling for SME

2022-12-07 Thread Zenghui Yu

On 2022/4/19 19:22, Mark Brown wrote:


diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
index c938603b3ba0..92c69e5ac269 100644
--- a/arch/arm64/kernel/syscall.c
+++ b/arch/arm64/kernel/syscall.c
@@ -158,11 +158,36 @@ static void el0_svc_common(struct pt_regs *regs, int 
scno, int sc_nr,
syscall_trace_exit(regs);
 }
 
-static inline void sve_user_discard(void)

+/*
+ * As per the ABI exit SME streaming mode and clear the SVE state not
+ * shared with FPSIMD on syscall entry.
+ */
+static inline void fp_user_discard(void)
 {
+   /*
+* If SME is active then exit streaming mode.  If ZA is active
+* then flush the SVE registers but leave userspace access to
+* both SVE and SME enabled, otherwise disable SME for the
+* task and fall through to disabling SVE too.  This means


It looks a bit confusing to me that in the current implementation, if
ZA is *not* active, we don't actually go to disable SME for the task
(which IMHO can be disabled as user-space is not actively using it now).


+* that after a syscall we never have any streaming mode
+* register state to track, if this changes the KVM code will
+* need updating.
+*/
+   if (system_supports_sme() && test_thread_flag(TIF_SME)) {
+   u64 svcr = read_sysreg_s(SYS_SVCR_EL0);
+
+   if (svcr & SYS_SVCR_EL0_SM_MASK)
+   sme_smstop_sm();


As per the SME syscall ABI

| On syscall PSTATE.SM will be cleared and the SVE registers will be
| handled as per the standard SVE ABI.

and the SVE syscall ABI

| On syscall, V0..V31 are preserved (as without SVE).  Thus, bits
| [127:0] of Z0..Z31 are preserved.  All other bits of Z0..Z31, and all
| of P0..P15 and FFR become zero on return from a syscall.

Can we infer from the documentation that V0-V31 should be preserved on
return from a syscall? But with sme_smstop_sm(), all implemented bits of
Z0-Z31 are set to zero by hardware. Is this intentional?

Please fix me up if I've mis-read things here.


+   }
+
if (!system_supports_sve())
return;
 
+	/*

+* If SME is not active then disable SVE, the registers will
+* be cleared when userspace next attempts to access them and
+* we do not need to track the SVE register state until then.
+*/
clear_thread_flag(TIF_SVE);
 
 	/*


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


Re: [PATCH 1/2] ACPI/AEST: Initial AEST driver

2022-12-07 Thread Ruidong Tian

Hi, Tyler.

I am very interested in your work about AEST.
When do you plan to update the v2 patch series?

Best regards.

在 2022/5/9 21:37, Tyler Baicar 写道:

Hi Shuuichirou,

I should be able to get a v2 patch series out by the end of the month.

Thanks,
Tyler

On 4/20/2022 3:54 AM, ishii.shuuic...@fujitsu.com wrote:

Hi, Tyler.

When do you plan to post the v2 patch series?
Please let me know if you don't mind.

Best regards.


-Original Message-
From: Tyler Baicar 
Sent: Friday, December 17, 2021 8:33 AM
To: Ishii, Shuuichirou/石井 周一郎 ; 'Tyler 
Baicar'

; patc...@amperecomputing.com;
abdulha...@os.amperecomputing.com; dar...@os.amperecomputing.com;
catalin.mari...@arm.com; w...@kernel.org; m...@kernel.org;
james.mo...@arm.com; alexandru.eli...@arm.com; suzuki.poul...@arm.com;
lorenzo.pieral...@arm.com; guohan...@huawei.com; sudeep.ho...@arm.com;
raf...@kernel.org; l...@kernel.org; tony.l...@intel.com; b...@alien8.de;
mark.rutl...@arm.com; anshuman.khand...@arm.com;
vincenzo.frasc...@arm.com; ta...@google.com; mar...@marcan.st;
keesc...@chromium.org; jthie...@redhat.com; masahi...@kernel.org;
samitolva...@google.com; john.ga...@huawei.com; 
daniel.lezc...@linaro.org;

g...@linux.ibm.com; zhangshao...@hisilicon.com; tmri...@linux.ibm.com;
dchin...@redhat.com; t...@linutronix.de; linux-ker...@vger.kernel.org;
linux-arm-ker...@lists.infradead.org; kvmarm@lists.cs.columbia.edu;
linux-a...@vger.kernel.org; linux-e...@vger.kernel.org;
vineeth.pil...@microsoft.com
Subject: Re: [PATCH 1/2] ACPI/AEST: Initial AEST driver

Hi Shuuichirou,

Thank you for your feedback!

On 12/9/2021 3:10 AM, ishii.shuuic...@fujitsu.com wrote:

Hi, Tyler.

We would like to make a few comments.


-Original Message-
From: Tyler Baicar 
Sent: Thursday, November 25, 2021 2:07 AM
To: patc...@amperecomputing.com; abdulha...@os.amperecomputing.com;
dar...@os.amperecomputing.com; catalin.mari...@arm.com;
w...@kernel.org; m...@kernel.org; james.mo...@arm.com;
alexandru.eli...@arm.com; suzuki.poul...@arm.com;
lorenzo.pieral...@arm.com; guohan...@huawei.com;
sudeep.ho...@arm.com; raf...@kernel.org; l...@kernel.org;
tony.l...@intel.com; b...@alien8.de; mark.rutl...@arm.com;
anshuman.khand...@arm.com; vincenzo.frasc...@arm.com;
ta...@google.com; mar...@marcan.st; keesc...@chromium.org;
jthie...@redhat.com; masahi...@kernel.org; samitolva...@google.com;
john.ga...@huawei.com; daniel.lezc...@linaro.org; g...@linux.ibm.com;
zhangshao...@hisilicon.com; tmri...@linux.ibm.com;
dchin...@redhat.com; t...@linutronix.de;
linux-ker...@vger.kernel.org; linux-arm-ker...@lists.infradead.org;
kvmarm@lists.cs.columbia.edu; linux-a...@vger.kernel.org;
linux-e...@vger.kernel.org; Ishii, Shuuichirou/石井
周一郎 ; vineeth.pil...@microsoft.com
Cc: Tyler Baicar 
Subject: [PATCH 1/2] ACPI/AEST: Initial AEST driver

Add support for parsing the ARM Error Source Table and basic handling
of errors reported through both memory mapped and system register

interfaces.


Assume system register interfaces are only registered with private
peripheral interrupts (PPIs); otherwise there is no guarantee the
core handling the error is the core which took the error and has the
syndrome info in its system registers.

Add logging for all detected errors and trigger a kernel panic if
there is any uncorrected error present.

Signed-off-by: Tyler Baicar 
---

[...]


+static int __init aest_init_node(struct acpi_aest_hdr *node) {
+    union acpi_aest_processor_data *proc_data;
+    union aest_node_spec *node_spec;
+    struct aest_node_data *data;
+    int ret;
+
+    data = kzalloc(sizeof(struct aest_node_data), GFP_KERNEL);
+    if (!data)
+    return -ENOMEM;
+
+    data->node_type = node->type;
+
+    node_spec = ACPI_ADD_PTR(union aest_node_spec, node,
node->node_specific_offset);
+
+    switch (node->type) {
+    case ACPI_AEST_PROCESSOR_ERROR_NODE:
+    memcpy(&data->data, node_spec, sizeof(struct
acpi_aest_processor));
+    break;
+    case ACPI_AEST_MEMORY_ERROR_NODE:
+    memcpy(&data->data, node_spec, sizeof(struct
acpi_aest_memory));
+    break;
+    case ACPI_AEST_SMMU_ERROR_NODE:
+    memcpy(&data->data, node_spec, sizeof(struct
acpi_aest_smmu));
+    break;
+    case ACPI_AEST_VENDOR_ERROR_NODE:
+    memcpy(&data->data, node_spec, sizeof(struct
acpi_aest_vendor));
+    break;
+    case ACPI_AEST_GIC_ERROR_NODE:
+    memcpy(&data->data, node_spec, sizeof(struct
acpi_aest_gic));
+    break;
+    default:
+    kfree(data);
+    return -EINVAL;
+    }
+
+    if (node->type == ACPI_AEST_PROCESSOR_ERROR_NODE) {
+    proc_data = ACPI_ADD_PTR(union acpi_aest_processor_data,
node_spec,
+ sizeof(acpi_aest_processor));
+
+    switch (data->data.processor.resource_type) {
+    case ACPI_AEST_CACHE_RESOURCE:
+    memcpy(&data->proc_data, proc_data,
+   sizeof(struct acpi_aest_processor_cache));
+    break;
+    case ACPI_AEST_TLB_RESOURCE:
+    memcpy