[Devel] [PATCH RHEL7 COMMIT] arch/x86: assure cpuinfo inside ct is subset of host's one
Konstantin Khorenko
khorenko at virtuozzo.com
Tue Oct 20 09:00:23 PDT 2015
The commit is pushed to "branch-rh7-3.10.0-229.7.2.vz7.9.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-229.7.2.vz7.8.9
------>
commit e61afdf96e4f358c18e57c236cce7a3ee4bf0826
Author: Vladimir Davydov <vdavydov at virtuozzo.com>
Date: Tue Oct 20 20:00:23 2015 +0400
arch/x86: assure cpuinfo inside ct is subset of host's one
Port diff-arch-x86-assure-cpuinfo-inside-ct-is-subset-of-hosts-one
In order to reflect cpuid masking setup, /proc/cpuinfo output inside a
container is reported basing on an immediate output of the cpuid
instruction, while host's /proc/cpuinfo still uses cached in-kernel
value. The cached value is usually equal to the output of cpuid at boot
time, but it isn't always true. The kernel can clear some capability
bits due to a hardware bug or because it was explicitly disabled by
passing the appropriate boot parameter. As a result the output of
/proc/cpuinfo inside a container can be wider than that on host, which
looks ridiculous. Let's fix this by using logical AND to combine the
kernel cached value and the raw output of cpuid while reporting cpu
features in /proc/cpuinfo inside a container.
https://jira.sw.ru/browse/PSBM-30688
Signed-off-by: Vladimir Davydov <vdavydov at parallels.com>
=============================================================================
Changes in port:
- cleanup flags->val initialization: use memcpy instead of looping over
individual feature bits
https://jira.sw.ru/browse/PSBM-33638
Signed-off-by: Vladimir Davydov <vdavydov at virtuozzo.com>
---
arch/x86/kernel/cpu/proc.c | 35 ++++++++++++++++++++---------------
1 file changed, 20 insertions(+), 15 deletions(-)
diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c
index 1a95a06..ee32933 100644
--- a/arch/x86/kernel/cpu/proc.c
+++ b/arch/x86/kernel/cpu/proc.c
@@ -67,26 +67,31 @@ static void init_cpu_flags(void *dummy)
int cpu = smp_processor_id();
struct cpu_flags *flags = &per_cpu(cpu_flags, cpu);
struct cpuinfo_x86 *c = &cpu_data(cpu);
- unsigned int tmp1, tmp2, tmp3;
- int i;
+ unsigned int eax, ebx, ecx, edx;
- bitmap_zero((unsigned long *)flags, 32*NCAPINTS);
- for (i = 0; i < 32*NCAPINTS; i++)
- if (cpu_has(c, i))
- set_bit(i, (unsigned long *)flags);
+ memcpy(flags->val, c->x86_capability, NCAPINTS * sizeof(u32));
+
+ /*
+ * Clear feature bits masked using cpuid masking/faulting.
+ */
- if (c->cpuid_level >= 0x00000001)
- __do_cpuid_fault(0x00000001, 0, &tmp1, &tmp2,
- &flags->val[4], &flags->val[0]);
+ if (c->cpuid_level >= 0x00000001) {
+ __do_cpuid_fault(0x00000001, 0, &eax, &ebx, &ecx, &edx);
+ flags->val[4] &= ecx;
+ flags->val[0] &= edx;
+ }
if ((c->extended_cpuid_level & 0xffff0000) == 0x80000000 &&
- c->extended_cpuid_level >= 0x80000001)
- __do_cpuid_fault(0x80000001, 0, &tmp1, &tmp2,
- &flags->val[6], &flags->val[1]);
+ c->extended_cpuid_level >= 0x80000001) {
+ __do_cpuid_fault(0x80000001, 0, &eax, &ebx, &ecx, &edx);
+ flags->val[6] &= ecx;
+ flags->val[1] &= edx;
+ }
- if (c->cpuid_level >= 0x0000000d)
- __do_cpuid_fault(0x0000000d, 1, &flags->val[10],
- &tmp1, &tmp2, &tmp3);
+ if (c->cpuid_level >= 0x0000000d) {
+ __do_cpuid_fault(0x0000000d, 1, &eax, &ebx, &ecx, &edx);
+ flags->val[10] &= eax;
+ }
}
static int show_cpuinfo(struct seq_file *m, void *v)
More information about the Devel
mailing list