summaryrefslogtreecommitdiff
path: root/arch/x86/coco/sev/core.c
diff options
context:
space:
mode:
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);