[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