arch/x86/kernel/apic/x2apic_savic.c
Source file repositories/reference/linux-study-clean/arch/x86/kernel/apic/x2apic_savic.c
File Facts
- System
- Linux kernel
- Corpus path
arch/x86/kernel/apic/x2apic_savic.c- Extension
.c- Size
- 10590 bytes
- Lines
- 429
- Domain
- Architecture Layer
- Bucket
- arch/x86
- Inferred role
- Architecture Layer: implementation source
- Status
- source implementation candidate
Why This File Exists
CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/cc_platform.hlinux/cpumask.hlinux/percpu-defs.hlinux/align.hasm/apic.hasm/sev.hlocal.h
Detected Declarations
struct secure_avic_pagefunction savic_acpi_madt_oem_checkfunction update_vectorfunction readfunction self_ipi_reg_writefunction send_ipi_destfunction send_ipi_allbutfunction for_each_cpufunction self_ipifunction savic_icr_writefunction savic_writefunction send_ipifunction savic_send_ipifunction send_ipi_maskfunction for_each_cpufunction savic_send_ipi_maskfunction savic_send_ipi_mask_allbutselffunction savic_send_ipi_allbutselffunction savic_send_ipi_allfunction savic_send_ipi_selffunction savic_update_vectorfunction savic_eoifunction savic_teardownfunction savic_setupfunction savic_probe
Annotated Snippet
struct secure_avic_page {
u8 regs[PAGE_SIZE];
} __aligned(PAGE_SIZE);
static struct secure_avic_page __percpu *savic_page __ro_after_init;
static int savic_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
{
return x2apic_enabled() && cc_platform_has(CC_ATTR_SNP_SECURE_AVIC);
}
static inline void *get_reg_bitmap(unsigned int cpu, unsigned int offset)
{
return &per_cpu_ptr(savic_page, cpu)->regs[offset];
}
static inline void update_vector(unsigned int cpu, unsigned int offset,
unsigned int vector, bool set)
{
void *bitmap = get_reg_bitmap(cpu, offset);
if (set)
apic_set_vector(vector, bitmap);
else
apic_clear_vector(vector, bitmap);
}
#define SAVIC_ALLOWED_IRR 0x204
/*
* When Secure AVIC is enabled, RDMSR/WRMSR of the APIC registers
* result in #VC exception (for non-accelerated register accesses)
* with VMEXIT_AVIC_NOACCEL error code. The #VC exception handler
* can read/write the x2APIC register in the guest APIC backing page.
*
* Since doing this would increase the latency of accessing x2APIC
* registers, instead of doing RDMSR/WRMSR based accesses and
* handling the APIC register reads/writes in the #VC exception handler,
* the read() and write() callbacks directly read/write the APIC register
* from/to the vCPU's APIC backing page.
*/
static u32 savic_read(u32 reg)
{
void *ap = this_cpu_ptr(savic_page);
switch (reg) {
case APIC_LVTT:
case APIC_TMICT:
case APIC_TMCCT:
case APIC_TDCR:
case APIC_LVTTHMR:
case APIC_LVTPC:
case APIC_LVT0:
case APIC_LVT1:
case APIC_LVTERR:
return savic_ghcb_msr_read(reg);
case APIC_ID:
case APIC_LVR:
case APIC_TASKPRI:
case APIC_ARBPRI:
case APIC_PROCPRI:
case APIC_LDR:
case APIC_SPIV:
case APIC_ESR:
case APIC_EFEAT:
case APIC_ECTRL:
case APIC_SEOI:
case APIC_IER:
case APIC_EILVTn(0) ... APIC_EILVTn(3):
return apic_get_reg(ap, reg);
case APIC_ICR:
return (u32)apic_get_reg64(ap, reg);
case APIC_ISR ... APIC_ISR + 0x70:
case APIC_TMR ... APIC_TMR + 0x70:
if (WARN_ONCE(!IS_ALIGNED(reg, 16),
"APIC register read offset 0x%x not aligned at 16 bytes", reg))
return 0;
return apic_get_reg(ap, reg);
/* IRR and ALLOWED_IRR offset range */
case APIC_IRR ... APIC_IRR + 0x74:
/*
* Valid APIC_IRR/SAVIC_ALLOWED_IRR registers are at 16 bytes strides from
* their respective base offset. APIC_IRRs are in the range
*
* (0x200, 0x210, ..., 0x270)
*
* while the SAVIC_ALLOWED_IRR range starts 4 bytes later, in the range
*
* (0x204, 0x214, ..., 0x274).
*
Annotation
- Immediate include surface: `linux/cc_platform.h`, `linux/cpumask.h`, `linux/percpu-defs.h`, `linux/align.h`, `asm/apic.h`, `asm/sev.h`, `local.h`.
- Detected declarations: `struct secure_avic_page`, `function savic_acpi_madt_oem_check`, `function update_vector`, `function read`, `function self_ipi_reg_write`, `function send_ipi_dest`, `function send_ipi_allbut`, `function for_each_cpu`, `function self_ipi`, `function savic_icr_write`.
- Atlas domain: Architecture Layer / arch/x86.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.