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 <vdavy...@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 <vdavy...@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 <vdavy...@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) _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel