Commit ba37a143 authored by Michael Roth's avatar Michael Roth Committed by Borislav Petkov
Browse files

x86/sev: Add a sev= cmdline option



For debugging purposes it is very useful to have a way to see the full
contents of the SNP CPUID table provided to a guest. Add an sev=debug
kernel command-line option to do so.

Also introduce some infrastructure so that additional options can be
specified via sev=option1[,option2] over time in a consistent manner.

  [ bp: Massage, simplify string parsing. ]

Suggested-by: default avatarBorislav Petkov <bp@alien8.de>
Signed-off-by: default avatarMichael Roth <michael.roth@amd.com>
Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
Link: https://lore.kernel.org/r/20220307213356.2797205-41-brijesh.singh@amd.com
parent 30612045
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -5308,6 +5308,8 @@


	serialnumber	[BUGS=X86-32]
	serialnumber	[BUGS=X86-32]


	sev=option[,option...] [X86-64] See Documentation/x86/x86_64/boot-options.rst

	shapers=	[NET]
	shapers=	[NET]
			Maximal number of shapers.
			Maximal number of shapers.


+14 −0
Original line number Original line Diff line number Diff line
@@ -310,3 +310,17 @@ Miscellaneous
    Do not use GB pages for kernel direct mappings.
    Do not use GB pages for kernel direct mappings.
  gbpages
  gbpages
    Use GB pages for kernel direct mappings.
    Use GB pages for kernel direct mappings.


AMD SEV (Secure Encrypted Virtualization)
=========================================
Options relating to AMD SEV, specified via the following format:

::

   sev=option1[,option2]

The available options are:

   debug
     Enable debug messages.
+44 −0
Original line number Original line Diff line number Diff line
@@ -112,6 +112,13 @@ DEFINE_STATIC_KEY_FALSE(sev_es_enable_key);


static DEFINE_PER_CPU(struct sev_es_save_area *, sev_vmsa);
static DEFINE_PER_CPU(struct sev_es_save_area *, sev_vmsa);


struct sev_config {
	__u64 debug		: 1,
	      __reserved	: 63;
};

static struct sev_config sev_cfg __read_mostly;

static __always_inline bool on_vc_stack(struct pt_regs *regs)
static __always_inline bool on_vc_stack(struct pt_regs *regs)
{
{
	unsigned long sp = regs->sp;
	unsigned long sp = regs->sp;
@@ -2042,6 +2049,23 @@ void __init snp_abort(void)
	sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED);
	sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED);
}
}


static void dump_cpuid_table(void)
{
	const struct snp_cpuid_table *cpuid_table = snp_cpuid_get_table();
	int i = 0;

	pr_info("count=%d reserved=0x%x reserved2=0x%llx\n",
		cpuid_table->count, cpuid_table->__reserved1, cpuid_table->__reserved2);

	for (i = 0; i < SNP_CPUID_COUNT_MAX; i++) {
		const struct snp_cpuid_fn *fn = &cpuid_table->fn[i];

		pr_info("index=%3d fn=0x%08x subfn=0x%08x: eax=0x%08x ebx=0x%08x ecx=0x%08x edx=0x%08x xcr0_in=0x%016llx xss_in=0x%016llx reserved=0x%016llx\n",
			i, fn->eax_in, fn->ecx_in, fn->eax, fn->ebx, fn->ecx,
			fn->edx, fn->xcr0_in, fn->xss_in, fn->__reserved);
	}
}

/*
/*
 * It is useful from an auditing/testing perspective to provide an easy way
 * It is useful from an auditing/testing perspective to provide an easy way
 * for the guest owner to know that the CPUID table has been initialized as
 * for the guest owner to know that the CPUID table has been initialized as
@@ -2059,6 +2083,26 @@ static int __init report_cpuid_table(void)
	pr_info("Using SNP CPUID table, %d entries present.\n",
	pr_info("Using SNP CPUID table, %d entries present.\n",
		cpuid_table->count);
		cpuid_table->count);


	if (sev_cfg.debug)
		dump_cpuid_table();

	return 0;
	return 0;
}
}
arch_initcall(report_cpuid_table);
arch_initcall(report_cpuid_table);

static int __init init_sev_config(char *str)
{
	char *s;

	while ((s = strsep(&str, ","))) {
		if (!strcmp(s, "debug")) {
			sev_cfg.debug = true;
			continue;
		}

		pr_info("SEV command-line option '%s' was not recognized\n", s);
	}

	return 1;
}
__setup("sev=", init_sev_config);