2018-11-05 13:28:20

by Wen Pu

[permalink] [raw]
Subject: [PATCH] x86/cpu: Avoid endless loop to get the number of cache leaves

To get the number of cache leaves on AMD or Hygon platform, it should
get the value of cpuid leaf 0x8000001d. But on certain broken platform
such as a not fullly implemented virtual platform(Xen, for example),
the value of the cpuid leaf will nerver be CTYPE_NULL, so the kernel
will run into an endless loop.

To fix this problem, add a new enum type CTYPE_MAX to limit the maximum
cpuid accessing.

Signed-off-by: Pu Wen <[email protected]>
---
arch/x86/kernel/cpu/cacheinfo.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/cpu/cacheinfo.c b/arch/x86/kernel/cpu/cacheinfo.c
index dc1b934..7bd167f 100644
--- a/arch/x86/kernel/cpu/cacheinfo.c
+++ b/arch/x86/kernel/cpu/cacheinfo.c
@@ -121,7 +121,8 @@ enum _cache_type {
CTYPE_NULL = 0,
CTYPE_DATA = 1,
CTYPE_INST = 2,
- CTYPE_UNIFIED = 3
+ CTYPE_UNIFIED = 3,
+ CTYPE_MAX = 4
};

union _cpuid4_leaf_eax {
@@ -640,7 +641,7 @@ static int find_num_cache_leaves(struct cpuinfo_x86 *c)
/* Do cpuid(op) loop to find out num_cache_leaves */
cpuid_count(op, i, &eax, &ebx, &ecx, &edx);
cache_eax.full = eax;
- } while (cache_eax.split.type != CTYPE_NULL);
+ } while (cache_eax.split.type != CTYPE_NULL && i != CTYPE_MAX);
return i;
}

--
2.7.4



2018-11-15 17:24:35

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH] x86/cpu: Avoid endless loop to get the number of cache leaves

On Mon, Nov 05, 2018 at 08:53:45PM +0800, Pu Wen wrote:
> To get the number of cache leaves on AMD or Hygon platform, it should
> get the value of cpuid leaf 0x8000001d. But on certain broken platform
> such as a not fullly implemented virtual platform(Xen, for example),
> the value of the cpuid leaf will nerver be CTYPE_NULL, so the kernel
> will run into an endless loop.
>
> To fix this problem, add a new enum type CTYPE_MAX to limit the maximum
> cpuid accessing.
>
> Signed-off-by: Pu Wen <[email protected]>
> ---
> arch/x86/kernel/cpu/cacheinfo.c | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/arch/x86/kernel/cpu/cacheinfo.c b/arch/x86/kernel/cpu/cacheinfo.c
> index dc1b934..7bd167f 100644
> --- a/arch/x86/kernel/cpu/cacheinfo.c
> +++ b/arch/x86/kernel/cpu/cacheinfo.c
> @@ -121,7 +121,8 @@ enum _cache_type {
> CTYPE_NULL = 0,
> CTYPE_DATA = 1,
> CTYPE_INST = 2,
> - CTYPE_UNIFIED = 3
> + CTYPE_UNIFIED = 3,
> + CTYPE_MAX = 4
> };
>
> union _cpuid4_leaf_eax {
> @@ -640,7 +641,7 @@ static int find_num_cache_leaves(struct cpuinfo_x86 *c)
> /* Do cpuid(op) loop to find out num_cache_leaves */
> cpuid_count(op, i, &eax, &ebx, &ecx, &edx);
> cache_eax.full = eax;
> - } while (cache_eax.split.type != CTYPE_NULL);
> + } while (cache_eax.split.type != CTYPE_NULL && i != CTYPE_MAX);

i is an int and CTYPE_MAX is enum _cache_type. Huh?

This works by chance because CTYPE_MAX is 4 and the termination CPUID
leaf is the 4th too.

--
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

2018-12-08 02:49:39

by Wen Pu

[permalink] [raw]
Subject: Re: [PATCH] x86/cpu: Avoid endless loop to get the number of cache leaves

Sorry for the late reply :)

On 2018/11/16 1:22, Borislav Petkov wrote:
>> @@ -640,7 +641,7 @@ static int find_num_cache_leaves(struct cpuinfo_x86 *c)
>> /* Do cpuid(op) loop to find out num_cache_leaves */
>> cpuid_count(op, i, &eax, &ebx, &ecx, &edx);
>> cache_eax.full = eax;
>> - } while (cache_eax.split.type != CTYPE_NULL);
>> + } while (cache_eax.split.type != CTYPE_NULL && i != CTYPE_MAX);
> i is an int and CTYPE_MAX is enum _cache_type. Huh?

How about define CTYPE_MAX like this:
#define CTYPE_MAX 4

> This works by chance because CTYPE_MAX is 4 and the termination CPUID
> leaf is the 4th too.

It will return CTYPE_NULL when accessing the 4th CPUID leaf in most of
the cases, but in certain case it will not. So I think it's better to
restrict the maximum CPUID access times to 4 for kernel robustness.

--
Regards,
Pu Wen


2018-12-08 11:13:35

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH] x86/cpu: Avoid endless loop to get the number of cache leaves

On Sat, Dec 08, 2018 at 10:46:54AM +0800, Pu Wen wrote:
> How about define CTYPE_MAX like this:
> #define CTYPE_MAX 4

How about you look at the definition of CPUID leaf 4 and think about it
a bit and realize that this is the wrong thing to do?

> It will return CTYPE_NULL when accessing the 4th CPUID leaf in most of
> the cases, but in certain case it will not.

Well, that's certain cases' problem, isn't it? How about fixing xen
instead?

--
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.