[x64][interrupts] Fix locking inversion in InterruptManager

During interrupt handler registration the InterruptManager
acquires its spinlock before calling InterruptTableEntry::SetHandler,
which acquires the table entry's spinlock.

InterruptManager::RegisterInterruptHandler (acquires IM::lock_)
  InterruptTableEntry::SetHandler (acquires ITE::lock_)

However, if an interrupt is configured as non-permanent with the option
INTERRUPT_MASK_POSTWAIT then during the handler dispatch path the
InterruptTableEntry lock will be acquired before the
InterruptEventDispatcher's IrqHandler calls into
InterruptManager::MaskInterrupt, which acquires the InterruptManager
lock.

platform_irq
  InterruptManager::InvokeX86Vector
    InterruptTableEntry::InvokeIfPresent (acquires ITE::lock_)
      InterruptEventDispatcher::IrqHandler
        InterruptManager::MaskInterrupt (acquires IM::lock_)

Fortunately, this is an easy fix because the locking in MaskInterrupt
and UnmaskInterrupt is unnecessary. The call stack looks like:

InterruptDispatcher::IrqHandler
  InterruptManager::MaskInterrupt (acquires lock_)
    IoApic::MaskIrq
      apic_io_mask_irq (acquires apic singleton lock)

InterruptManager will not go out of scope and those methods do nothing
but call into the IoApic with a vector number, so no state needs to be
protected in the InterruptManager or InterruptTableEntry. IoApic
maintains its own locking via a singleton lock acquired by
apic_io_mask_irq.

Change-Id: Ib8b1be10adf7a87f8a360db5269b763b9324ee54
Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/550048
Commit-Queue: Christopher Anderson <cja@google.com>
Reviewed-by: Nick Maniscalco <maniscalco@google.com>
Reviewed-by: Adrian Danis <adanis@google.com>
1 file changed
tree: 6a75394fb3f292da9213edf30481938cee1973e1
  1. boards/
  2. build/
  3. buildtools/
  4. bundles/
  5. docs/
  6. examples/
  7. garnet/
  8. products/
  9. scripts/
  10. sdk/
  11. src/
  12. third_party/
  13. tools/
  14. zircon/
  15. .clang-format
  16. .clang-tidy
  17. .git-blame-ignore-revs
  18. .gitattributes
  19. .gitignore
  20. .gn
  21. .style.yapf
  22. AUTHORS
  23. BUILD.gn
  24. CODE_OF_CONDUCT.md
  25. CONTRIBUTING.md
  26. LICENSE
  27. OWNERS
  28. PATENTS
  29. README.md
  30. rustfmt.toml
README.md

Fuchsia

Pink + Purple == Fuchsia (a new operating system)

What is Fuchsia?

Fuchsia is a modular, capability-based operating system. Fuchsia runs on modern 64-bit Intel and ARM processors.

Fuchsia is an open source project with a code of conduct that we expect everyone who interacts with the project to respect.

Read more about Fuchsia's principles.

How can I build and run Fuchsia?

See Getting Started.

Where can I learn more about Fuchsia?

See fuchsia.dev.