972
edits
[unchecked revision] | [unchecked revision] |
(Added table of LAPIC registers. Table taken from the x86 sdm (Volume 3A, Chapter 10.4)) |
m (Bot: Replace deprecated source tag with syntaxhighlight) |
||
(27 intermediate revisions by 9 users not shown) | |||
Line 3:
== Detection ==
The [[CPUID]].01h:EDX[bit 9] flag specifies whether a CPU has a built-in local APIC. You can find all of the APICs on a system (both local and IO APICs) by parsing the [[MADT]].
== Local APIC and IO-APIC ==
Line 9:
In an APIC-based system, each CPU is made of a "core" and a "local APIC". The local APIC is responsible for handling cpu-specific interrupt configuration. Among other things, it contains the ''Local Vector Table (LVT)'' that translates events such as "internal clock" and other "local" interrupt sources into a interrupt vector (e.g. LocalINT1 pin could be raising an NMI exception by storing "2" in the corresponding entry of the LVT).
More information about the local APIC can be found in Chapter 10 of the
In addition, there is an I/O APIC (e.g. intel 82093AA) that is part of the chipset and provides multi-processor interrupt management, incorporating both static and dynamic symmetric interrupt distribution across all processors. In systems with multiple I/O subsystems, each subsystem can have its own set of interrupts.
Line 20:
Inter-Processor Interrupts (IPIs) are generated by a local APIC and can be used as basic signaling for scheduling coordination, multi-processor bootstrapping, etc.
Detailed information on issuing them are available in the Chapter 11.6 of Volume 3 of the Intel Software Developer's Manual, available at the bottom of the page.
== Local APIC configuration ==
Line 33 ⟶ 34:
Here are some code examples on setting up the APIC:
<
#define IA32_APIC_BASE_MSR 0x1B
#define IA32_APIC_BASE_MSR_BSP 0x100 // Processor is a BSP
Line 51 ⟶ 52:
void cpu_set_apic_base(uintptr_t apic) {
uint32_t edx = 0;
uint32_t eax = (apic &
#ifdef __PHYSICAL_MEMORY_EXTENSION__
Line 76 ⟶ 77:
void enable_apic() {
/* Section 11.4.1 of 3rd volume of Intel SDM recommends mapping the base address page as strong uncacheable for correct APIC operation. */
/* Hardware enable the Local APIC if it wasn't enabled */
cpu_set_apic_base(cpu_get_apic_base());
Line 82 ⟶ 85:
write_reg(0xF0, ReadRegister(0xF0) | 0x100);
}
</syntaxhighlight>
== Local APIC and x86 SMM Attacks ==
Line 89 ⟶ 92:
As System Management Mode's memory (SMRAM) is given a protected range of memory (which can vary from system to system), it is possible to map the APIC memory location into the SMRAM. The result of this is that SMM memory is pushed outside its protected range and exposed to lesser-privileged permission rings. Using this method, attackers can leverage their permissions using System Management Mode, which is protected from all rings above -2.
In newer generation Intel processors (starting with the [https://en.wikipedia.org/wiki/Intel_Atom Intel Atom] in 2013), this has been taken into account. An undocumented check is performed against the [[System Management Range Registers]] when the APIC is relocated to memory. This check ensures that the APIC does not overlap with the SMRAM. '''However''', this relies on the SMRR to be configured correctly. Otherwise, this mitigation will not work properly and attackers will still be able to
== Local APIC registers ==
Line 254 ⟶ 257:
=== EOI Register ===
Write to the register with offset 0xB0 using the value 0 to signal an end of interrupt. A non-zero value
=== Local Vector Table Registers ===
Line 265 ⟶ 268:
| The vector number
|-
| Bits 8-
| 100b if NMI
|-
| Bit 11
| Reserved
|-
| Bit 12
Line 299 ⟶ 305:
|-
| Bits 8-10
| The
|-
| Bit 11
Line 328 ⟶ 334:
IOAPICBASE+0x10. All accesses must be done on 4 byte boundaries. The address register uses the bottom 8 bits for register select. Here is some example code that illustrates this:
<
uint32_t cpuReadIoApic(void *ioapicaddr, uint32_t reg)
{
Line 342 ⟶ 348:
ioapic[4] = value;
}
</syntaxhighlight>
Note the use of the [[volatile (keyword)|volatile]] keyword. This prevents a compiler like [[Visual C]] from reordering or optimizing away the memory accesses, which would be a Bad Thing™. The volatile keyword is put before the '*' sign. It means that the ''value pointed to'' is volatile, not the pointer itself.
Line 395 ⟶ 401:
| Destination field. If the destination mode bit was clear, then the lower 4 bits contain the bit APIC ID to sent the interrupt to. If the bit was set, the upper 4 bits also contain a set of processors. (See below)
|}
For more information, check out chapter 3 of [http://web.archive.org/web/20161130153145/http://download.intel.com/design/chipsets/datashts/29056601.pdf the I/O APIC datasheet].
The redirection table allows you to choose which external interrupts are sent to which processors and with which interrupt vectors. When choosing the processors you should consider: spreading out the workload between the processors, avoiding processors in a low-power state, and avoiding throttled processors. When choosing the interrupt vectors you should remember that interrupts 0x00 to 0x1F are reserved for internal processor exceptions, the interrupts you remapped the PIC to may receive spurious interrupts, that 0xFF is probably where you put the APIC spurious interrupt, and that the upper 4 bits of an interrupt vector indicate its priority.
Line 410 ⟶ 416:
| rowspan="3" | Bits 24-31
| Flat model
| Bitmap of target processors (each bit identifies single processor; supports a maximum of 8 local APIC units)
|-
| rowspan="2" | Cluster model
Line 430 ⟶ 436:
|}
The cluster addressing scheme has some limitations on the Pentium era systems. It may require special hardware to route the APIC bus messages between different CPU clusters or that it is sometimes limited to 15 agents (CPUs) in total. More info can be found in [https://books.google.com/books?id=TVzjEZg1--YC&printsec=frontcover "Pentium Processor System Architecture. Chapter 15: The APIC"]
Operating systems running on 64-bit processors typically use "Flat model" when the system has up to 8 CPUs. If more than 8 CPUs is used some OSes use cluster model which allow to address in total 60 CPUs (cluster 0xf is a broadcast and there is 15 clusters with 4 CPUs in each).
The logical delivery mode is handy to address multiple CPUs when doing IPIs or it might be used in conjunction with lowest priority delivery mode to deliver IRQs from MSI/IO-APICs to a certain CPU in the group specified in the destination field.
== See Also ==
Line 470 ⟶ 449:
===Threads===
* [
* [
* [
===External Links===
* [https://web.archive.org/web/20161128201003/http://www.intel.com/design/chipsets/datashts/290566.htm
* [https://web.archive.org/web/20170430050751/http://
* [
* [
* [
* [
* [https://books.google.
[[Category:Interrupts]]
[[Category:Multiprocessing]]
[[de:Advanced Programmable Interrupt Controller]]
|