Current code always maps the IOAPIC as shared (decrypted) in a confidential VM. But Hyper-V guest VMs on AMD SEV-SNP with vTOM enabled use a paravisor running in VMPL0 to emulate the IOAPIC. In such a case, the IOAPIC must be accessed as private (encrypted). Fix this by gating the IOAPIC decrypted mapping on a new cc_platform_has() attribute that a subsequent patch in the series will set only for Hyper-V guests. Signed-off-by: Michael Kelley <mikelley@xxxxxxxxxxxxx> Reviewed-by: Wei Liu <wei.liu@xxxxxxxxxx> --- arch/x86/kernel/apic/io_apic.c | 3 ++- include/linux/cc_platform.h | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index a868b76..c65e0cc 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -2686,7 +2686,8 @@ static void io_apic_set_fixmap(enum fixed_addresses idx, phys_addr_t phys) * Ensure fixmaps for IOAPIC MMIO respect memory encryption pgprot * bits, just like normal ioremap(): */ - flags = pgprot_decrypted(flags); + if (!cc_platform_has(CC_ATTR_EMULATED_IOAPIC)) + flags = pgprot_decrypted(flags); __set_fixmap(idx, phys, flags); } diff --git a/include/linux/cc_platform.h b/include/linux/cc_platform.h index cb0d6cd..7a0da75 100644 --- a/include/linux/cc_platform.h +++ b/include/linux/cc_platform.h @@ -90,6 +90,18 @@ enum cc_attr { * Examples include TDX Guest. */ CC_ATTR_HOTPLUG_DISABLED, + + /** + * @CC_ATTR_EMULATED_IOAPIC: Guest VM has an emulated I/O APIC + * + * The platform/OS is running as a guest/virtual machine with + * an I/O APIC that is emulated by a paravisor running in the + * guest VM context. As such, the I/O APIC is accessed in the + * encrypted portion of the guest physical address space. + * + * Examples include Hyper-V SEV-SNP guests using vTOM. + */ + CC_ATTR_EMULATED_IOAPIC, }; #ifdef CONFIG_ARCH_HAS_CC_PLATFORM -- 1.8.3.1