* [PATCH 0/4] ARM: Cleanup following bitops improvements
@ 2024-09-02 10:03 Andrew Cooper
2024-09-02 10:03 ` [PATCH 1/4] ARM/div: Drop __div64_fls() Andrew Cooper
` (3 more replies)
0 siblings, 4 replies; 12+ messages in thread
From: Andrew Cooper @ 2024-09-02 10:03 UTC (permalink / raw)
To: Xen-devel
Cc: Andrew Cooper, Stefano Stabellini, Julien Grall,
Volodymyr Babchuk, Bertrand Marquis, Michal Orzel
Patch 1 has been posted before, but is included here just so it doesn't get
lost.
Patch 2 is a bugfix found by code inspection.
Patches 3 and 4 switch to a more efficient form.
Andrew Cooper (4):
ARM/div: Drop __div64_fls()
ARM/vgic: Correct the expression for lr_all_full()
ARM/vgic: Use for_each_set_bit() in gic_find_unused_lr()
ARM/vgic: Use for_each_set_bit() in vgic-mmio*
xen/arch/arm/gic-vgic.c | 15 +++++++------
xen/arch/arm/include/asm/div64.h | 18 +++-------------
xen/arch/arm/vgic/vgic-mmio-v2.c | 3 +--
xen/arch/arm/vgic/vgic-mmio.c | 36 +++++++++++++++++++++-----------
4 files changed, 35 insertions(+), 37 deletions(-)
--
2.39.2
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 1/4] ARM/div: Drop __div64_fls()
2024-09-02 10:03 [PATCH 0/4] ARM: Cleanup following bitops improvements Andrew Cooper
@ 2024-09-02 10:03 ` Andrew Cooper
2024-09-03 8:37 ` Michal Orzel
2024-09-02 10:03 ` [PATCH 2/4] ARM/vgic: Correct the expression for lr_all_full() Andrew Cooper
` (2 subsequent siblings)
3 siblings, 1 reply; 12+ messages in thread
From: Andrew Cooper @ 2024-09-02 10:03 UTC (permalink / raw)
To: Xen-devel
Cc: Andrew Cooper, Stefano Stabellini, Julien Grall,
Volodymyr Babchuk, Bertrand Marquis, Michal Orzel
Following the improvements to Xen's bitops, fls() does constant propagation in
all cases. Use it, and drop the local opencoded helper.
No functional change.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Stefano Stabellini <sstabellini@kernel.org>
CC: Julien Grall <julien@xen.org>
CC: Volodymyr Babchuk <Volodymyr_Babchuk@epam.com>
CC: Bertrand Marquis <bertrand.marquis@arm.com>
CC: Michal Orzel <michal.orzel@amd.com>
ARM32 gets a very minor code generation improvement:
xen.git/xen$ ../scripts/bloat-o-meter xen-syms-arm32-{before,after}
add/remove: 0/0 grow/shrink: 0/6 up/down: 0/-48 (-48)
Function old new delta
wallclock_time 288 280 -8
printk_start_of_line 560 552 -8
domain_vtimer_init 472 464 -8
do_settime 376 368 -8
burn_credits 760 752 -8
__printk_ratelimit 424 416 -8
But it's just a couple of operations improvement and no real change in code
structure. I expect that the constant propagation being done through
__builtin_clz(), rather than pure C, is giving the optimiser a bit more
information to work with.
This file also has an __GNUC__ < 4 case which seems ripe for removing...
---
xen/arch/arm/include/asm/div64.h | 18 +++---------------
1 file changed, 3 insertions(+), 15 deletions(-)
diff --git a/xen/arch/arm/include/asm/div64.h b/xen/arch/arm/include/asm/div64.h
index 0459d5cc0122..da1f1fcbd503 100644
--- a/xen/arch/arm/include/asm/div64.h
+++ b/xen/arch/arm/include/asm/div64.h
@@ -102,7 +102,7 @@
/* preserve low part of n for reminder computation */ \
__r = __n; \
/* determine number of bits to represent __b */ \
- __p = 1 << __div64_fls(__b); \
+ __p = 1 << fls(__b); \
/* compute __m = ((__p << 64) + __b - 1) / __b */ \
__m = (~0ULL / __b) * __p; \
__m += (((~0ULL % __b + 1) * __p) + __b - 1) / __b; \
@@ -150,8 +150,8 @@
__p /= (__m & -__m); \
__m /= (__m & -__m); \
} else { \
- __p >>= __div64_fls(__bits); \
- __m >>= __div64_fls(__bits); \
+ __p >>= fls(__bits); \
+ __m >>= fls(__bits); \
} \
/* No correction needed. */ \
__c = 0; \
@@ -217,18 +217,6 @@
__r; \
})
-/* our own fls implementation to make sure constant propagation is fine */
-#define __div64_fls(bits) \
-({ \
- unsigned int __left = (bits), __nr = 0; \
- if (__left & 0xffff0000) __nr += 16, __left >>= 16; \
- if (__left & 0x0000ff00) __nr += 8, __left >>= 8; \
- if (__left & 0x000000f0) __nr += 4, __left >>= 4; \
- if (__left & 0x0000000c) __nr += 2, __left >>= 2; \
- if (__left & 0x00000002) __nr += 1; \
- __nr; \
-})
-
#endif /* GCC version */
#endif /* BITS_PER_LONG */
--
2.39.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 2/4] ARM/vgic: Correct the expression for lr_all_full()
2024-09-02 10:03 [PATCH 0/4] ARM: Cleanup following bitops improvements Andrew Cooper
2024-09-02 10:03 ` [PATCH 1/4] ARM/div: Drop __div64_fls() Andrew Cooper
@ 2024-09-02 10:03 ` Andrew Cooper
2024-09-03 8:42 ` Michal Orzel
2024-09-02 10:03 ` [PATCH 3/4] ARM/vgic: Use for_each_set_bit() in gic_find_unused_lr() Andrew Cooper
2024-09-02 10:03 ` [PATCH 4/4] ARM/vgic: Use for_each_set_bit() in vgic-mmio* Andrew Cooper
3 siblings, 1 reply; 12+ messages in thread
From: Andrew Cooper @ 2024-09-02 10:03 UTC (permalink / raw)
To: Xen-devel
Cc: Andrew Cooper, Stefano Stabellini, Julien Grall,
Volodymyr Babchuk, Bertrand Marquis, Michal Orzel
The current expression hits UB with 31 LRs (shifting into the sign bit), and
malfunctions with 32 LRs (shifting beyond the range of int). Swapping 1 for
1ULL fixes some of these, but still malfunctions at 64 LRs which is the
architectural limit.
Instead, shift -1ULL right in order to create the mask.
Fixes: 596f885a3202 ("xen/arm: set GICH_HCR_UIE if all the LRs are in use")
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Stefano Stabellini <sstabellini@kernel.org>
CC: Julien Grall <julien@xen.org>
CC: Volodymyr Babchuk <Volodymyr_Babchuk@epam.com>
CC: Bertrand Marquis <bertrand.marquis@arm.com>
CC: Michal Orzel <michal.orzel@amd.com>
Found by code inspection while doing bitops work. I don't even know if
there's a platform that really has 31 LRs, but the rest of Xen's code is
written with the expectation that there may be 64.
---
xen/arch/arm/gic-vgic.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/xen/arch/arm/gic-vgic.c b/xen/arch/arm/gic-vgic.c
index 9aa245a36d98..3f14aab2efc7 100644
--- a/xen/arch/arm/gic-vgic.c
+++ b/xen/arch/arm/gic-vgic.c
@@ -16,7 +16,8 @@
#include <asm/gic.h>
#include <asm/vgic.h>
-#define lr_all_full() (this_cpu(lr_mask) == ((1 << gic_get_nr_lrs()) - 1))
+#define lr_all_full() \
+ (this_cpu(lr_mask) == (-1ULL >> (64 - gic_get_nr_lrs())))
#undef GIC_DEBUG
--
2.39.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 3/4] ARM/vgic: Use for_each_set_bit() in gic_find_unused_lr()
2024-09-02 10:03 [PATCH 0/4] ARM: Cleanup following bitops improvements Andrew Cooper
2024-09-02 10:03 ` [PATCH 1/4] ARM/div: Drop __div64_fls() Andrew Cooper
2024-09-02 10:03 ` [PATCH 2/4] ARM/vgic: Correct the expression for lr_all_full() Andrew Cooper
@ 2024-09-02 10:03 ` Andrew Cooper
2024-09-03 8:46 ` Michal Orzel
2024-09-02 10:03 ` [PATCH 4/4] ARM/vgic: Use for_each_set_bit() in vgic-mmio* Andrew Cooper
3 siblings, 1 reply; 12+ messages in thread
From: Andrew Cooper @ 2024-09-02 10:03 UTC (permalink / raw)
To: Xen-devel
Cc: Andrew Cooper, Stefano Stabellini, Julien Grall,
Volodymyr Babchuk, Bertrand Marquis, Michal Orzel
There are no bits set in lr_mask beyond nr_lrs, so when substituting
bitmap_for_each() for for_each_set_bit(), we don't need to worry about the
upper bound.
However, the type of lr_mask does matter, so switch it to be uint64_t * and
move unsigned long * override until the find_next_zero_bit() call.
Move lr_val into a narrower scope and drop used_lr as it's declared by
for_each_set_bit() itself.
Drop the nr_lrs variable and use gic_get_nr_lrs() in the one location its now
used. It hides a triple pointer defererence, and while it may not be needed
in the PRISTINE case, it certainly doesn't need to be live across the rest of
the function.
No functional change.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Stefano Stabellini <sstabellini@kernel.org>
CC: Julien Grall <julien@xen.org>
CC: Volodymyr Babchuk <Volodymyr_Babchuk@epam.com>
CC: Bertrand Marquis <bertrand.marquis@arm.com>
CC: Michal Orzel <michal.orzel@amd.com>
ARM64:
$ ../scripts/bloat-o-meter xen-syms-arm64-{before,after}
add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-28 (-28)
Function old new delta
gic_find_unused_lr.constprop 228 200 -28
inc -2 find_next_bit()
ARM32:
$ ../scripts/bloat-o-meter xen-syms-arm32-{before,after}
add/remove: 0/0 grow/shrink: 1/0 up/down: 48/0 (48)
Function old new delta
gic_find_unused_lr 260 308 +48
because uint64_t, but -2 _find_{first,next}_bit_le()
---
xen/arch/arm/gic-vgic.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/xen/arch/arm/gic-vgic.c b/xen/arch/arm/gic-vgic.c
index 3f14aab2efc7..ea48c5375a91 100644
--- a/xen/arch/arm/gic-vgic.c
+++ b/xen/arch/arm/gic-vgic.c
@@ -102,25 +102,23 @@ static unsigned int gic_find_unused_lr(struct vcpu *v,
struct pending_irq *p,
unsigned int lr)
{
- unsigned int nr_lrs = gic_get_nr_lrs();
- unsigned long *lr_mask = (unsigned long *) &this_cpu(lr_mask);
- struct gic_lr lr_val;
+ uint64_t *lr_mask = &this_cpu(lr_mask);
ASSERT(spin_is_locked(&v->arch.vgic.lock));
if ( unlikely(test_bit(GIC_IRQ_GUEST_PRISTINE_LPI, &p->status)) )
{
- unsigned int used_lr;
-
- bitmap_for_each ( used_lr, lr_mask, nr_lrs )
+ for_each_set_bit ( used_lr, *lr_mask )
{
+ struct gic_lr lr_val;
+
gic_hw_ops->read_lr(used_lr, &lr_val);
if ( lr_val.virq == p->irq )
return used_lr;
}
}
- lr = find_next_zero_bit(lr_mask, nr_lrs, lr);
+ lr = find_next_zero_bit((unsigned long *)lr_mask, gic_get_nr_lrs(), lr);
return lr;
}
--
2.39.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 4/4] ARM/vgic: Use for_each_set_bit() in vgic-mmio*
2024-09-02 10:03 [PATCH 0/4] ARM: Cleanup following bitops improvements Andrew Cooper
` (2 preceding siblings ...)
2024-09-02 10:03 ` [PATCH 3/4] ARM/vgic: Use for_each_set_bit() in gic_find_unused_lr() Andrew Cooper
@ 2024-09-02 10:03 ` Andrew Cooper
2024-09-03 10:30 ` Michal Orzel
3 siblings, 1 reply; 12+ messages in thread
From: Andrew Cooper @ 2024-09-02 10:03 UTC (permalink / raw)
To: Xen-devel
Cc: Andrew Cooper, Stefano Stabellini, Julien Grall,
Volodymyr Babchuk, Bertrand Marquis, Michal Orzel
These are all loops over a scalar value, and don't need to call general bitop
helpers behind the scenes.
No functional change.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Stefano Stabellini <sstabellini@kernel.org>
CC: Julien Grall <julien@xen.org>
CC: Volodymyr Babchuk <Volodymyr_Babchuk@epam.com>
CC: Bertrand Marquis <bertrand.marquis@arm.com>
CC: Michal Orzel <michal.orzel@amd.com>
Slighly RFC. It's unclear whether len is the size of the register, or the
size of the access. For sub-GPR accesses, won't the upper bits be clear
anyway? If so, this can be simplified further.
$ ../scripts/bloat-o-meter xen-syms-arm64-{before,after}
add/remove: 0/0 grow/shrink: 2/5 up/down: 20/-140 (-120)
Function old new delta
vgic_mmio_write_spending 320 332 +12
vgic_mmio_write_cpending 368 376 +8
vgic_mmio_write_sactive 192 176 -16
vgic_mmio_write_cactive 192 176 -16
vgic_mmio_write_cenable 316 288 -28
vgic_mmio_write_senable 320 284 -36
vgic_mmio_write_sgir 344 300 -44
$ ../scripts/bloat-o-meter xen-syms-arm32-{before,after}
add/remove: 0/0 grow/shrink: 0/4 up/down: 0/-32 (-32)
Function old new delta
vgic_mmio_write_sactive 204 200 -4
vgic_mmio_write_cpending 464 460 -4
vgic_mmio_write_cactive 204 200 -4
vgic_mmio_write_sgir 336 316 -20
---
xen/arch/arm/vgic/vgic-mmio-v2.c | 3 +--
xen/arch/arm/vgic/vgic-mmio.c | 36 +++++++++++++++++++++-----------
2 files changed, 25 insertions(+), 14 deletions(-)
diff --git a/xen/arch/arm/vgic/vgic-mmio-v2.c b/xen/arch/arm/vgic/vgic-mmio-v2.c
index 670b335db2c3..42fac0403f07 100644
--- a/xen/arch/arm/vgic/vgic-mmio-v2.c
+++ b/xen/arch/arm/vgic/vgic-mmio-v2.c
@@ -90,7 +90,6 @@ static void vgic_mmio_write_sgir(struct vcpu *source_vcpu,
unsigned int intid = val & GICD_SGI_INTID_MASK;
unsigned long targets = (val & GICD_SGI_TARGET_MASK) >>
GICD_SGI_TARGET_SHIFT;
- unsigned int vcpu_id;
switch ( val & GICD_SGI_TARGET_LIST_MASK )
{
@@ -108,7 +107,7 @@ static void vgic_mmio_write_sgir(struct vcpu *source_vcpu,
return;
}
- bitmap_for_each ( vcpu_id, &targets, 8 )
+ for_each_set_bit ( vcpu_id, (uint8_t)targets )
{
struct vcpu *vcpu = d->vcpu[vcpu_id];
struct vgic_irq *irq = vgic_get_irq(d, vcpu, intid);
diff --git a/xen/arch/arm/vgic/vgic-mmio.c b/xen/arch/arm/vgic/vgic-mmio.c
index bd4caf7fc326..f7c336a238ab 100644
--- a/xen/arch/arm/vgic/vgic-mmio.c
+++ b/xen/arch/arm/vgic/vgic-mmio.c
@@ -69,9 +69,11 @@ void vgic_mmio_write_senable(struct vcpu *vcpu,
unsigned long val)
{
uint32_t intid = VGIC_ADDR_TO_INTID(addr, 1);
- unsigned int i;
- bitmap_for_each ( i, &val, len * 8 )
+ if ( len < sizeof(val) )
+ val &= (1UL << (len * 8)) - 1;
+
+ for_each_set_bit ( i, val )
{
struct vgic_irq *irq = vgic_get_irq(vcpu->domain, vcpu, intid + i);
unsigned long flags;
@@ -114,9 +116,11 @@ void vgic_mmio_write_cenable(struct vcpu *vcpu,
unsigned long val)
{
uint32_t intid = VGIC_ADDR_TO_INTID(addr, 1);
- unsigned int i;
- bitmap_for_each ( i, &val, len * 8 )
+ if ( len < sizeof(val) )
+ val &= (1UL << (len * 8)) - 1;
+
+ for_each_set_bit ( i, val )
{
struct vgic_irq *irq;
unsigned long flags;
@@ -182,11 +186,13 @@ void vgic_mmio_write_spending(struct vcpu *vcpu,
unsigned long val)
{
uint32_t intid = VGIC_ADDR_TO_INTID(addr, 1);
- unsigned int i;
unsigned long flags;
irq_desc_t *desc;
- bitmap_for_each ( i, &val, len * 8 )
+ if ( len < sizeof(val) )
+ val &= (1UL << (len * 8)) - 1;
+
+ for_each_set_bit ( i, val )
{
struct vgic_irq *irq = vgic_get_irq(vcpu->domain, vcpu, intid + i);
@@ -230,11 +236,13 @@ void vgic_mmio_write_cpending(struct vcpu *vcpu,
unsigned long val)
{
uint32_t intid = VGIC_ADDR_TO_INTID(addr, 1);
- unsigned int i;
unsigned long flags;
irq_desc_t *desc;
- bitmap_for_each ( i, &val, len * 8 )
+ if ( len < sizeof(val) )
+ val &= (1UL << (len * 8)) - 1;
+
+ for_each_set_bit ( i, val )
{
struct vgic_irq *irq = vgic_get_irq(vcpu->domain, vcpu, intid + i);
@@ -326,9 +334,11 @@ void vgic_mmio_write_cactive(struct vcpu *vcpu,
unsigned long val)
{
uint32_t intid = VGIC_ADDR_TO_INTID(addr, 1);
- unsigned int i;
- bitmap_for_each ( i, &val, len * 8 )
+ if ( len < sizeof(val) )
+ val &= (1UL << (len * 8)) - 1;
+
+ for_each_set_bit ( i, val )
{
struct vgic_irq *irq = vgic_get_irq(vcpu->domain, vcpu, intid + i);
@@ -356,9 +366,11 @@ void vgic_mmio_write_sactive(struct vcpu *vcpu,
unsigned long val)
{
uint32_t intid = VGIC_ADDR_TO_INTID(addr, 1);
- unsigned int i;
- bitmap_for_each ( i, &val, len * 8 )
+ if ( len < sizeof(val) )
+ val &= (1UL << (len * 8)) - 1;
+
+ for_each_set_bit ( i, val )
{
struct vgic_irq *irq = vgic_get_irq(vcpu->domain, vcpu, intid + i);
--
2.39.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 1/4] ARM/div: Drop __div64_fls()
2024-09-02 10:03 ` [PATCH 1/4] ARM/div: Drop __div64_fls() Andrew Cooper
@ 2024-09-03 8:37 ` Michal Orzel
0 siblings, 0 replies; 12+ messages in thread
From: Michal Orzel @ 2024-09-03 8:37 UTC (permalink / raw)
To: Andrew Cooper, Xen-devel
Cc: Stefano Stabellini, Julien Grall, Volodymyr Babchuk,
Bertrand Marquis
On 02/09/2024 12:03, Andrew Cooper wrote:
>
>
> Following the improvements to Xen's bitops, fls() does constant propagation in
> all cases. Use it, and drop the local opencoded helper.
>
> No functional change.
>
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Michal Orzel <michal.orzel@amd.com>
> ---
> CC: Stefano Stabellini <sstabellini@kernel.org>
> CC: Julien Grall <julien@xen.org>
> CC: Volodymyr Babchuk <Volodymyr_Babchuk@epam.com>
> CC: Bertrand Marquis <bertrand.marquis@arm.com>
> CC: Michal Orzel <michal.orzel@amd.com>
>
> ARM32 gets a very minor code generation improvement:
>
> xen.git/xen$ ../scripts/bloat-o-meter xen-syms-arm32-{before,after}
> add/remove: 0/0 grow/shrink: 0/6 up/down: 0/-48 (-48)
> Function old new delta
> wallclock_time 288 280 -8
> printk_start_of_line 560 552 -8
> domain_vtimer_init 472 464 -8
> do_settime 376 368 -8
> burn_credits 760 752 -8
> __printk_ratelimit 424 416 -8
>
> But it's just a couple of operations improvement and no real change in code
> structure. I expect that the constant propagation being done through
> __builtin_clz(), rather than pure C, is giving the optimiser a bit more
> information to work with.
>
> This file also has an __GNUC__ < 4 case which seems ripe for removing...
Agree and noted.
~Michal
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 2/4] ARM/vgic: Correct the expression for lr_all_full()
2024-09-02 10:03 ` [PATCH 2/4] ARM/vgic: Correct the expression for lr_all_full() Andrew Cooper
@ 2024-09-03 8:42 ` Michal Orzel
0 siblings, 0 replies; 12+ messages in thread
From: Michal Orzel @ 2024-09-03 8:42 UTC (permalink / raw)
To: Andrew Cooper, Xen-devel
Cc: Stefano Stabellini, Julien Grall, Volodymyr Babchuk,
Bertrand Marquis
On 02/09/2024 12:03, Andrew Cooper wrote:
>
>
> The current expression hits UB with 31 LRs (shifting into the sign bit), and
> malfunctions with 32 LRs (shifting beyond the range of int). Swapping 1 for
> 1ULL fixes some of these, but still malfunctions at 64 LRs which is the
> architectural limit.
>
> Instead, shift -1ULL right in order to create the mask.
>
> Fixes: 596f885a3202 ("xen/arm: set GICH_HCR_UIE if all the LRs are in use")
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Michal Orzel <michal.orzel@amd.com>
> ---
> CC: Stefano Stabellini <sstabellini@kernel.org>
> CC: Julien Grall <julien@xen.org>
> CC: Volodymyr Babchuk <Volodymyr_Babchuk@epam.com>
> CC: Bertrand Marquis <bertrand.marquis@arm.com>
> CC: Michal Orzel <michal.orzel@amd.com>
>
> Found by code inspection while doing bitops work. I don't even know if
> there's a platform that really has 31 LRs, but the rest of Xen's code is
> written with the expectation that there may be 64.
So, for GICv2 the limit is 64 and for GICv3 the limit is 16. This made me realize we need to
fix the mask for GICv3 (ICH_VTR_NRLRGS) from 0x3f to 0xf. I'll send a patch.
> ---
> xen/arch/arm/gic-vgic.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/xen/arch/arm/gic-vgic.c b/xen/arch/arm/gic-vgic.c
> index 9aa245a36d98..3f14aab2efc7 100644
> --- a/xen/arch/arm/gic-vgic.c
> +++ b/xen/arch/arm/gic-vgic.c
> @@ -16,7 +16,8 @@
> #include <asm/gic.h>
> #include <asm/vgic.h>
>
> -#define lr_all_full() (this_cpu(lr_mask) == ((1 << gic_get_nr_lrs()) - 1))
> +#define lr_all_full() \
> + (this_cpu(lr_mask) == (-1ULL >> (64 - gic_get_nr_lrs())))
>
> #undef GIC_DEBUG
>
> --
> 2.39.2
>
~Michal
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 3/4] ARM/vgic: Use for_each_set_bit() in gic_find_unused_lr()
2024-09-02 10:03 ` [PATCH 3/4] ARM/vgic: Use for_each_set_bit() in gic_find_unused_lr() Andrew Cooper
@ 2024-09-03 8:46 ` Michal Orzel
2024-09-03 13:07 ` Andrew Cooper
0 siblings, 1 reply; 12+ messages in thread
From: Michal Orzel @ 2024-09-03 8:46 UTC (permalink / raw)
To: Andrew Cooper, Xen-devel
Cc: Stefano Stabellini, Julien Grall, Volodymyr Babchuk,
Bertrand Marquis
On 02/09/2024 12:03, Andrew Cooper wrote:
>
>
> There are no bits set in lr_mask beyond nr_lrs, so when substituting
> bitmap_for_each() for for_each_set_bit(), we don't need to worry about the
> upper bound.
>
> However, the type of lr_mask does matter, so switch it to be uint64_t * and
> move unsigned long * override until the find_next_zero_bit() call.
>
> Move lr_val into a narrower scope and drop used_lr as it's declared by
> for_each_set_bit() itself.
>
> Drop the nr_lrs variable and use gic_get_nr_lrs() in the one location its now
> used. It hides a triple pointer defererence, and while it may not be needed
s/defererence/dereference
> in the PRISTINE case, it certainly doesn't need to be live across the rest of
> the function.
>
> No functional change.
>
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Michal Orzel <michal.orzel@amd.com>
~Michal
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 4/4] ARM/vgic: Use for_each_set_bit() in vgic-mmio*
2024-09-02 10:03 ` [PATCH 4/4] ARM/vgic: Use for_each_set_bit() in vgic-mmio* Andrew Cooper
@ 2024-09-03 10:30 ` Michal Orzel
2024-09-03 13:19 ` Andrew Cooper
0 siblings, 1 reply; 12+ messages in thread
From: Michal Orzel @ 2024-09-03 10:30 UTC (permalink / raw)
To: Andrew Cooper, Xen-devel, Julien Grall
Cc: Stefano Stabellini, Volodymyr Babchuk, Bertrand Marquis
On 02/09/2024 12:03, Andrew Cooper wrote:
>
>
> These are all loops over a scalar value, and don't need to call general bitop
> helpers behind the scenes.
>
> No functional change.
>
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
> ---
> CC: Stefano Stabellini <sstabellini@kernel.org>
> CC: Julien Grall <julien@xen.org>
> CC: Volodymyr Babchuk <Volodymyr_Babchuk@epam.com>
> CC: Bertrand Marquis <bertrand.marquis@arm.com>
> CC: Michal Orzel <michal.orzel@amd.com>
>
> Slighly RFC. It's unclear whether len is the size of the register, or the
> size of the access. For sub-GPR accesses, won't the upper bits be clear
> anyway? If so, this can be simplified further.
See dispatch_mmio_write(). "len" refers to access size (i.e. 1/4/8 bytes). Each register is defined
with a region access i.e. VGIC_ACCESS_32bit that is compared with the actual access. In the current code
there is no register with 8B access. If there is a mismatch, there will be a data abort injected.
Also, the top 32-bits are not cleared anywhere, so I don't think we can drop masking. @Julien?
>
> $ ../scripts/bloat-o-meter xen-syms-arm64-{before,after}
> add/remove: 0/0 grow/shrink: 2/5 up/down: 20/-140 (-120)
> Function old new delta
> vgic_mmio_write_spending 320 332 +12
> vgic_mmio_write_cpending 368 376 +8
> vgic_mmio_write_sactive 192 176 -16
> vgic_mmio_write_cactive 192 176 -16
> vgic_mmio_write_cenable 316 288 -28
> vgic_mmio_write_senable 320 284 -36
> vgic_mmio_write_sgir 344 300 -44
>
> $ ../scripts/bloat-o-meter xen-syms-arm32-{before,after}
> add/remove: 0/0 grow/shrink: 0/4 up/down: 0/-32 (-32)
> Function old new delta
> vgic_mmio_write_sactive 204 200 -4
> vgic_mmio_write_cpending 464 460 -4
> vgic_mmio_write_cactive 204 200 -4
> vgic_mmio_write_sgir 336 316 -20
> ---
> xen/arch/arm/vgic/vgic-mmio-v2.c | 3 +--
> xen/arch/arm/vgic/vgic-mmio.c | 36 +++++++++++++++++++++-----------
> 2 files changed, 25 insertions(+), 14 deletions(-)
>
> diff --git a/xen/arch/arm/vgic/vgic-mmio-v2.c b/xen/arch/arm/vgic/vgic-mmio-v2.c
> index 670b335db2c3..42fac0403f07 100644
> --- a/xen/arch/arm/vgic/vgic-mmio-v2.c
> +++ b/xen/arch/arm/vgic/vgic-mmio-v2.c
> @@ -90,7 +90,6 @@ static void vgic_mmio_write_sgir(struct vcpu *source_vcpu,
> unsigned int intid = val & GICD_SGI_INTID_MASK;
> unsigned long targets = (val & GICD_SGI_TARGET_MASK) >>
> GICD_SGI_TARGET_SHIFT;
> - unsigned int vcpu_id;
>
> switch ( val & GICD_SGI_TARGET_LIST_MASK )
> {
> @@ -108,7 +107,7 @@ static void vgic_mmio_write_sgir(struct vcpu *source_vcpu,
> return;
> }
>
> - bitmap_for_each ( vcpu_id, &targets, 8 )
> + for_each_set_bit ( vcpu_id, (uint8_t)targets )
> {
> struct vcpu *vcpu = d->vcpu[vcpu_id];
> struct vgic_irq *irq = vgic_get_irq(d, vcpu, intid);
> diff --git a/xen/arch/arm/vgic/vgic-mmio.c b/xen/arch/arm/vgic/vgic-mmio.c
> index bd4caf7fc326..f7c336a238ab 100644
> --- a/xen/arch/arm/vgic/vgic-mmio.c
> +++ b/xen/arch/arm/vgic/vgic-mmio.c
> @@ -69,9 +69,11 @@ void vgic_mmio_write_senable(struct vcpu *vcpu,
> unsigned long val)
> {
> uint32_t intid = VGIC_ADDR_TO_INTID(addr, 1);
> - unsigned int i;
>
> - bitmap_for_each ( i, &val, len * 8 )
> + if ( len < sizeof(val) )
> + val &= (1UL << (len * 8)) - 1;
> +
> + for_each_set_bit ( i, val )
> {
> struct vgic_irq *irq = vgic_get_irq(vcpu->domain, vcpu, intid + i);
> unsigned long flags;
> @@ -114,9 +116,11 @@ void vgic_mmio_write_cenable(struct vcpu *vcpu,
> unsigned long val)
> {
> uint32_t intid = VGIC_ADDR_TO_INTID(addr, 1);
> - unsigned int i;
>
> - bitmap_for_each ( i, &val, len * 8 )
> + if ( len < sizeof(val) )
> + val &= (1UL << (len * 8)) - 1;
> +
> + for_each_set_bit ( i, val )
> {
> struct vgic_irq *irq;
> unsigned long flags;
> @@ -182,11 +186,13 @@ void vgic_mmio_write_spending(struct vcpu *vcpu,
> unsigned long val)
> {
> uint32_t intid = VGIC_ADDR_TO_INTID(addr, 1);
> - unsigned int i;
> unsigned long flags;
> irq_desc_t *desc;
>
> - bitmap_for_each ( i, &val, len * 8 )
> + if ( len < sizeof(val) )
> + val &= (1UL << (len * 8)) - 1;
> +
> + for_each_set_bit ( i, val )
> {
> struct vgic_irq *irq = vgic_get_irq(vcpu->domain, vcpu, intid + i);
>
> @@ -230,11 +236,13 @@ void vgic_mmio_write_cpending(struct vcpu *vcpu,
> unsigned long val)
> {
> uint32_t intid = VGIC_ADDR_TO_INTID(addr, 1);
> - unsigned int i;
> unsigned long flags;
> irq_desc_t *desc;
>
> - bitmap_for_each ( i, &val, len * 8 )
> + if ( len < sizeof(val) )
> + val &= (1UL << (len * 8)) - 1;
> +
> + for_each_set_bit ( i, val )
> {
> struct vgic_irq *irq = vgic_get_irq(vcpu->domain, vcpu, intid + i);
>
> @@ -326,9 +334,11 @@ void vgic_mmio_write_cactive(struct vcpu *vcpu,
> unsigned long val)
> {
> uint32_t intid = VGIC_ADDR_TO_INTID(addr, 1);
> - unsigned int i;
>
> - bitmap_for_each ( i, &val, len * 8 )
> + if ( len < sizeof(val) )
> + val &= (1UL << (len * 8)) - 1;
> +
> + for_each_set_bit ( i, val )
> {
> struct vgic_irq *irq = vgic_get_irq(vcpu->domain, vcpu, intid + i);
>
> @@ -356,9 +366,11 @@ void vgic_mmio_write_sactive(struct vcpu *vcpu,
> unsigned long val)
> {
> uint32_t intid = VGIC_ADDR_TO_INTID(addr, 1);
> - unsigned int i;
>
> - bitmap_for_each ( i, &val, len * 8 )
> + if ( len < sizeof(val) )
> + val &= (1UL << (len * 8)) - 1;
> +
> + for_each_set_bit ( i, val )
> {
> struct vgic_irq *irq = vgic_get_irq(vcpu->domain, vcpu, intid + i);
>
> --
> 2.39.2
>
~Michal
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 3/4] ARM/vgic: Use for_each_set_bit() in gic_find_unused_lr()
2024-09-03 8:46 ` Michal Orzel
@ 2024-09-03 13:07 ` Andrew Cooper
0 siblings, 0 replies; 12+ messages in thread
From: Andrew Cooper @ 2024-09-03 13:07 UTC (permalink / raw)
To: Michal Orzel, Xen-devel
Cc: Stefano Stabellini, Julien Grall, Volodymyr Babchuk,
Bertrand Marquis
On 03/09/2024 9:46 am, Michal Orzel wrote:
>
> On 02/09/2024 12:03, Andrew Cooper wrote:
>>
>> There are no bits set in lr_mask beyond nr_lrs, so when substituting
>> bitmap_for_each() for for_each_set_bit(), we don't need to worry about the
>> upper bound.
>>
>> However, the type of lr_mask does matter, so switch it to be uint64_t * and
>> move unsigned long * override until the find_next_zero_bit() call.
>>
>> Move lr_val into a narrower scope and drop used_lr as it's declared by
>> for_each_set_bit() itself.
>>
>> Drop the nr_lrs variable and use gic_get_nr_lrs() in the one location its now
>> used. It hides a triple pointer defererence, and while it may not be needed
> s/defererence/dereference
Fixed.
>
>> in the PRISTINE case, it certainly doesn't need to be live across the rest of
>> the function.
>>
>> No functional change.
>>
>> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
> Reviewed-by: Michal Orzel <michal.orzel@amd.com>
Thanks.
~Andrew
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 4/4] ARM/vgic: Use for_each_set_bit() in vgic-mmio*
2024-09-03 10:30 ` Michal Orzel
@ 2024-09-03 13:19 ` Andrew Cooper
2024-09-09 21:54 ` Julien Grall
0 siblings, 1 reply; 12+ messages in thread
From: Andrew Cooper @ 2024-09-03 13:19 UTC (permalink / raw)
To: Michal Orzel, Xen-devel, Julien Grall
Cc: Stefano Stabellini, Volodymyr Babchuk, Bertrand Marquis
On 03/09/2024 11:30 am, Michal Orzel wrote:
>
> On 02/09/2024 12:03, Andrew Cooper wrote:
>>
>> These are all loops over a scalar value, and don't need to call general bitop
>> helpers behind the scenes.
>>
>> No functional change.
>>
>> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
>> ---
>> CC: Stefano Stabellini <sstabellini@kernel.org>
>> CC: Julien Grall <julien@xen.org>
>> CC: Volodymyr Babchuk <Volodymyr_Babchuk@epam.com>
>> CC: Bertrand Marquis <bertrand.marquis@arm.com>
>> CC: Michal Orzel <michal.orzel@amd.com>
>>
>> Slighly RFC. It's unclear whether len is the size of the register, or the
>> size of the access. For sub-GPR accesses, won't the upper bits be clear
>> anyway? If so, this can be simplified further.
> See dispatch_mmio_write(). "len" refers to access size (i.e. 1/4/8 bytes). Each register is defined
> with a region access i.e. VGIC_ACCESS_32bit that is compared with the actual access. In the current code
> there is no register with 8B access. If there is a mismatch, there will be a data abort injected.
> Also, the top 32-bits are not cleared anywhere, so I don't think we can drop masking. @Julien?
Ok, so it is necessary right now to have the clamping logic in every
callback.
However, given that the size is validated before dispatching, clamping
once in dispatch_mmio_write() would save a lot of repeated code in the
callbacks.
i.e., I think this:
diff --git a/xen/arch/arm/vgic/vgic-mmio.c b/xen/arch/arm/vgic/vgic-mmio.c
index bd4caf7fc326..e8b9805a0b2c 100644
--- a/xen/arch/arm/vgic/vgic-mmio.c
+++ b/xen/arch/arm/vgic/vgic-mmio.c
@@ -590,6 +590,9 @@ static int dispatch_mmio_write(struct vcpu *vcpu,
mmio_info_t *info,
if ( !region )
return 0;
+ if ( len < sizeof(data) )
+ data &= ~((1UL << (len * 8)) - 1);
+
switch (iodev->iodev_type)
{
case IODEV_DIST:
would work to replace every if() introduced below.
~Andrew
>
>> $ ../scripts/bloat-o-meter xen-syms-arm64-{before,after}
>> add/remove: 0/0 grow/shrink: 2/5 up/down: 20/-140 (-120)
>> Function old new delta
>> vgic_mmio_write_spending 320 332 +12
>> vgic_mmio_write_cpending 368 376 +8
>> vgic_mmio_write_sactive 192 176 -16
>> vgic_mmio_write_cactive 192 176 -16
>> vgic_mmio_write_cenable 316 288 -28
>> vgic_mmio_write_senable 320 284 -36
>> vgic_mmio_write_sgir 344 300 -44
>>
>> $ ../scripts/bloat-o-meter xen-syms-arm32-{before,after}
>> add/remove: 0/0 grow/shrink: 0/4 up/down: 0/-32 (-32)
>> Function old new delta
>> vgic_mmio_write_sactive 204 200 -4
>> vgic_mmio_write_cpending 464 460 -4
>> vgic_mmio_write_cactive 204 200 -4
>> vgic_mmio_write_sgir 336 316 -20
>> ---
>> xen/arch/arm/vgic/vgic-mmio-v2.c | 3 +--
>> xen/arch/arm/vgic/vgic-mmio.c | 36 +++++++++++++++++++++-----------
>> 2 files changed, 25 insertions(+), 14 deletions(-)
>>
>> diff --git a/xen/arch/arm/vgic/vgic-mmio-v2.c b/xen/arch/arm/vgic/vgic-mmio-v2.c
>> index 670b335db2c3..42fac0403f07 100644
>> --- a/xen/arch/arm/vgic/vgic-mmio-v2.c
>> +++ b/xen/arch/arm/vgic/vgic-mmio-v2.c
>> @@ -90,7 +90,6 @@ static void vgic_mmio_write_sgir(struct vcpu *source_vcpu,
>> unsigned int intid = val & GICD_SGI_INTID_MASK;
>> unsigned long targets = (val & GICD_SGI_TARGET_MASK) >>
>> GICD_SGI_TARGET_SHIFT;
>> - unsigned int vcpu_id;
>>
>> switch ( val & GICD_SGI_TARGET_LIST_MASK )
>> {
>> @@ -108,7 +107,7 @@ static void vgic_mmio_write_sgir(struct vcpu *source_vcpu,
>> return;
>> }
>>
>> - bitmap_for_each ( vcpu_id, &targets, 8 )
>> + for_each_set_bit ( vcpu_id, (uint8_t)targets )
>> {
>> struct vcpu *vcpu = d->vcpu[vcpu_id];
>> struct vgic_irq *irq = vgic_get_irq(d, vcpu, intid);
>> diff --git a/xen/arch/arm/vgic/vgic-mmio.c b/xen/arch/arm/vgic/vgic-mmio.c
>> index bd4caf7fc326..f7c336a238ab 100644
>> --- a/xen/arch/arm/vgic/vgic-mmio.c
>> +++ b/xen/arch/arm/vgic/vgic-mmio.c
>> @@ -69,9 +69,11 @@ void vgic_mmio_write_senable(struct vcpu *vcpu,
>> unsigned long val)
>> {
>> uint32_t intid = VGIC_ADDR_TO_INTID(addr, 1);
>> - unsigned int i;
>>
>> - bitmap_for_each ( i, &val, len * 8 )
>> + if ( len < sizeof(val) )
>> + val &= (1UL << (len * 8)) - 1;
>> +
>> + for_each_set_bit ( i, val )
>> {
>> struct vgic_irq *irq = vgic_get_irq(vcpu->domain, vcpu, intid + i);
>> unsigned long flags;
>> @@ -114,9 +116,11 @@ void vgic_mmio_write_cenable(struct vcpu *vcpu,
>> unsigned long val)
>> {
>> uint32_t intid = VGIC_ADDR_TO_INTID(addr, 1);
>> - unsigned int i;
>>
>> - bitmap_for_each ( i, &val, len * 8 )
>> + if ( len < sizeof(val) )
>> + val &= (1UL << (len * 8)) - 1;
>> +
>> + for_each_set_bit ( i, val )
>> {
>> struct vgic_irq *irq;
>> unsigned long flags;
>> @@ -182,11 +186,13 @@ void vgic_mmio_write_spending(struct vcpu *vcpu,
>> unsigned long val)
>> {
>> uint32_t intid = VGIC_ADDR_TO_INTID(addr, 1);
>> - unsigned int i;
>> unsigned long flags;
>> irq_desc_t *desc;
>>
>> - bitmap_for_each ( i, &val, len * 8 )
>> + if ( len < sizeof(val) )
>> + val &= (1UL << (len * 8)) - 1;
>> +
>> + for_each_set_bit ( i, val )
>> {
>> struct vgic_irq *irq = vgic_get_irq(vcpu->domain, vcpu, intid + i);
>>
>> @@ -230,11 +236,13 @@ void vgic_mmio_write_cpending(struct vcpu *vcpu,
>> unsigned long val)
>> {
>> uint32_t intid = VGIC_ADDR_TO_INTID(addr, 1);
>> - unsigned int i;
>> unsigned long flags;
>> irq_desc_t *desc;
>>
>> - bitmap_for_each ( i, &val, len * 8 )
>> + if ( len < sizeof(val) )
>> + val &= (1UL << (len * 8)) - 1;
>> +
>> + for_each_set_bit ( i, val )
>> {
>> struct vgic_irq *irq = vgic_get_irq(vcpu->domain, vcpu, intid + i);
>>
>> @@ -326,9 +334,11 @@ void vgic_mmio_write_cactive(struct vcpu *vcpu,
>> unsigned long val)
>> {
>> uint32_t intid = VGIC_ADDR_TO_INTID(addr, 1);
>> - unsigned int i;
>>
>> - bitmap_for_each ( i, &val, len * 8 )
>> + if ( len < sizeof(val) )
>> + val &= (1UL << (len * 8)) - 1;
>> +
>> + for_each_set_bit ( i, val )
>> {
>> struct vgic_irq *irq = vgic_get_irq(vcpu->domain, vcpu, intid + i);
>>
>> @@ -356,9 +366,11 @@ void vgic_mmio_write_sactive(struct vcpu *vcpu,
>> unsigned long val)
>> {
>> uint32_t intid = VGIC_ADDR_TO_INTID(addr, 1);
>> - unsigned int i;
>>
>> - bitmap_for_each ( i, &val, len * 8 )
>> + if ( len < sizeof(val) )
>> + val &= (1UL << (len * 8)) - 1;
>> +
>> + for_each_set_bit ( i, val )
>> {
>> struct vgic_irq *irq = vgic_get_irq(vcpu->domain, vcpu, intid + i);
>>
>> --
>> 2.39.2
>>
> ~Michal
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 4/4] ARM/vgic: Use for_each_set_bit() in vgic-mmio*
2024-09-03 13:19 ` Andrew Cooper
@ 2024-09-09 21:54 ` Julien Grall
0 siblings, 0 replies; 12+ messages in thread
From: Julien Grall @ 2024-09-09 21:54 UTC (permalink / raw)
To: Andrew Cooper, Michal Orzel, Xen-devel
Cc: Stefano Stabellini, Volodymyr Babchuk, Bertrand Marquis
Hi,
On 03/09/2024 14:19, Andrew Cooper wrote:
> On 03/09/2024 11:30 am, Michal Orzel wrote:
>>
>> On 02/09/2024 12:03, Andrew Cooper wrote:
>>>
>>> These are all loops over a scalar value, and don't need to call general bitop
>>> helpers behind the scenes.
>>>
>>> No functional change.
>>>
>>> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
>>> ---
>>> CC: Stefano Stabellini <sstabellini@kernel.org>
>>> CC: Julien Grall <julien@xen.org>
>>> CC: Volodymyr Babchuk <Volodymyr_Babchuk@epam.com>
>>> CC: Bertrand Marquis <bertrand.marquis@arm.com>
>>> CC: Michal Orzel <michal.orzel@amd.com>
>>>
>>> Slighly RFC. It's unclear whether len is the size of the register, or the
>>> size of the access. For sub-GPR accesses, won't the upper bits be clear
>>> anyway? If so, this can be simplified further.
>> See dispatch_mmio_write(). "len" refers to access size (i.e. 1/4/8 bytes). Each register is defined
>> with a region access i.e. VGIC_ACCESS_32bit that is compared with the actual access. In the current code
>> there is no register with 8B access. If there is a mismatch, there will be a data abort injected.
>> Also, the top 32-bits are not cleared anywhere, so I don't think we can drop masking. @Julien?
That's correct, there are no masking in the I/O dispatch helpers.
>
> Ok, so it is necessary right now to have the clamping logic in every
> callback.
>
> However, given that the size is validated before dispatching, clamping
> once in dispatch_mmio_write() would save a lot of repeated code in the
> callbacks.
>
> i.e., I think this:
>
> diff --git a/xen/arch/arm/vgic/vgic-mmio.c b/xen/arch/arm/vgic/vgic-mmio.c
> index bd4caf7fc326..e8b9805a0b2c 100644
> --- a/xen/arch/arm/vgic/vgic-mmio.c
> +++ b/xen/arch/arm/vgic/vgic-mmio.c
> @@ -590,6 +590,9 @@ static int dispatch_mmio_write(struct vcpu *vcpu,
> mmio_info_t *info,
> if ( !region )
> return 0;
>
> + if ( len < sizeof(data) )
> + data &= ~((1UL << (len * 8)) - 1);
> +
I think it would make sense to move the masking one level higher in
handle_write() (arch/arm/io.c). So this would cover all the emulation
helpers.
Cheers,
--
Julien Grall
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2024-09-09 21:54 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-09-02 10:03 [PATCH 0/4] ARM: Cleanup following bitops improvements Andrew Cooper
2024-09-02 10:03 ` [PATCH 1/4] ARM/div: Drop __div64_fls() Andrew Cooper
2024-09-03 8:37 ` Michal Orzel
2024-09-02 10:03 ` [PATCH 2/4] ARM/vgic: Correct the expression for lr_all_full() Andrew Cooper
2024-09-03 8:42 ` Michal Orzel
2024-09-02 10:03 ` [PATCH 3/4] ARM/vgic: Use for_each_set_bit() in gic_find_unused_lr() Andrew Cooper
2024-09-03 8:46 ` Michal Orzel
2024-09-03 13:07 ` Andrew Cooper
2024-09-02 10:03 ` [PATCH 4/4] ARM/vgic: Use for_each_set_bit() in vgic-mmio* Andrew Cooper
2024-09-03 10:30 ` Michal Orzel
2024-09-03 13:19 ` Andrew Cooper
2024-09-09 21:54 ` Julien Grall
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.