···483483484484 If in doubt, say Y.485485486486+config AMD_SECURE_AVIC487487+ bool "AMD Secure AVIC"488488+ depends on AMD_MEM_ENCRYPT && X86_X2APIC489489+ help490490+ Enable this to get AMD Secure AVIC support on guests that have this feature.491491+492492+ AMD Secure AVIC provides hardware acceleration for performance sensitive493493+ APIC accesses and support for managing guest owned APIC state for SEV-SNP494494+ guests. Secure AVIC does not support xAPIC mode. It has functional495495+ dependency on x2apic being enabled in the guest.496496+497497+ If you don't know what to do here, say N.498498+486499config X86_POSTED_MSI487500 bool "Enable MSI and MSI-x delivery by posted interrupts"488501 depends on X86_64 && IRQ_REMAP
+9-1
arch/x86/boot/compressed/sev.c
···186186 MSR_AMD64_SNP_VMSA_REG_PROT | \187187 MSR_AMD64_SNP_RESERVED_BIT13 | \188188 MSR_AMD64_SNP_RESERVED_BIT15 | \189189+ MSR_AMD64_SNP_SECURE_AVIC | \189190 MSR_AMD64_SNP_RESERVED_MASK)191191+192192+#ifdef CONFIG_AMD_SECURE_AVIC193193+#define SNP_FEATURE_SECURE_AVIC MSR_AMD64_SNP_SECURE_AVIC194194+#else195195+#define SNP_FEATURE_SECURE_AVIC 0196196+#endif190197191198/*192199 * SNP_FEATURES_PRESENT is the mask of SNP features that are implemented···201194 * guest kernel, a corresponding bit should be added to the mask.202195 */203196#define SNP_FEATURES_PRESENT (MSR_AMD64_SNP_DEBUG_SWAP | \204204- MSR_AMD64_SNP_SECURE_TSC)197197+ MSR_AMD64_SNP_SECURE_TSC | \198198+ SNP_FEATURE_SECURE_AVIC)205199206200u64 snp_get_unsupported_features(u64 status)207201{
+3
arch/x86/coco/core.c
···104104 case CC_ATTR_HOST_SEV_SNP:105105 return cc_flags.host_sev_snp;106106107107+ case CC_ATTR_SNP_SECURE_AVIC:108108+ return sev_status & MSR_AMD64_SNP_SECURE_AVIC;109109+107110 default:108111 return false;109112 }
···208208#define GHCB_TERM_SVSM_CAA 9 /* SVSM is present but CAA is not page aligned */209209#define GHCB_TERM_SECURE_TSC 10 /* Secure TSC initialization failed */210210#define GHCB_TERM_SVSM_CA_REMAP_FAIL 11 /* SVSM is present but CA could not be remapped */211211+#define GHCB_TERM_SAVIC_FAIL 12 /* Secure AVIC-specific failure */211212212213#define GHCB_RESP_CODE(v) ((v) & GHCB_MSR_INFO_MASK)213214
···1818# APIC probe will depend on the listing order here1919obj-$(CONFIG_X86_NUMACHIP) += apic_numachip.o2020obj-$(CONFIG_X86_UV) += x2apic_uv_x.o2121+obj-$(CONFIG_AMD_SECURE_AVIC) += x2apic_savic.o2122obj-$(CONFIG_X86_X2APIC) += x2apic_phys.o2223obj-$(CONFIG_X86_X2APIC) += x2apic_cluster.o2324obj-y += apic_flat_64.o
+46-41
arch/x86/kernel/apic/apic.c
···592592 0xF, ~0UL);593593 } else594594 clockevents_register_device(levt);595595+596596+ apic_update_vector(smp_processor_id(), LOCAL_TIMER_VECTOR, true);595597}596598597599/*···11701168 if (!apic_accessible())11711169 return;1172117011711171+ if (apic->teardown)11721172+ apic->teardown();11731173+11731174 apic_soft_disable();1174117511751176#ifdef CONFIG_X86_32···14331428 u32 regs[APIC_IR_REGS];14341429};1435143014361436-static bool apic_check_and_ack(union apic_ir *irr, union apic_ir *isr)14311431+static bool apic_check_and_eoi_isr(union apic_ir *isr)14371432{14381433 int i, bit;14391439-14401440- /* Read the IRRs */14411441- for (i = 0; i < APIC_IR_REGS; i++)14421442- irr->regs[i] = apic_read(APIC_IRR + i * 0x10);1443143414441435 /* Read the ISRs */14451436 for (i = 0; i < APIC_IR_REGS; i++)14461437 isr->regs[i] = apic_read(APIC_ISR + i * 0x10);1447143814481448- /*14491449- * If the ISR map is not empty. ACK the APIC and run another round14501450- * to verify whether a pending IRR has been unblocked and turned14511451- * into a ISR.14521452- */14531453- if (!bitmap_empty(isr->map, APIC_IR_BITS)) {14541454- /*14551455- * There can be multiple ISR bits set when a high priority14561456- * interrupt preempted a lower priority one. Issue an ACK14571457- * per set bit.14581458- */14591459- for_each_set_bit(bit, isr->map, APIC_IR_BITS)14601460- apic_eoi();14391439+ /* If the ISR map empty, nothing to do here. */14401440+ if (bitmap_empty(isr->map, APIC_IR_BITS))14611441 return true;14621462- }1463144214641464- return !bitmap_empty(irr->map, APIC_IR_BITS);14431443+ /*14441444+ * There can be multiple ISR bits set when a high priority14451445+ * interrupt preempted a lower priority one. Issue an EOI for each14461446+ * set bit. The priority traversal order does not matter as there14471447+ * can't be new ISR bits raised at this point. What matters is that14481448+ * an EOI is issued for each ISR bit.14491449+ */14501450+ for_each_set_bit(bit, isr->map, APIC_IR_BITS)14511451+ apic_eoi();14521452+14531453+ /* Reread the ISRs, they should be empty now */14541454+ for (i = 0; i < APIC_IR_REGS; i++)14551455+ isr->regs[i] = apic_read(APIC_ISR + i * 0x10);14561456+14571457+ return bitmap_empty(isr->map, APIC_IR_BITS);14651458}1466145914671460/*14681468- * After a crash, we no longer service the interrupts and a pending14691469- * interrupt from previous kernel might still have ISR bit set.14611461+ * If a CPU services an interrupt and crashes before issuing EOI to the14621462+ * local APIC, the corresponding ISR bit is still set when the crashing CPU14631463+ * jumps into a crash kernel. Read the ISR and issue an EOI for each set14641464+ * bit to acknowledge it as otherwise these slots would be locked forever14651465+ * waiting for an EOI.14701466 *14711471- * Most probably by now the CPU has serviced that pending interrupt and it14721472- * might not have done the apic_eoi() because it thought, interrupt14731473- * came from i8259 as ExtInt. LAPIC did not get EOI so it does not clear14741474- * the ISR bit and cpu thinks it has already serviced the interrupt. Hence14751475- * a vector might get locked. It was noticed for timer irq (vector14761476- * 0x31). Issue an extra EOI to clear ISR.14671467+ * If there are pending bits in the IRR, then they won't be converted into14681468+ * ISR bits as the CPU has interrupts disabled. They will be delivered once14691469+ * the CPU enables interrupts and there is nothing which can prevent that.14771470 *14781478- * If there are pending IRR bits they turn into ISR bits after a higher14791479- * priority ISR bit has been acked.14711471+ * In the worst case this results in spurious interrupt warnings.14801472 */14811481-static void apic_pending_intr_clear(void)14731473+static void apic_clear_isr(void)14821474{14831483- union apic_ir irr, isr;14751475+ union apic_ir ir;14841476 unsigned int i;1485147714861486- /* 512 loops are way oversized and give the APIC a chance to obey. */14871487- for (i = 0; i < 512; i++) {14881488- if (!apic_check_and_ack(&irr, &isr))14891489- return;14901490- }14911491- /* Dump the IRR/ISR content if that failed */14921492- pr_warn("APIC: Stale IRR: %256pb ISR: %256pb\n", irr.map, isr.map);14781478+ if (!apic_check_and_eoi_isr(&ir))14791479+ pr_warn("APIC: Stale ISR: %256pb\n", ir.map);14801480+14811481+ for (i = 0; i < APIC_IR_REGS; i++)14821482+ ir.regs[i] = apic_read(APIC_IRR + i * 0x10);14831483+14841484+ if (!bitmap_empty(ir.map, APIC_IR_BITS))14851485+ pr_warn("APIC: Stale IRR: %256pb\n", ir.map);14931486}1494148714951488/**···15051502 disable_ioapic_support();15061503 return;15071504 }15051505+15061506+ if (apic->setup)15071507+ apic->setup();1508150815091509 /*15101510 * If this comes from kexec/kcrash the APIC might be enabled in···15471541 value |= 0x10;15481542 apic_write(APIC_TASKPRI, value);1549154315501550- /* Clear eventually stale ISR/IRR bits */15511551- apic_pending_intr_clear();15441544+ apic_clear_isr();1552154515531546 /*15541547 * Now that we are all set up, enable the APIC
···11+// SPDX-License-Identifier: GPL-2.0-only22+/*33+ * AMD Secure AVIC Support (SEV-SNP Guests)44+ *55+ * Copyright (C) 2024 Advanced Micro Devices, Inc.66+ *77+ * Author: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>88+ */99+1010+#include <linux/cc_platform.h>1111+#include <linux/cpumask.h>1212+#include <linux/percpu-defs.h>1313+#include <linux/align.h>1414+1515+#include <asm/apic.h>1616+#include <asm/sev.h>1717+1818+#include "local.h"1919+2020+struct secure_avic_page {2121+ u8 regs[PAGE_SIZE];2222+} __aligned(PAGE_SIZE);2323+2424+static struct secure_avic_page __percpu *savic_page __ro_after_init;2525+2626+static int savic_acpi_madt_oem_check(char *oem_id, char *oem_table_id)2727+{2828+ return x2apic_enabled() && cc_platform_has(CC_ATTR_SNP_SECURE_AVIC);2929+}3030+3131+static inline void *get_reg_bitmap(unsigned int cpu, unsigned int offset)3232+{3333+ return &per_cpu_ptr(savic_page, cpu)->regs[offset];3434+}3535+3636+static inline void update_vector(unsigned int cpu, unsigned int offset,3737+ unsigned int vector, bool set)3838+{3939+ void *bitmap = get_reg_bitmap(cpu, offset);4040+4141+ if (set)4242+ apic_set_vector(vector, bitmap);4343+ else4444+ apic_clear_vector(vector, bitmap);4545+}4646+4747+#define SAVIC_ALLOWED_IRR 0x2044848+4949+/*5050+ * When Secure AVIC is enabled, RDMSR/WRMSR of the APIC registers5151+ * result in #VC exception (for non-accelerated register accesses)5252+ * with VMEXIT_AVIC_NOACCEL error code. The #VC exception handler5353+ * can read/write the x2APIC register in the guest APIC backing page.5454+ *5555+ * Since doing this would increase the latency of accessing x2APIC5656+ * registers, instead of doing RDMSR/WRMSR based accesses and5757+ * handling the APIC register reads/writes in the #VC exception handler,5858+ * the read() and write() callbacks directly read/write the APIC register5959+ * from/to the vCPU's APIC backing page.6060+ */6161+static u32 savic_read(u32 reg)6262+{6363+ void *ap = this_cpu_ptr(savic_page);6464+6565+ switch (reg) {6666+ case APIC_LVTT:6767+ case APIC_TMICT:6868+ case APIC_TMCCT:6969+ case APIC_TDCR:7070+ case APIC_LVTTHMR:7171+ case APIC_LVTPC:7272+ case APIC_LVT0:7373+ case APIC_LVT1:7474+ case APIC_LVTERR:7575+ return savic_ghcb_msr_read(reg);7676+ case APIC_ID:7777+ case APIC_LVR:7878+ case APIC_TASKPRI:7979+ case APIC_ARBPRI:8080+ case APIC_PROCPRI:8181+ case APIC_LDR:8282+ case APIC_SPIV:8383+ case APIC_ESR:8484+ case APIC_EFEAT:8585+ case APIC_ECTRL:8686+ case APIC_SEOI:8787+ case APIC_IER:8888+ case APIC_EILVTn(0) ... APIC_EILVTn(3):8989+ return apic_get_reg(ap, reg);9090+ case APIC_ICR:9191+ return (u32)apic_get_reg64(ap, reg);9292+ case APIC_ISR ... APIC_ISR + 0x70:9393+ case APIC_TMR ... APIC_TMR + 0x70:9494+ if (WARN_ONCE(!IS_ALIGNED(reg, 16),9595+ "APIC register read offset 0x%x not aligned at 16 bytes", reg))9696+ return 0;9797+ return apic_get_reg(ap, reg);9898+ /* IRR and ALLOWED_IRR offset range */9999+ case APIC_IRR ... APIC_IRR + 0x74:100100+ /*101101+ * Valid APIC_IRR/SAVIC_ALLOWED_IRR registers are at 16 bytes strides from102102+ * their respective base offset. APIC_IRRs are in the range103103+ *104104+ * (0x200, 0x210, ..., 0x270)105105+ *106106+ * while the SAVIC_ALLOWED_IRR range starts 4 bytes later, in the range107107+ *108108+ * (0x204, 0x214, ..., 0x274).109109+ *110110+ * Filter out everything else.111111+ */112112+ if (WARN_ONCE(!(IS_ALIGNED(reg, 16) ||113113+ IS_ALIGNED(reg - 4, 16)),114114+ "Misaligned APIC_IRR/ALLOWED_IRR APIC register read offset 0x%x", reg))115115+ return 0;116116+ return apic_get_reg(ap, reg);117117+ default:118118+ pr_err("Error reading unknown Secure AVIC reg offset 0x%x\n", reg);119119+ return 0;120120+ }121121+}122122+123123+#define SAVIC_NMI_REQ 0x278124124+125125+/*126126+ * On WRMSR to APIC_SELF_IPI register by the guest, Secure AVIC hardware127127+ * updates the APIC_IRR in the APIC backing page of the vCPU. In addition,128128+ * hardware evaluates the new APIC_IRR update for interrupt injection to129129+ * the vCPU. So, self IPIs are hardware-accelerated.130130+ */131131+static inline void self_ipi_reg_write(unsigned int vector)132132+{133133+ native_apic_msr_write(APIC_SELF_IPI, vector);134134+}135135+136136+static void send_ipi_dest(unsigned int cpu, unsigned int vector, bool nmi)137137+{138138+ if (nmi)139139+ apic_set_reg(per_cpu_ptr(savic_page, cpu), SAVIC_NMI_REQ, 1);140140+ else141141+ update_vector(cpu, APIC_IRR, vector, true);142142+}143143+144144+static void send_ipi_allbut(unsigned int vector, bool nmi)145145+{146146+ unsigned int cpu, src_cpu;147147+148148+ guard(irqsave)();149149+150150+ src_cpu = raw_smp_processor_id();151151+152152+ for_each_cpu(cpu, cpu_online_mask) {153153+ if (cpu == src_cpu)154154+ continue;155155+ send_ipi_dest(cpu, vector, nmi);156156+ }157157+}158158+159159+static inline void self_ipi(unsigned int vector, bool nmi)160160+{161161+ u32 icr_low = APIC_SELF_IPI | vector;162162+163163+ if (nmi)164164+ icr_low |= APIC_DM_NMI;165165+166166+ native_x2apic_icr_write(icr_low, 0);167167+}168168+169169+static void savic_icr_write(u32 icr_low, u32 icr_high)170170+{171171+ unsigned int dsh, vector;172172+ u64 icr_data;173173+ bool nmi;174174+175175+ dsh = icr_low & APIC_DEST_ALLBUT;176176+ vector = icr_low & APIC_VECTOR_MASK;177177+ nmi = ((icr_low & APIC_DM_FIXED_MASK) == APIC_DM_NMI);178178+179179+ switch (dsh) {180180+ case APIC_DEST_SELF:181181+ self_ipi(vector, nmi);182182+ break;183183+ case APIC_DEST_ALLINC:184184+ self_ipi(vector, nmi);185185+ fallthrough;186186+ case APIC_DEST_ALLBUT:187187+ send_ipi_allbut(vector, nmi);188188+ break;189189+ default:190190+ send_ipi_dest(icr_high, vector, nmi);191191+ break;192192+ }193193+194194+ icr_data = ((u64)icr_high) << 32 | icr_low;195195+ if (dsh != APIC_DEST_SELF)196196+ savic_ghcb_msr_write(APIC_ICR, icr_data);197197+ apic_set_reg64(this_cpu_ptr(savic_page), APIC_ICR, icr_data);198198+}199199+200200+static void savic_write(u32 reg, u32 data)201201+{202202+ void *ap = this_cpu_ptr(savic_page);203203+204204+ switch (reg) {205205+ case APIC_LVTT:206206+ case APIC_TMICT:207207+ case APIC_TDCR:208208+ case APIC_LVT0:209209+ case APIC_LVT1:210210+ case APIC_LVTTHMR:211211+ case APIC_LVTPC:212212+ case APIC_LVTERR:213213+ savic_ghcb_msr_write(reg, data);214214+ break;215215+ case APIC_TASKPRI:216216+ case APIC_EOI:217217+ case APIC_SPIV:218218+ case SAVIC_NMI_REQ:219219+ case APIC_ESR:220220+ case APIC_ECTRL:221221+ case APIC_SEOI:222222+ case APIC_IER:223223+ case APIC_EILVTn(0) ... APIC_EILVTn(3):224224+ apic_set_reg(ap, reg, data);225225+ break;226226+ case APIC_ICR:227227+ savic_icr_write(data, 0);228228+ break;229229+ case APIC_SELF_IPI:230230+ self_ipi_reg_write(data);231231+ break;232232+ /* ALLOWED_IRR offsets are writable */233233+ case SAVIC_ALLOWED_IRR ... SAVIC_ALLOWED_IRR + 0x70:234234+ if (IS_ALIGNED(reg - 4, 16)) {235235+ apic_set_reg(ap, reg, data);236236+ break;237237+ }238238+ fallthrough;239239+ default:240240+ pr_err("Error writing unknown Secure AVIC reg offset 0x%x\n", reg);241241+ }242242+}243243+244244+static void send_ipi(u32 dest, unsigned int vector, unsigned int dsh)245245+{246246+ unsigned int icr_low;247247+248248+ icr_low = __prepare_ICR(dsh, vector, APIC_DEST_PHYSICAL);249249+ savic_icr_write(icr_low, dest);250250+}251251+252252+static void savic_send_ipi(int cpu, int vector)253253+{254254+ u32 dest = per_cpu(x86_cpu_to_apicid, cpu);255255+256256+ send_ipi(dest, vector, 0);257257+}258258+259259+static void send_ipi_mask(const struct cpumask *mask, unsigned int vector, bool excl_self)260260+{261261+ unsigned int cpu, this_cpu;262262+263263+ guard(irqsave)();264264+265265+ this_cpu = raw_smp_processor_id();266266+267267+ for_each_cpu(cpu, mask) {268268+ if (excl_self && cpu == this_cpu)269269+ continue;270270+ send_ipi(per_cpu(x86_cpu_to_apicid, cpu), vector, 0);271271+ }272272+}273273+274274+static void savic_send_ipi_mask(const struct cpumask *mask, int vector)275275+{276276+ send_ipi_mask(mask, vector, false);277277+}278278+279279+static void savic_send_ipi_mask_allbutself(const struct cpumask *mask, int vector)280280+{281281+ send_ipi_mask(mask, vector, true);282282+}283283+284284+static void savic_send_ipi_allbutself(int vector)285285+{286286+ send_ipi(0, vector, APIC_DEST_ALLBUT);287287+}288288+289289+static void savic_send_ipi_all(int vector)290290+{291291+ send_ipi(0, vector, APIC_DEST_ALLINC);292292+}293293+294294+static void savic_send_ipi_self(int vector)295295+{296296+ self_ipi_reg_write(vector);297297+}298298+299299+static void savic_update_vector(unsigned int cpu, unsigned int vector, bool set)300300+{301301+ update_vector(cpu, SAVIC_ALLOWED_IRR, vector, set);302302+}303303+304304+static void savic_eoi(void)305305+{306306+ unsigned int cpu;307307+ int vec;308308+309309+ cpu = raw_smp_processor_id();310310+ vec = apic_find_highest_vector(get_reg_bitmap(cpu, APIC_ISR));311311+ if (WARN_ONCE(vec == -1, "EOI write while no active interrupt in APIC_ISR"))312312+ return;313313+314314+ /* Is level-triggered interrupt? */315315+ if (apic_test_vector(vec, get_reg_bitmap(cpu, APIC_TMR))) {316316+ update_vector(cpu, APIC_ISR, vec, false);317317+ /*318318+ * Propagate the EOI write to the hypervisor for level-triggered319319+ * interrupts. Return to the guest from GHCB protocol event takes320320+ * care of re-evaluating interrupt state.321321+ */322322+ savic_ghcb_msr_write(APIC_EOI, 0);323323+ } else {324324+ /*325325+ * Hardware clears APIC_ISR and re-evaluates the interrupt state326326+ * to determine if there is any pending interrupt which can be327327+ * delivered to CPU.328328+ */329329+ native_apic_msr_eoi();330330+ }331331+}332332+333333+static void savic_teardown(void)334334+{335335+ /* Disable Secure AVIC */336336+ native_wrmsrq(MSR_AMD64_SAVIC_CONTROL, 0);337337+ savic_unregister_gpa(NULL);338338+}339339+340340+static void savic_setup(void)341341+{342342+ void *ap = this_cpu_ptr(savic_page);343343+ enum es_result res;344344+ unsigned long gpa;345345+346346+ /*347347+ * Before Secure AVIC is enabled, APIC MSR reads are intercepted.348348+ * APIC_ID MSR read returns the value from the hypervisor.349349+ */350350+ apic_set_reg(ap, APIC_ID, native_apic_msr_read(APIC_ID));351351+352352+ gpa = __pa(ap);353353+354354+ /*355355+ * The NPT entry for a vCPU's APIC backing page must always be356356+ * present when the vCPU is running in order for Secure AVIC to357357+ * function. A VMEXIT_BUSY is returned on VMRUN and the vCPU cannot358358+ * be resumed if the NPT entry for the APIC backing page is not359359+ * present. Notify GPA of the vCPU's APIC backing page to the360360+ * hypervisor by calling savic_register_gpa(). Before executing361361+ * VMRUN, the hypervisor makes use of this information to make sure362362+ * the APIC backing page is mapped in NPT.363363+ */364364+ res = savic_register_gpa(gpa);365365+ if (res != ES_OK)366366+ sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_SAVIC_FAIL);367367+368368+ native_wrmsrq(MSR_AMD64_SAVIC_CONTROL,369369+ gpa | MSR_AMD64_SAVIC_EN | MSR_AMD64_SAVIC_ALLOWEDNMI);370370+}371371+372372+static int savic_probe(void)373373+{374374+ if (!cc_platform_has(CC_ATTR_SNP_SECURE_AVIC))375375+ return 0;376376+377377+ if (!x2apic_mode) {378378+ pr_err("Secure AVIC enabled in non x2APIC mode\n");379379+ sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_SAVIC_FAIL);380380+ /* unreachable */381381+ }382382+383383+ savic_page = alloc_percpu(struct secure_avic_page);384384+ if (!savic_page)385385+ sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_SAVIC_FAIL);386386+387387+ return 1;388388+}389389+390390+static struct apic apic_x2apic_savic __ro_after_init = {391391+392392+ .name = "secure avic x2apic",393393+ .probe = savic_probe,394394+ .acpi_madt_oem_check = savic_acpi_madt_oem_check,395395+ .setup = savic_setup,396396+ .teardown = savic_teardown,397397+398398+ .dest_mode_logical = false,399399+400400+ .disable_esr = 0,401401+402402+ .cpu_present_to_apicid = default_cpu_present_to_apicid,403403+404404+ .max_apic_id = UINT_MAX,405405+ .x2apic_set_max_apicid = true,406406+ .get_apic_id = x2apic_get_apic_id,407407+408408+ .calc_dest_apicid = apic_default_calc_apicid,409409+410410+ .send_IPI = savic_send_ipi,411411+ .send_IPI_mask = savic_send_ipi_mask,412412+ .send_IPI_mask_allbutself = savic_send_ipi_mask_allbutself,413413+ .send_IPI_allbutself = savic_send_ipi_allbutself,414414+ .send_IPI_all = savic_send_ipi_all,415415+ .send_IPI_self = savic_send_ipi_self,416416+417417+ .nmi_to_offline_cpu = true,418418+419419+ .read = savic_read,420420+ .write = savic_write,421421+ .eoi = savic_eoi,422422+ .icr_read = native_x2apic_icr_read,423423+ .icr_write = savic_icr_write,424424+425425+ .update_vector = savic_update_vector,426426+};427427+428428+apic_driver(apic_x2apic_savic);
+8
include/linux/cc_platform.h
···9696 * enabled to run SEV-SNP guests.9797 */9898 CC_ATTR_HOST_SEV_SNP,9999+100100+ /**101101+ * @CC_ATTR_SNP_SECURE_AVIC: Secure AVIC mode is active.102102+ *103103+ * The host kernel is running with the necessary features enabled104104+ * to run SEV-SNP guests with full Secure AVIC capabilities.105105+ */106106+ CC_ATTR_SNP_SECURE_AVIC,99107};100108101109#ifdef CONFIG_ARCH_HAS_CC_PLATFORM