|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH] xen/riscv: bound each IMSIC MMIO regset by the per-group hart slots
imsic_init() requires every MMIO register set to be exactly
IMSIC_HART_SIZE(guest_index_bits) * nr_parent_irqs bytes, i.e. to cover
the interrupt files of all harts listed in interrupts-extended. This only
holds when the DT describes a single register set.
When harts are split into groups (riscv,group-index-bits > 0), each group
has its own register set, which only covers the harts of that group. For
example, the SpacemiT V100 IMSIC node describes two 2 MiB register sets,
each holding 64 hart slots of 32 KiB, with 128 parent interrupts in total.
Xen expects 4 MiB per register set and fails with:
IMSIC MMIO size is incorrect 2097152, expected MMIO size: 4194304
A register set can also be smaller than its slot space, when the number
of harts in a group is not a power of two.
Check instead that a register set does not exceed the address space of
one group of BIT(hart_index_bits) hart slots.
While at it, print the MMIO sizes in hex, so they can be compared directly
with the reg property of the DT node.
Fixes: c9bd8b322ecb ("xen/riscv: imsic_init() implementation")
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Baptiste Le Duc <baptiste.le-duc@xxxxxxxxxx>
---
xen/arch/riscv/imsic.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/xen/arch/riscv/imsic.c b/xen/arch/riscv/imsic.c
index 44b8640ea3..255ac44b52 100644
--- a/xen/arch/riscv/imsic.c
+++ b/xen/arch/riscv/imsic.c
@@ -416,8 +416,8 @@ int __init imsic_init(const struct dt_device_node *node)
for ( unsigned int i = 0; i < nr_mmios; i++ )
{
unsigned int guest_bits = imsic_cfg.guest_index_bits;
- unsigned long expected_mmio_size =
- IMSIC_HART_SIZE(guest_bits) * nr_parent_irqs;
+ unsigned long max_mmio_regset_size =
+ IMSIC_HART_SIZE(guest_bits) * BIT(imsic_cfg.hart_index_bits, U);
rc = dt_device_get_address(node, i, &mmios[i].base_addr,
&mmios[i].size);
@@ -442,11 +442,11 @@ int __init imsic_init(const struct dt_device_node *node)
goto imsic_init_err;
}
- if ( mmios[i].size != expected_mmio_size )
+ if ( mmios[i].size > max_mmio_regset_size )
{
rc = -EINVAL;
- printk(XENLOG_ERR "%s: IMSIC MMIO size is incorrect %ld, expected
MMIO size: %ld\n",
- node->name, mmios[i].size, expected_mmio_size);
+ printk(XENLOG_ERR "%s: IMSIC MMIO regset %u size %#lx larger than
max %#lx\n",
+ node->name, i, mmios[i].size, max_mmio_regset_size);
goto imsic_init_err;
}
}
---
base-commit: 97bf370375113caf92fccf04e2877fc6b5ff887f
change-id: 20261113-fix-imsic-mmio-dt-c3317ac2efec
Best regards,
--
Baptiste Le Duc <baptiste.le-duc@xxxxxxxxxx>
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |