diff mbox series

[v14,04/19] x86/cpufeatures: Add SGX feature bits

Message ID 20180925130845.9962-5-jarkko.sakkinen@linux.intel.com (mailing list archive)
State New, archived
Headers show
Series Intel SGX1 support | expand

Commit Message

Jarkko Sakkinen Sept. 25, 2018, 1:06 p.m. UTC
From: Sean Christopherson <sean.j.christopherson@intel.com>

Add SGX feature bits as part of the Linux defined leaf 8, which
currently contains virtualization flags.  There are currently four
documented SGX feature bits, with more expected in the not-too-distant
future.

Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
Co-developed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
---
 arch/x86/include/asm/cpufeatures.h |  8 +++++-
 arch/x86/kernel/cpu/intel.c        | 40 ++++++++++++++++++++++++++++++
 2 files changed, 47 insertions(+), 1 deletion(-)

Comments

Borislav Petkov Sept. 25, 2018, 4:48 p.m. UTC | #1
On Tue, Sep 25, 2018 at 04:06:41PM +0300, Jarkko Sakkinen wrote:
> From: Sean Christopherson <sean.j.christopherson@intel.com>
> 
> Add SGX feature bits as part of the Linux defined leaf 8, which
> currently contains virtualization flags.  There are currently four
> documented SGX feature bits, with more expected in the not-too-distant
> future.

...

