Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions arch/x86/coco/sev/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1425,6 +1425,34 @@ int snp_issue_svsm_attest_req(u64 call_id, struct svsm_call *call,
}
EXPORT_SYMBOL_GPL(snp_issue_svsm_attest_req);

void snp_issue_svsm_reboot_req(void)
{
struct svsm_call call;
unsigned long flags;

if (!snp_vmpl)
return;

local_irq_save(flags);

/*
* Set input registers for the request and set RDX and R8 to known
* values in order to detect length values being returned in them.
*/
call.caa = svsm_get_caa();
call.rax = SVSM_REBOOT_CALL(SVSM_REBOOT_EXECUTE);
call.rcx = 0;
svsm_perform_call_protocol(&call);
/*
* If SVSM_REBOOT_EXECUTE is supported in the underlying SVSM,
* it will NOT return here. If it is not supported, return to
* the caller to try other reboot schemes.
*/

local_irq_restore(flags);
}
EXPORT_SYMBOL_GPL(snp_issue_svsm_reboot_req);

static int snp_issue_guest_request(struct snp_guest_req *req)
{
struct snp_req_data *input = &req->input;
Expand Down
5 changes: 5 additions & 0 deletions arch/x86/include/asm/sev.h
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,9 @@ struct svsm_call {
#define SVSM_VTPM_QUERY 0
#define SVSM_VTPM_CMD 1

#define SVSM_REBOOT_CALL(x) ((5ULL << 32) | (x))
#define SVSM_REBOOT_EXECUTE 0

#ifdef CONFIG_AMD_MEM_ENCRYPT

extern u8 snp_vmpl;
Expand Down Expand Up @@ -523,6 +526,7 @@ int prepare_pte_enc(struct pte_enc_desc *d);
void set_pte_enc_mask(pte_t *kpte, unsigned long pfn, pgprot_t new_prot);
void snp_kexec_finish(void);
void snp_kexec_begin(void);
void snp_issue_svsm_reboot_req(void);

int snp_msg_init(struct snp_msg_desc *mdesc, int vmpck_id);
struct snp_msg_desc *snp_msg_alloc(void);
Expand Down Expand Up @@ -615,6 +619,7 @@ static inline int prepare_pte_enc(struct pte_enc_desc *d) { return 0; }
static inline void set_pte_enc_mask(pte_t *kpte, unsigned long pfn, pgprot_t new_prot) { }
static inline void snp_kexec_finish(void) { }
static inline void snp_kexec_begin(void) { }
static inline void snp_issue_svsm_reboot_req(void) { }
static inline int snp_msg_init(struct snp_msg_desc *mdesc, int vmpck_id) { return -1; }
static inline struct snp_msg_desc *snp_msg_alloc(void) { return NULL; }
static inline void snp_msg_free(struct snp_msg_desc *mdesc) { }
Expand Down
10 changes: 10 additions & 0 deletions arch/x86/kernel/reboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <asm/cpu.h>
#include <asm/nmi.h>
#include <asm/smp.h>
#include <asm/sev.h>

#include <linux/ctype.h>
#include <linux/mc146818rtc.h>
Expand Down Expand Up @@ -650,6 +651,15 @@ static void native_machine_emergency_restart(void)
reboot_type = BOOT_EFI;
}

/*
* If we're running under SVSM, try to reboot using SVSM.
*/
if (snp_vmpl) {
pr_emerg("Trying SVSM Reboot\n");
snp_issue_svsm_reboot_req();
pr_emerg("SVSM Reboot returned.\n");
}

for (;;) {
/* Could also try the reset bit in the Hammer NB */
switch (reboot_type) {
Expand Down