Skip to content
Closed
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
11 changes: 11 additions & 0 deletions arch/x86/kernel/crash.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/memblock.h>
#include <linux/psp-sev.h>

#include <asm/processor.h>
#include <asm/hardirq.h>
Expand Down Expand Up @@ -131,6 +132,16 @@ void native_machine_crash_shutdown(struct pt_regs *regs)
/* The kernel is broken so disable interrupts */
local_irq_disable();

/*
* Disable SEV/SNP to allow access to the reserved memory areas
* including a normal IOMMU configuration
* This needs to happen very early in the machine exit due to its
* cross-cpu dependencies.
*/
#ifdef CONFIG_AMD_SEV_SNP
sev_emergency_exit();
#endif

crash_smp_send_stop();

/*
Expand Down
29 changes: 26 additions & 3 deletions drivers/crypto/ccp/sev-dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <linux/fs.h>
#include <linux/fs_struct.h>
#include <linux/amd-iommu.h>
#include <linux/crash_dump.h>

#include <asm/smp.h>
#include <asm/cacheflush.h>
Expand Down Expand Up @@ -2264,9 +2265,12 @@ int sev_dev_init(struct psp_device *psp)

static void sev_firmware_shutdown(struct sev_device *sev)
{
int error;
int error, rc;

sev_platform_shutdown(NULL);
rc = sev_platform_shutdown(&error);
if (rc)
dev_err(sev->dev, "SEV: failed to shutdown platform error 0x%#x, rc %d\n",
error, rc);

if (sev_es_tmr) {
/* The TMR area was encrypted, flush it from the cache */
Expand Down Expand Up @@ -2295,7 +2299,11 @@ static void sev_firmware_shutdown(struct sev_device *sev)
*/
free_snp_host_map(sev);

sev_snp_shutdown(&error);
rc = sev_snp_shutdown(&error);
if (rc)
dev_err(sev->dev, "SEV: failed to shutdown SEV/SNP error 0x%#x, rc %d\n",
error, rc);

}

void sev_dev_destroy(struct psp_device *psp)
Expand Down Expand Up @@ -2379,3 +2387,18 @@ void sev_pci_exit(void)

sev_firmware_shutdown(sev);
}

void sev_emergency_exit(void)
{
struct sev_device *sev;

if (!psp_master)
return;

sev = psp_master->sev_data;

if (!sev)
return;

sev_firmware_shutdown(sev);
}
8 changes: 8 additions & 0 deletions include/linux/psp-sev.h
Original file line number Diff line number Diff line change
Expand Up @@ -804,6 +804,14 @@ struct sev_data_snp_shutdown_ex {
*/
int sev_platform_init(int *error);

/**
* sev_emergency_exit - perform SEV and SNP deinitialization
*
* Intended for emergency situations like kernel crashes
* enableing kdump on the incoming kernel without running SEV/SNP
*/
void sev_emergency_exit(void);

/**
* sev_platform_status - perform SEV PLATFORM_STATUS command
*
Expand Down