Page MenuHomeFreeBSD

io_apic: Don't route to APIC ID > 255
Needs ReviewPublic

Authored by cperciva on Sat, Mar 14, 6:31 PM.
Tags
None
Referenced Files
F148753069: D55857.id173699.diff
Fri, Mar 20, 1:12 AM
Unknown Object (File)
Thu, Mar 19, 5:26 PM
Unknown Object (File)
Thu, Mar 19, 4:00 AM
Unknown Object (File)
Tue, Mar 17, 6:17 AM
Unknown Object (File)
Sat, Mar 14, 11:31 PM
Subscribers

Details

Reviewers
kib
jhb
emaste
Summary

I/O APIC Redirection Table Entries use 8 bits encode the Destination ID.
Attempting to route an IRQ to a higher APIC ID would result in it being
silently routed to the value reduced modulo 256, causing a panic if the
IRQ fired since the receiving CPU would not expect that IRQ.

Instead, print an error message and mask the interrupt. Note that we
also check io_cpu in ioapic_enable_source and force the mask bit back
on despite the request to remove it.

Tested on: EC2 r8i.96xlarge
MFC after: 1 month
Sponsored by: Amazon

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped
Build Status
Buildable 71405
Build 68288: arc lint + arc unit

Event Timeline

Add comment about keeping interrupt masked even when "enabling" it.

Did you tried enabling DMAR/AMD IOMMU and interrupt remapping on this machine?

In D55857#1278564, @kib wrote:

Did you tried enabling DMAR/AMD IOMMU and interrupt remapping on this machine?

This (virtual) machine doesn't have a proper IOMMU. See http://david.woodhou.se/15-bit-msi.pdf for context.

In D55857#1278564, @kib wrote:

Did you tried enabling DMAR/AMD IOMMU and interrupt remapping on this machine?

This (virtual) machine doesn't have a proper IOMMU. See http://david.woodhou.se/15-bit-msi.pdf for context.

sys/x86/x86/io_apic.c
272

I think kib's point here is that this will break machines that work with an IOMMU today. They will have io_cpu > IOAPIC_MAX_ID, but will have a valid low. Your test here is insufficient.

I think instead we need to add a new bool (or just another 1-bit field after io_masked) which is something like io_valid. It should be cleared to 0 in both your new case below, and in the IOMMU case in ioapic_program_intpin when remapping fails with an error other than EOPNOTSUPP. I would probably add an invalid: label at the bottom of ioapic_program_intpin` that clears this field and just sets the mask bit similar to what happens now for the IRQ_DISABLED case. Then enable_source can instead do this:

if (intpin->io_masked && intpio->io_valid)

I would also check the valid flag in ioapic_disable_source as well probably.

sys/x86/x86/io_apic.c
272

Oh, whoops. I forgot that the >255 check was only relevant when when we hit the IOMMU EOPNOTSUPP case. Yeah, sounds like we need a new io_valid flag, I'll get to work on that.