summaryrefslogtreecommitdiff
path: root/arch/x86/coco/sev/core.c
diff options
context:
space:
mode:
authorNeeraj Upadhyay <Neeraj.Upadhyay@amd.com>2025-08-28 16:39:26 +0530
committerBorislav Petkov (AMD) <bp@alien8.de>2025-09-01 12:47:07 +0200
commitea7d792e11e10f502933c39f3836cb73d35dac36 (patch)
treeb0f3eadd902590e8a601eb5064cb283fe6026acc /arch/x86/coco/sev/core.c
parent2c6978ea1a85603fe7d401f7bb3a1fbcab21fde2 (diff)
x86/apic: Support LAPIC timer for Secure AVIC
Secure AVIC requires the LAPIC timer to be emulated by the hypervisor. KVM already supports emulating the LAPIC timer using hrtimers. In order to emulate it, APIC_LVTT, APIC_TMICT and APIC_TDCR register values need to be propagated to the hypervisor for arming the timer. APIC_TMCCT register value has to be read from the hypervisor, which is required for calibrating the APIC timer. So, read/write all APIC timer registers from/to the hypervisor. Co-developed-by: Kishon Vijay Abraham I <kvijayab@amd.com> Signed-off-by: Kishon Vijay Abraham I <kvijayab@amd.com> Signed-off-by: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com> Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de> Reviewed-by: Tianyu Lan <tiala@microsoft.com> Link: https://lore.kernel.org/20250828110926.208866-1-Neeraj.Upadhyay@amd.com
Diffstat (limited to 'arch/x86/coco/sev/core.c')
-rw-r--r--arch/x86/coco/sev/core.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/arch/x86/coco/sev/core.c b/arch/x86/coco/sev/core.c
index bb33fc2265db..da9fa9d7254b 100644
--- a/arch/x86/coco/sev/core.c
+++ b/arch/x86/coco/sev/core.c
@@ -1108,6 +1108,32 @@ int __init sev_es_efi_map_ghcbs_cas(pgd_t *pgd)
return 0;
}
+u64 savic_ghcb_msr_read(u32 reg)
+{
+ u64 msr = APIC_BASE_MSR + (reg >> 4);
+ struct pt_regs regs = { .cx = msr };
+ struct es_em_ctxt ctxt = { .regs = &regs };
+ struct ghcb_state state;
+ enum es_result res;
+ struct ghcb *ghcb;
+
+ guard(irqsave)();
+
+ ghcb = __sev_get_ghcb(&state);
+ vc_ghcb_invalidate(ghcb);
+
+ res = sev_es_ghcb_handle_msr(ghcb, &ctxt, false);
+ if (res != ES_OK) {
+ pr_err("Secure AVIC MSR (0x%llx) read returned error (%d)\n", msr, res);
+ /* MSR read failures are treated as fatal errors */
+ snp_abort();
+ }
+
+ __sev_put_ghcb(&state);
+
+ return regs.ax | regs.dx << 32;
+}
+
void savic_ghcb_msr_write(u32 reg, u64 value)
{
u64 msr = APIC_BASE_MSR + (reg >> 4);