Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1538675 > unrolled thread
| Started by | "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> |
|---|---|
| First post | 2016-12-08 17:30 +0100 |
| Last post | 2016-12-09 17:40 +0100 |
| Articles | 6 — 4 participants |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
[RFC, PATCHv1 15/28] x86: detect 5-level paging support "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> - 2016-12-08 17:30 +0100
Re: [RFC, PATCHv1 15/28] x86: detect 5-level paging support Borislav Petkov <bp@alien8.de> - 2016-12-08 21:10 +0100
Re: [RFC, PATCHv1 15/28] x86: detect 5-level paging support Linus Torvalds <torvalds@linux-foundation.org> - 2016-12-08 21:10 +0100
Re: [RFC, PATCHv1 15/28] x86: detect 5-level paging support Borislav Petkov <bp@alien8.de> - 2016-12-08 21:30 +0100
Re: [RFC, PATCHv1 15/28] x86: detect 5-level paging support "Kirill A. Shutemov" <kirill@shutemov.name> - 2016-12-09 16:40 +0100
Re: [RFC, PATCHv1 15/28] x86: detect 5-level paging support Borislav Petkov <bp@alien8.de> - 2016-12-09 17:40 +0100
| From | "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> |
|---|---|
| Date | 2016-12-08 17:30 +0100 |
| Subject | [RFC, PATCHv1 15/28] x86: detect 5-level paging support |
| Message-ID | <sM9K2-8la-3@gated-at.bofh.it> |
5-level paging support is required from hardware when compiled with
CONFIG_X86_5LEVEL=y. We may implement runtime switch support later.
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
---
arch/x86/boot/cpucheck.c | 9 +++++++++
arch/x86/boot/cpuflags.c | 16 ++++++++++++++++
arch/x86/include/asm/cpufeatures.h | 1 +
arch/x86/include/asm/disabled-features.h | 8 +++++++-
arch/x86/include/asm/required-features.h | 8 +++++++-
5 files changed, 40 insertions(+), 2 deletions(-)
diff --git a/arch/x86/boot/cpucheck.c b/arch/x86/boot/cpucheck.c
index 4ad7d70e8739..8f0c4c9fc904 100644
--- a/arch/x86/boot/cpucheck.c
+++ b/arch/x86/boot/cpucheck.c
@@ -44,6 +44,15 @@ static const u32 req_flags[NCAPINTS] =
0, /* REQUIRED_MASK5 not implemented in this file */
REQUIRED_MASK6,
0, /* REQUIRED_MASK7 not implemented in this file */
+ 0, /* REQUIRED_MASK8 not implemented in this file */
+ 0, /* REQUIRED_MASK9 not implemented in this file */
+ 0, /* REQUIRED_MASK10 not implemented in this file */
+ 0, /* REQUIRED_MASK11 not implemented in this file */
+ 0, /* REQUIRED_MASK12 not implemented in this file */
+ 0, /* REQUIRED_MASK13 not implemented in this file */
+ 0, /* REQUIRED_MASK14 not implemented in this file */
+ 0, /* REQUIRED_MASK15 not implemented in this file */
+ REQUIRED_MASK16,
};
#define A32(a, b, c, d) (((d) << 24)+((c) << 16)+((b) << 8)+(a))
diff --git a/arch/x86/boot/cpuflags.c b/arch/x86/boot/cpuflags.c
index 6687ab953257..26e9a287805f 100644
--- a/arch/x86/boot/cpuflags.c
+++ b/arch/x86/boot/cpuflags.c
@@ -80,6 +80,17 @@ static inline void cpuid(u32 id, u32 *a, u32 *b, u32 *c, u32 *d)
);
}
+static inline void cpuid_count(u32 id, u32 count,
+ u32 *a, u32 *b, u32 *c, u32 *d)
+{
+ asm volatile(".ifnc %%ebx,%3 ; movl %%ebx,%3 ; .endif \n\t"
+ "cpuid \n\t"
+ ".ifnc %%ebx,%3 ; xchgl %%ebx,%3 ; .endif \n\t"
+ : "=a" (*a), "=c" (*c), "=d" (*d), EBX_REG (*b)
+ : "a" (id), "c" (count)
+ );
+}
+
void get_cpuflags(void)
{
u32 max_intel_level, max_amd_level;
@@ -108,6 +119,11 @@ void get_cpuflags(void)
cpu.model += ((tfms >> 16) & 0xf) << 4;
}
+ if (max_intel_level >= 0x00000007) {
+ cpuid_count(0x00000007, 0, &ignored, &ignored,
+ &cpu.flags[16], &ignored);
+ }
+
cpuid(0x80000000, &max_amd_level, &ignored, &ignored,
&ignored);
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index 92a8308b96f6..388f1277880f 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -280,6 +280,7 @@
/* Intel-defined CPU features, CPUID level 0x00000007:0 (ecx), word 16 */
#define X86_FEATURE_PKU (16*32+ 3) /* Protection Keys for Userspace */
#define X86_FEATURE_OSPKE (16*32+ 4) /* OS Protection Keys Enable */
+#define X86_FEATURE_LA57 (16*32+16) /* 5-level page tables */
/* 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/include/asm/disabled-features.h b/arch/x86/include/asm/disabled-features.h
index 85599ad4d024..fc0960236fc3 100644
--- a/arch/x86/include/asm/disabled-features.h
+++ b/arch/x86/include/asm/disabled-features.h
@@ -36,6 +36,12 @@
# define DISABLE_OSPKE (1<<(X86_FEATURE_OSPKE & 31))
#endif /* CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS */
+#ifdef CONFIG_X86_5LEVEL
+#define DISABLE_LA57 0
+#else
+#define DISABLE_LA57 (1<<(X86_FEATURE_LA57 & 31))
+#endif
+
/*
* Make sure to add features to the correct mask
*/
@@ -55,7 +61,7 @@
#define DISABLED_MASK13 0
#define DISABLED_MASK14 0
#define DISABLED_MASK15 0
-#define DISABLED_MASK16 (DISABLE_PKU|DISABLE_OSPKE)
+#define DISABLED_MASK16 (DISABLE_PKU|DISABLE_OSPKE|DISABLE_LA57)
#define DISABLED_MASK17 0
#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 18)
diff --git a/arch/x86/include/asm/required-features.h b/arch/x86/include/asm/required-features.h
index fac9a5c0abe9..d91ba04dd007 100644
--- a/arch/x86/include/asm/required-features.h
+++ b/arch/x86/include/asm/required-features.h
@@ -53,6 +53,12 @@
# define NEED_MOVBE 0
#endif
+#ifdef CONFIG_X86_5LEVEL
+# define NEED_LA57 (1<<(X86_FEATURE_LA57 & 31))
+#else
+# define NEED_LA57 0
+#endif
+
#ifdef CONFIG_X86_64
#ifdef CONFIG_PARAVIRT
/* Paravirtualized systems may not have PSE or PGE available */
@@ -98,7 +104,7 @@
#define REQUIRED_MASK13 0
#define REQUIRED_MASK14 0
#define REQUIRED_MASK15 0
-#define REQUIRED_MASK16 0
+#define REQUIRED_MASK16 (NEED_LA57)
#define REQUIRED_MASK17 0
#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 18)
--
2.10.2
[toc] | [next] | [standalone]
| From | Borislav Petkov <bp@alien8.de> |
|---|---|
| Date | 2016-12-08 21:10 +0100 |
| Message-ID | <sMdaV-254-15@gated-at.bofh.it> |
| In reply to | #1538675 |
On Thu, Dec 08, 2016 at 07:21:37PM +0300, Kirill A. Shutemov wrote:
> 5-level paging support is required from hardware when compiled with
> CONFIG_X86_5LEVEL=y. We may implement runtime switch support later.
>
> Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
...
> diff --git a/arch/x86/boot/cpuflags.c b/arch/x86/boot/cpuflags.c
> index 6687ab953257..26e9a287805f 100644
> --- a/arch/x86/boot/cpuflags.c
> +++ b/arch/x86/boot/cpuflags.c
> @@ -80,6 +80,17 @@ static inline void cpuid(u32 id, u32 *a, u32 *b, u32 *c, u32 *d)
> );
> }
>
> +static inline void cpuid_count(u32 id, u32 count,
> + u32 *a, u32 *b, u32 *c, u32 *d)
> +{
> + asm volatile(".ifnc %%ebx,%3 ; movl %%ebx,%3 ; .endif \n\t"
> + "cpuid \n\t"
> + ".ifnc %%ebx,%3 ; xchgl %%ebx,%3 ; .endif \n\t"
> + : "=a" (*a), "=c" (*c), "=d" (*d), EBX_REG (*b)
> + : "a" (id), "c" (count)
> + );
> +}
Pls make those like cpuid() and cpuid_count() in
arch/x86/include/asm/processor.h, which explicitly assign ecx and then
call the underlying helper.
The cpuid() in cpuflags.c doesn't zero ecx which, if we have to be
pedantic, it should do. It calls CPUID now with the ptr value of its 4th
on 64-bit and 3rd arg on 32-bit, respectively, IINM.
--
Regards/Gruss,
Boris.
Good mailing practices for 400: avoid top-posting and trim the reply.
[toc] | [prev] | [next] | [standalone]
| From | Linus Torvalds <torvalds@linux-foundation.org> |
|---|---|
| Date | 2016-12-08 21:10 +0100 |
| Message-ID | <sMdaV-254-17@gated-at.bofh.it> |
| In reply to | #1538847 |
On Thu, Dec 8, 2016 at 12:05 PM, Borislav Petkov <bp@alien8.de> wrote:
>
> The cpuid() in cpuflags.c doesn't zero ecx which, if we have to be
> pedantic, it should do. It calls CPUID now with the ptr value of its 4th
> on 64-bit and 3rd arg on 32-bit, respectively, IINM.
In fact, just do a single cpuid_count(), and then implement the
traditional cpuid() as just
#define cpuid(x, a,b,c,d) cpuid_count(x, 0, a, b, c, d)
or something.
Especially since that's some of the ugliest inline asm ever due to the
nasty BX handling.
Linus
[toc] | [prev] | [next] | [standalone]
| From | Borislav Petkov <bp@alien8.de> |
|---|---|
| Date | 2016-12-08 21:30 +0100 |
| Message-ID | <sMduh-2eY-5@gated-at.bofh.it> |
| In reply to | #1538848 |
On Thu, Dec 08, 2016 at 12:08:53PM -0800, Linus Torvalds wrote:
> Especially since that's some of the ugliest inline asm ever due to the
> nasty BX handling.
Yeah, about that: why doesn't gcc handle that for us like it would
handle a clobbered register? I mean, it *should* know that BX is live
when building with -fPIC... The .ifnc thing looks really silly.
Hmmm.
--
Regards/Gruss,
Boris.
Good mailing practices for 400: avoid top-posting and trim the reply.
[toc] | [prev] | [next] | [standalone]
| From | "Kirill A. Shutemov" <kirill@shutemov.name> |
|---|---|
| Date | 2016-12-09 16:40 +0100 |
| Message-ID | <sMvrc-4YR-19@gated-at.bofh.it> |
| In reply to | #1538847 |
On Thu, Dec 08, 2016 at 09:05:05PM +0100, Borislav Petkov wrote:
> On Thu, Dec 08, 2016 at 07:21:37PM +0300, Kirill A. Shutemov wrote:
> > 5-level paging support is required from hardware when compiled with
> > CONFIG_X86_5LEVEL=y. We may implement runtime switch support later.
> >
> > Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
>
> ...
>
> > diff --git a/arch/x86/boot/cpuflags.c b/arch/x86/boot/cpuflags.c
> > index 6687ab953257..26e9a287805f 100644
> > --- a/arch/x86/boot/cpuflags.c
> > +++ b/arch/x86/boot/cpuflags.c
> > @@ -80,6 +80,17 @@ static inline void cpuid(u32 id, u32 *a, u32 *b, u32 *c, u32 *d)
> > );
> > }
> >
> > +static inline void cpuid_count(u32 id, u32 count,
> > + u32 *a, u32 *b, u32 *c, u32 *d)
> > +{
> > + asm volatile(".ifnc %%ebx,%3 ; movl %%ebx,%3 ; .endif \n\t"
> > + "cpuid \n\t"
> > + ".ifnc %%ebx,%3 ; xchgl %%ebx,%3 ; .endif \n\t"
> > + : "=a" (*a), "=c" (*c), "=d" (*d), EBX_REG (*b)
> > + : "a" (id), "c" (count)
> > + );
> > +}
>
> Pls make those like cpuid() and cpuid_count() in
> arch/x86/include/asm/processor.h, which explicitly assign ecx and then
> call the underlying helper.
>
> The cpuid() in cpuflags.c doesn't zero ecx which, if we have to be
> pedantic, it should do. It calls CPUID now with the ptr value of its 4th
> on 64-bit and 3rd arg on 32-bit, respectively, IINM.
Something like this?
diff --git a/arch/x86/boot/cpuflags.c b/arch/x86/boot/cpuflags.c
index 6687ab953257..366aad972025 100644
--- a/arch/x86/boot/cpuflags.c
+++ b/arch/x86/boot/cpuflags.c
@@ -70,16 +70,22 @@ int has_eflag(unsigned long mask)
# define EBX_REG "=b"
#endif
-static inline void cpuid(u32 id, u32 *a, u32 *b, u32 *c, u32 *d)
+static inline void cpuid_count(u32 id, u32 count,
+ u32 *a, u32 *b, u32 *c, u32 *d)
{
+ *a = id;
+ *c = count;
+
asm volatile(".ifnc %%ebx,%3 ; movl %%ebx,%3 ; .endif \n\t"
"cpuid \n\t"
".ifnc %%ebx,%3 ; xchgl %%ebx,%3 ; .endif \n\t"
: "=a" (*a), "=c" (*c), "=d" (*d), EBX_REG (*b)
- : "a" (id)
+ : "a" (id), "c" (count)
);
}
+#define cpuid(id, a, b, c, d) cpuid_count(id, 0, a, b, c, d)
+
void get_cpuflags(void)
{
u32 max_intel_level, max_amd_level;
--
Kirill A. Shutemov
[toc] | [prev] | [next] | [standalone]
| From | Borislav Petkov <bp@alien8.de> |
|---|---|
| Date | 2016-12-09 17:40 +0100 |
| Message-ID | <sMwnh-5zi-109@gated-at.bofh.it> |
| In reply to | #1539444 |
On Fri, Dec 09, 2016 at 06:32:33PM +0300, Kirill A. Shutemov wrote:
> Something like this?
>
> diff --git a/arch/x86/boot/cpuflags.c b/arch/x86/boot/cpuflags.c
> index 6687ab953257..366aad972025 100644
> --- a/arch/x86/boot/cpuflags.c
> +++ b/arch/x86/boot/cpuflags.c
> @@ -70,16 +70,22 @@ int has_eflag(unsigned long mask)
> # define EBX_REG "=b"
> #endif
>
> -static inline void cpuid(u32 id, u32 *a, u32 *b, u32 *c, u32 *d)
> +static inline void cpuid_count(u32 id, u32 count,
> + u32 *a, u32 *b, u32 *c, u32 *d)
> {
> + *a = id;
> + *c = count;
> +
> asm volatile(".ifnc %%ebx,%3 ; movl %%ebx,%3 ; .endif \n\t"
> "cpuid \n\t"
> ".ifnc %%ebx,%3 ; xchgl %%ebx,%3 ; .endif \n\t"
> : "=a" (*a), "=c" (*c), "=d" (*d), EBX_REG (*b)
> - : "a" (id)
> + : "a" (id), "c" (count)
> );
> }
>
> +#define cpuid(id, a, b, c, d) cpuid_count(id, 0, a, b, c, d)
LGTM.
Thanks.
--
Regards/Gruss,
Boris.
Good mailing practices for 400: avoid top-posting and trim the reply.
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web