|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v3 1/4] iommu/amd: support all delivery modes with x2APIC
On 15.10.2019 17:47, Roger Pau Monne wrote:
> Current AMD IOMMU code will attempt to create remapping entries for
> all IO-APIC pins, regardless of the delivery mode. AMD IOMMU
> implementation doesn't support remapping entries for IO-APIC pins with
> delivery mode set to SMI, MNI, INIT or ExtINT, instead those entries
Nit: "NMI"
> are not translated provided the right bits are set in the device table
> entry.
>
> This change checks whether the device table entry has the correct bits
> set in order to delivery the requested interrupt or a warning message
> is printed. It also translates the 32bit destination field into a
> physical or logical IO-APIC entry format. Note that if the 32bit
> destination cannot fit into the legacy format a message is printed and
> the entry is masked.
>
> Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
For this to have an effect on firmware initialized RTEs, it also
requires patch 4 aiui. In fact I think it should be _only_ this
case where we allow delivery modes other than fixed and lowest
priority ("arbitrated" in AMD terminology). Hence I think this
patch wants to go last in the series, and the code be changed to
reject runtime requests to fiddle with non-"normal" delivery
modes (this may go further and actually disallow changing such
RTEs at runtime alongside disallowing their production).
> --- a/xen/drivers/passthrough/amd/iommu_intr.c
> +++ b/xen/drivers/passthrough/amd/iommu_intr.c
> @@ -439,6 +439,80 @@ int __init amd_iommu_setup_ioapic_remapping(void)
> return 0;
> }
>
> +void setup_forced_ioapic_rte(unsigned int apic, unsigned int pin,
> + struct amd_iommu *iommu,
> + struct IO_APIC_route_entry *rte)
> +{
> + unsigned int idx = ioapic_id_to_index(IO_APIC_ID(apic));
> + struct amd_iommu_dte *table = iommu->dev_table.buffer;
> + unsigned int req_id, dest, offset;
> + union irte_ptr entry;
> +
> + ASSERT(x2apic_enabled);
> +
> + if ( idx == MAX_IO_APICS )
Better >= ?
> + {
> + rte->mask = true;
> + return;
> + }
> +
> + req_id = get_intremap_requestor_id(ioapic_sbdf[idx].seg,
> + ioapic_sbdf[idx].bdf);
> +
> + switch ( rte->delivery_mode )
> + {
> + case dest_SMI:
> + break;
Don't you want to check the sys_mgt field here, along the lines of the
other ones below?
> +#define DEL_CHECK(type, dte_field) \
> + case dest_ ## type: \
> + if ( !table[req_id].dte_field ) \
> + printk(XENLOG_WARNING \
> + STR(type) " on IO-APIC %u pin %u will be aborted\n", \
> + apic, pin); \
> + break;
Please omit the final ; here, such that ...
> + DEL_CHECK(NMI, nmi_pass);
> + DEL_CHECK(INIT, init_pass);
> + DEL_CHECK(ExtINT, ext_int_pass);
... the ones here become an actual requirement.
> +#undef DEL_CHECK
> +
> + default:
> + ASSERT_UNREACHABLE();
> + return;
> + }
> +
> + offset = ioapic_sbdf[idx].pin_2_idx[pin];
> + if ( offset >= INTREMAP_MAX_ENTRIES )
> + {
> + rte->mask = true;
> + return;
> + }
> +
> + entry = get_intremap_entry(iommu, req_id, offset);
> + dest = get_full_dest(entry.ptr128);
> +
> +#define SET_DEST(name, dest_mask) {
> \
> + if ( dest & ~(dest_mask) )
> \
> + {
> \
> + printk(XENLOG_WARNING
> \
> + "IO-APIC %u pin %u " STR(name) " destination (%x) > %x\n",
> \
> + apic, pin, dest, dest_mask);
> \
> + rte->mask = true;
> \
> + return;
> \
> + }
> \
> + rte->dest.name.name ## _dest = dest;
> \
> +}
> +
> + if ( rte->dest_mode )
> + SET_DEST(physical, 0xf)
> + else
> + SET_DEST(logical, 0xff)
This reads as if the code was broken. Please add () around the outermost
{} of the macro, allowing you to put ; here. Or otherwise, just like
above for DEL_CHECK(), omit the {} as well as the final semicolon.
Furthermore - are you sure about this distinction? See e.g.
update_intremap_entry_from_ioapic() and
amd_iommu_setup_ioapic_remapping(), which unilaterally use
rte->dest.logical.logical_dest. Likewise io_apic.c's SET_DEST() users,
which generally pass "logical" for as middle argument. I thought one of
my half way recent patches (IRQ handling or AMD IOMMU work) had a remark
in it regarding such a badly documented extension, but I can't seem to
be able to find it anymore.
> @@ -482,6 +556,13 @@ void amd_iommu_ioapic_update_ire(
> *((u32 *)&new_rte) = value;
> /* read upper 32 bits from io-apic rte */
> *(((u32 *)&new_rte) + 1) = __io_apic_read(apic, reg + 1);
> +
> + if ( new_rte.delivery_mode > 1 && x2apic_enabled )
The literal 1 here wants attaching of a comment. And why the
x2apic_enabled part of the condition?
Jan
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |