Path: blob/master/arch/x86/boot/compressed/sev-handle-vc.c
51760 views
// SPDX-License-Identifier: GPL-2.012#include "misc.h"3#include "error.h"4#include "sev.h"56#include <linux/kernel.h>7#include <linux/string.h>8#include <asm/insn.h>9#include <asm/pgtable_types.h>10#include <asm/ptrace.h>11#include <asm/sev.h>12#include <asm/trapnr.h>13#include <asm/trap_pf.h>14#include <asm/fpu/xcr.h>1516#define __BOOT_COMPRESSED17#undef __init18#define __init1920/* Basic instruction decoding support needed */21#include "../../lib/inat.c"22#include "../../lib/insn.c"2324/*25* Copy a version of this function here - insn-eval.c can't be used in26* pre-decompression code.27*/28bool insn_has_rep_prefix(struct insn *insn)29{30insn_byte_t p;3132insn_get_prefixes(insn);3334for_each_insn_prefix(insn, p) {35if (p == 0xf2 || p == 0xf3)36return true;37}3839return false;40}4142enum es_result vc_decode_insn(struct es_em_ctxt *ctxt)43{44char buffer[MAX_INSN_SIZE];45int ret;4647memcpy(buffer, (unsigned char *)ctxt->regs->ip, MAX_INSN_SIZE);4849ret = insn_decode(&ctxt->insn, buffer, MAX_INSN_SIZE, INSN_MODE_64);50if (ret < 0)51return ES_DECODE_FAILED;5253return ES_OK;54}5556extern void sev_insn_decode_init(void) __alias(inat_init_tables);5758/*59* Only a dummy for insn_get_seg_base() - Early boot-code is 64bit only and60* doesn't use segments.61*/62static unsigned long insn_get_seg_base(struct pt_regs *regs, int seg_reg_idx)63{64return 0UL;65}6667static enum es_result vc_write_mem(struct es_em_ctxt *ctxt,68void *dst, char *buf, size_t size)69{70memcpy(dst, buf, size);7172return ES_OK;73}7475static enum es_result vc_read_mem(struct es_em_ctxt *ctxt,76void *src, char *buf, size_t size)77{78memcpy(buf, src, size);7980return ES_OK;81}8283static enum es_result vc_ioio_check(struct es_em_ctxt *ctxt, u16 port, size_t size)84{85return ES_OK;86}8788static bool fault_in_kernel_space(unsigned long address)89{90return false;91}9293#define sev_printk(fmt, ...)9495#include "../../coco/sev/vc-shared.c"9697void do_boot_stage2_vc(struct pt_regs *regs, unsigned long exit_code)98{99struct es_em_ctxt ctxt;100enum es_result result;101102if (!boot_ghcb && !early_setup_ghcb())103sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SEV_ES_GEN_REQ);104105vc_ghcb_invalidate(boot_ghcb);106result = vc_init_em_ctxt(&ctxt, regs, exit_code);107if (result != ES_OK)108goto finish;109110result = vc_check_opcode_bytes(&ctxt, exit_code);111if (result != ES_OK)112goto finish;113114switch (exit_code) {115case SVM_EXIT_RDTSC:116case SVM_EXIT_RDTSCP:117result = vc_handle_rdtsc(boot_ghcb, &ctxt, exit_code);118break;119case SVM_EXIT_IOIO:120result = vc_handle_ioio(boot_ghcb, &ctxt);121break;122case SVM_EXIT_CPUID:123result = vc_handle_cpuid(boot_ghcb, &ctxt);124break;125default:126result = ES_UNSUPPORTED;127break;128}129130finish:131if (result == ES_OK)132vc_finish_insn(&ctxt);133else if (result != ES_RETRY)134sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SEV_ES_GEN_REQ);135}136137138