> +static void detect_sgx(struct cpuinfo_x86 *c)
> +{
> +#define _X86_FEATURE_SGX1		BIT(0)
> +#define _X86_FEATURE_SGX2		BIT(1)
> +#define _X86_FEATURE_SGX_ENCLV		BIT(5)
> +#define _X86_FEATURE_SGX_ENCLS_C	BIT(6)
> +
> +	unsigned int eax;
> +
> +	clear_cpu_cap(c, X86_FEATURE_SGX1);
> +	clear_cpu_cap(c, X86_FEATURE_SGX2);
> +	clear_cpu_cap(c, X86_FEATURE_SGX_ENCLV);
> +	clear_cpu_cap(c, X86_FEATURE_SGX_ENCLS_C);
> +
> +	if (c->cpuid_level < SGX_CPUID) {
> +		pr_err_once("x86/sgx: cannot enumerate CPUID leaf (0x%x)\n",
> +			    SGX_CPUID);
> +		clear_cpu_cap(c, X86_FEATURE_SGX);
> +		return;
> +	}
> +
> +	eax = cpuid_eax(SGX_CPUID);
> +
> +	if (eax & _X86_FEATURE_SGX1)
> +		set_cpu_cap(c, X86_FEATURE_SGX1);
> +
> +	if (eax & _X86_FEATURE_SGX2)
> +		set_cpu_cap(c, X86_FEATURE_SGX2);
> +
> +	if (eax & _X86_FEATURE_SGX_ENCLV)
> +		set_cpu_cap(c, X86_FEATURE_SGX_ENCLV);
> +
> +	if (eax & _X86_FEATURE_SGX_ENCLS_C)
> +		set_cpu_cap(c, X86_FEATURE_SGX_ENCLS_C);


Look at arch/x86/kernel/cpu/scattered.c for how to do this properly.
Jarkko Sakkinen Sept. 26, 2018, 11:11 a.m. UTC | #2
On Tue, Sep 25, 2018 at 06:48:54PM +0200, Borislav Petkov wrote:
> > +	eax = cpuid_eax(SGX_CPUID);
> > +
> > +	if (eax & _X86_FEATURE_SGX1)
> > +		set_cpu_cap(c, X86_FEATURE_SGX1);
> > +
> > +	if (eax & _X86_FEATURE_SGX2)
> > +		set_cpu_cap(c, X86_FEATURE_SGX2);
> > +
> > +	if (eax & _X86_FEATURE_SGX_ENCLV)
> > +		set_cpu_cap(c, X86_FEATURE_SGX_ENCLV);
> > +
> > +	if (eax & _X86_FEATURE_SGX_ENCLS_C)
> > +		set_cpu_cap(c, X86_FEATURE_SGX_ENCLS_C);
> 
> 
> Look at arch/x86/kernel/cpu/scattered.c for how to do this properly.

Thank you. I guess I understand what you want me to do i.e.

+       { X86_FEATURE_SGX1,             CPUID_EAX,  0, 0x00000012, 0 },
+       { X86_FEATURE_SGX2,             CPUID_EAX,  1, 0x00000012, 0 },
+       { X86_FEATURE_ENCLV,            CPUID_EAX,  5, 0x00000012, 0 },
+       { X86_FEATURE_ENCLS_C,          CPUID_EAX,  6, 0x00000012, 0 },

What puzzles me is that I cannot find any call site for
get_scattered_cpuid_leaf():

$ git grep get_scattered
arch/x86/kernel/cpu/cpu.h:extern u32 get_scattered_cpuid_leaf(unsigned int level,
arch/x86/kernel/cpu/scattered.c:u32 get_scattered_cpuid_leaf(unsigned int level, unsigned int sub_leaf,
arch/x86/kernel/cpu/scattered.c:EXPORT_SYMBOL_GPL(get_scattered_cpuid_leaf);

/Jarkko
Borislav Petkov Sept. 26, 2018, 11:36 a.m. UTC | #3
On Wed, Sep 26, 2018 at 02:11:39PM +0300, Jarkko Sakkinen wrote:
> Thank you. I guess I understand what you want me to do i.e.
> 
> +       { X86_FEATURE_SGX1,             CPUID_EAX,  0, 0x00000012, 0 },
> +       { X86_FEATURE_SGX2,             CPUID_EAX,  1, 0x00000012, 0 },
> +       { X86_FEATURE_ENCLV,            CPUID_EAX,  5, 0x00000012, 0 },
> +       { X86_FEATURE_ENCLS_C,          CPUID_EAX,  6, 0x00000012, 0 },

Yap.

> What puzzles me is that I cannot find any call site for
> get_scattered_cpuid_leaf():
> 
> $ git grep get_scattered
> arch/x86/kernel/cpu/cpu.h:extern u32 get_scattered_cpuid_leaf(unsigned int level,
> arch/x86/kernel/cpu/scattered.c:u32 get_scattered_cpuid_leaf(unsigned int level, unsigned int sub_leaf,
> arch/x86/kernel/cpu/scattered.c:EXPORT_SYMBOL_GPL(get_scattered_cpuid_leaf);

That used to be used in kvm last, see b7b27aa011a1df42728d1768fc181d9ce69e6911,
which removed it.

And it got added by

  47bdf3378d62 ("x86/cpuid: Provide get_scattered_cpuid_leaf()")

Lemme add those people to CC.

If no one wants it, feel free to decomission it.
Jarkko Sakkinen Sept. 27, 2018, 1:16 p.m. UTC | #4
On Wed, Sep 26, 2018 at 01:36:17PM +0200, Borislav Petkov wrote:
> On Wed, Sep 26, 2018 at 02:11:39PM +0300, Jarkko Sakkinen wrote:
> > Thank you. I guess I understand what you want me to do i.e.
> > 
> > +       { X86_FEATURE_SGX1,             CPUID_EAX,  0, 0x00000012, 0 },
> > +       { X86_FEATURE_SGX2,             CPUID_EAX,  1, 0x00000012, 0 },
> > +       { X86_FEATURE_ENCLV,            CPUID_EAX,  5, 0x00000012, 0 },
> > +       { X86_FEATURE_ENCLS_C,          CPUID_EAX,  6, 0x00000012, 0 },
> 
> Yap.
> 
> > What puzzles me is that I cannot find any call site for
> > get_scattered_cpuid_leaf():
> > 
> > $ git grep get_scattered
> > arch/x86/kernel/cpu/cpu.h:extern u32 get_scattered_cpuid_leaf(unsigned int level,
> > arch/x86/kernel/cpu/scattered.c:u32 get_scattered_cpuid_leaf(unsigned int level, unsigned int sub_leaf,
> > arch/x86/kernel/cpu/scattered.c:EXPORT_SYMBOL_GPL(get_scattered_cpuid_leaf);
> 
> That used to be used in kvm last, see b7b27aa011a1df42728d1768fc181d9ce69e6911,
> which removed it.
> 
> And it got added by
> 
>   47bdf3378d62 ("x86/cpuid: Provide get_scattered_cpuid_leaf()")
> 
> Lemme add those people to CC.
> 
> If no one wants it, feel free to decomission it.

Still kind of leaves me puzzled about the situation :-) Why this wasn't
used for example to replace detect_vmx_virtcap()?

/Jarkko
Borislav Petkov Sept. 27, 2018, 1:51 p.m. UTC | #5
On Thu, Sep 27, 2018 at 04:16:42PM +0300, Jarkko Sakkinen wrote:
> Still kind of leaves me puzzled about the situation :-) Why this wasn't
> used for example to replace detect_vmx_virtcap()?

I don't understand - detect_vmx_virtcap() is setting X86_FEATURE bits
based on MSR settings. get_scattered_cpuid_leaf() is regenerating a
CPUID leaf from the scattered bits.

Looks like apples and oranges to me...
Jarkko Sakkinen Sept. 27, 2018, 2:52 p.m. UTC | #6
On Thu, Sep 27, 2018 at 03:51:39PM +0200, Borislav Petkov wrote:
> On Thu, Sep 27, 2018 at 04:16:42PM +0300, Jarkko Sakkinen wrote:
> > Still kind of leaves me puzzled about the situation :-) Why this wasn't
> > used for example to replace detect_vmx_virtcap()?
> 
> I don't understand - detect_vmx_virtcap() is setting X86_FEATURE bits
> based on MSR settings. get_scattered_cpuid_leaf() is regenerating a
> CPUID leaf from the scattered bits.
> 
> Looks like apples and oranges to me...
> 
> -- 
> Regards/Gruss,
>     Boris.
> 
> Good mailing practices for 400: avoid top-posting and trim the reply.

Ugh, sorry, I was not thinking clearly :-)

/Jarkko
diff mbox series

Patch

diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index 7bb647f57d42..d6f4abe6d0b0 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -233,6 +233,12 @@ 
 #define X86_FEATURE_XENPV		( 8*32+16) /* "" Xen paravirtual guest */
 #define X86_FEATURE_EPT_AD		( 8*32+17) /* Intel Extended Page Table access-dirty bit */
 
+/* SGX flags: Linux defined, word 8 */
+#define X86_FEATURE_SGX1		( 8*32+24) /* SGX1 leaf functions */
+#define X86_FEATURE_SGX2		( 8*32+25) /* SGX2 leaf functions */
+#define X86_FEATURE_SGX_ENCLV		( 8*32+26) /* SGX ENCLV instruction, leafs E[INC|DEC]VIRTCHILD, ESETCONTEXT */
+#define X86_FEATURE_SGX_ENCLS_C		( 8*32+27) /* SGX ENCLS leafs ERDINFO, ETRACK, ELDBC and ELDUC */
+
 /* Intel-defined CPU features, CPUID level 0x00000007:0 (EBX), word 9 */
 #define X86_FEATURE_FSGSBASE		( 9*32+ 0) /* RDFSBASE, WRFSBASE, RDGSBASE, WRGSBASE instructions*/
 #define X86_FEATURE_TSC_ADJUST		( 9*32+ 1) /* TSC adjustment MSR 0x3B */
@@ -332,7 +338,7 @@ 
 #define X86_FEATURE_LA57		(16*32+16) /* 5-level page tables */
 #define X86_FEATURE_RDPID		(16*32+22) /* RDPID instruction */
 #define X86_FEATURE_CLDEMOTE		(16*32+25) /* CLDEMOTE instruction */
-#define X86_FEATURE_SGX_LC		(16*32+30) /* supports SGX launch configuration */
+#define X86_FEATURE_SGX_LC		(16*32+30) /* supports SGX launch control */
 
 /* AMD-defined CPU features, CPUID level 0x80000007 (EBX), word 17 */
 #define X86_FEATURE_OVERFLOW_RECOV	(17*32+ 0) /* MCA overflow recovery support */
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index fc3c07fe7df5..fcf188d5f9df 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -19,6 +19,7 @@ 
 #include <asm/microcode_intel.h>
 #include <asm/hwcap2.h>
 #include <asm/elf.h>
+#include <asm/sgx_arch.h>
 
 #ifdef CONFIG_X86_64
 #include <linux/topology.h>
@@ -512,6 +513,42 @@  static void detect_vmx_virtcap(struct cpuinfo_x86 *c)
 	}
 }
 
+static void detect_sgx(struct cpuinfo_x86 *c)
+{
+#define _X86_FEATURE_SGX1		BIT(0)
+#define _X86_FEATURE_SGX2		BIT(1)
+#define _X86_FEATURE_SGX_ENCLV		BIT(5)
+#define _X86_FEATURE_SGX_ENCLS_C	BIT(6)
+
+	unsigned int eax;
+
+	clear_cpu_cap(c, X86_FEATURE_SGX1);
+	clear_cpu_cap(c, X86_FEATURE_SGX2);
+	clear_cpu_cap(c, X86_FEATURE_SGX_ENCLV);
+	clear_cpu_cap(c, X86_FEATURE_SGX_ENCLS_C);
+
+	if (c->cpuid_level < SGX_CPUID) {
+		pr_err_once("x86/sgx: cannot enumerate CPUID leaf (0x%x)\n",
+			    SGX_CPUID);
+		clear_cpu_cap(c, X86_FEATURE_SGX);
+		return;
+	}
+
+	eax = cpuid_eax(SGX_CPUID);
+
+	if (eax & _X86_FEATURE_SGX1)
+		set_cpu_cap(c, X86_FEATURE_SGX1);
+
+	if (eax & _X86_FEATURE_SGX2)
+		set_cpu_cap(c, X86_FEATURE_SGX2);
+
+	if (eax & _X86_FEATURE_SGX_ENCLV)
+		set_cpu_cap(c, X86_FEATURE_SGX_ENCLV);
+
+	if (eax & _X86_FEATURE_SGX_ENCLS_C)
+		set_cpu_cap(c, X86_FEATURE_SGX_ENCLS_C);
+}
+
 #define MSR_IA32_TME_ACTIVATE		0x982
 
 /* Helpers to access TME_ACTIVATE MSR */
@@ -760,6 +797,9 @@  static void init_intel(struct cpuinfo_x86 *c)
 	if (cpu_has(c, X86_FEATURE_VMX))
 		detect_vmx_virtcap(c);
 
+	if (cpu_has(c, X86_FEATURE_SGX))
+		detect_sgx(c);
+
 	if (cpu_has(c, X86_FEATURE_TME))
 		detect_tme(c);