[Devel] [PATCH vz8 v2 2/2] x86: don't enable cpuid faults if /proc/vz/cpuid_override unused

2020-11-02 Thread Andrey Ryabinin
We don't need to enable cpuid faults if /proc/vz/cpuid_override
was never used. If task was attached to ve before a write to
'cpuid_override' it will not get cpuid faults now. It shouldn't
be a problem since the proper use of 'cpuid_override' requires
stopping all containers.

https://jira.sw.ru/browse/PSBM-121823
Signed-off-by: Andrey Ryabinin 
---

Changes since v1:
 - git add include/linux/cpuid_override.h 
 
 arch/x86/kernel/cpuid_fault.c  | 21 ++---
 include/linux/cpuid_override.h | 30 ++
 kernel/ve/ve.c |  5 -
 3 files changed, 36 insertions(+), 20 deletions(-)
 create mode 100644 include/linux/cpuid_override.h

diff --git a/arch/x86/kernel/cpuid_fault.c b/arch/x86/kernel/cpuid_fault.c
index 1e8ffacc4412..cb6c2216fa8a 100644
--- a/arch/x86/kernel/cpuid_fault.c
+++ b/arch/x86/kernel/cpuid_fault.c
@@ -1,3 +1,4 @@
+#include 
 #include 
 #include 
 #include 
@@ -9,25 +10,7 @@
 #include 
 #include 
 
-struct cpuid_override_entry {
-   unsigned int op;
-   unsigned int count;
-   bool has_count;
-   unsigned int eax;
-   unsigned int ebx;
-   unsigned int ecx;
-   unsigned int edx;
-};
-
-#define MAX_CPUID_OVERRIDE_ENTRIES 16
-
-struct cpuid_override_table {
-   struct rcu_head rcu_head;
-   int size;
-   struct cpuid_override_entry entries[MAX_CPUID_OVERRIDE_ENTRIES];
-};
-
-static struct cpuid_override_table __rcu *cpuid_override __read_mostly;
+struct cpuid_override_table __rcu *cpuid_override __read_mostly;
 static DEFINE_SPINLOCK(cpuid_override_lock);
 
 static void cpuid_override_update(struct cpuid_override_table *new_table)
diff --git a/include/linux/cpuid_override.h b/include/linux/cpuid_override.h
new file mode 100644
index ..ea0fa7af3d3c
--- /dev/null
+++ b/include/linux/cpuid_override.h
@@ -0,0 +1,30 @@
+#ifndef __CPUID_OVERRIDE_H
+#define __CPUID_OVERRIDE_H
+
+#include 
+
+struct cpuid_override_entry {
+   unsigned int op;
+   unsigned int count;
+   bool has_count;
+   unsigned int eax;
+   unsigned int ebx;
+   unsigned int ecx;
+   unsigned int edx;
+};
+
+#define MAX_CPUID_OVERRIDE_ENTRIES 16
+
+struct cpuid_override_table {
+   struct rcu_head rcu_head;
+   int size;
+   struct cpuid_override_entry entries[MAX_CPUID_OVERRIDE_ENTRIES];
+};
+
+extern struct cpuid_override_table __rcu *cpuid_override;
+
+static inline bool cpuid_override_on(void)
+{
+   return rcu_access_pointer(cpuid_override);
+}
+#endif
diff --git a/kernel/ve/ve.c b/kernel/ve/ve.c
index aad8ce69ca1f..0d4d0ab70369 100644
--- a/kernel/ve/ve.c
+++ b/kernel/ve/ve.c
@@ -9,6 +9,7 @@
  * 've.c' helper file performing VE sub-system initialization
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -801,6 +802,7 @@ static void ve_attach(struct cgroup_taskset *tset)
 {
struct cgroup_subsys_state *css;
struct task_struct *task;
+   extern struct cpuid_override_table __rcu *cpuid_override;
 
cgroup_taskset_for_each(task, css, tset) {
struct ve_struct *ve = css_to_ve(css);
@@ -816,7 +818,8 @@ static void ve_attach(struct cgroup_taskset *tset)
/* Leave parent exec domain */
task->parent_exec_id--;
 
-   set_tsk_thread_flag(task, TIF_CPUID_OVERRIDE);
+   if (cpuid_override_on())
+   set_tsk_thread_flag(task, TIF_CPUID_OVERRIDE);
task->task_ve = ve;
}
 }
-- 
2.26.2

___
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel


[Devel] [PATCH vz8 v2 1/2] x86, cpuinfo: Fix race on parallel /proc/cpuinfo read

2020-11-02 Thread Andrey Ryabinin
If several threads read /proc/cpuinfo some can see in 'flags'
values from c->x86_capability, before __do_cpuid_fault() called
and masks applied. Fix this by forming 'flags' on stack first
and copy them in per_cpu(cpu_flags, cpu) as a last step.

https://jira.sw.ru/browse/PSBM-121823
Signed-off-by: Andrey Ryabinin 
---
Changes since v1:
 - none
 
 arch/x86/kernel/cpu/proc.c | 17 +
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c
index 4fe1577d5e6f..4cc2951e34fb 100644
--- a/arch/x86/kernel/cpu/proc.c
+++ b/arch/x86/kernel/cpu/proc.c
@@ -69,11 +69,11 @@ static DEFINE_PER_CPU(struct cpu_flags, cpu_flags);
 static void init_cpu_flags(void *dummy)
 {
int cpu = smp_processor_id();
-   struct cpu_flags *flags = _cpu(cpu_flags, cpu);
+   struct cpu_flags flags;
struct cpuinfo_x86 *c = _data(cpu);
unsigned int eax, ebx, ecx, edx;
 
-   memcpy(flags->val, c->x86_capability, NCAPINTS * sizeof(u32));
+   memcpy(, c->x86_capability, sizeof(flags));
 
/*
 * Clear feature bits masked using cpuid masking/faulting.
@@ -81,26 +81,27 @@ static void init_cpu_flags(void *dummy)
 
if (c->cpuid_level >= 0x0001) {
__do_cpuid_fault(0x0001, 0, , , , );
-   flags->val[4] &= ecx;
-   flags->val[0] &= edx;
+   flags.val[4] &= ecx;
+   flags.val[0] &= edx;
}
 
if (c->cpuid_level >= 0x0007) {
__do_cpuid_fault(0x0007, 0, , , , );
-   flags->val[9] &= ebx;
+   flags.val[9] &= ebx;
}
 
if ((c->extended_cpuid_level & 0x) == 0x8000 &&
c->extended_cpuid_level >= 0x8001) {
__do_cpuid_fault(0x8001, 0, , , , );
-   flags->val[6] &= ecx;
-   flags->val[1] &= edx;
+   flags.val[6] &= ecx;
+   flags.val[1] &= edx;
}
 
if (c->cpuid_level >= 0x000d) {
__do_cpuid_fault(0x000d, 1, , , , );
-   flags->val[10] &= eax;
+   flags.val[10] &= eax;
}
+   memcpy(_cpu(cpu_flags, cpu), , sizeof(flags));
 }
 
 static int show_cpuinfo(struct seq_file *m, void *v)
-- 
2.26.2

___
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel


[Devel] [PATCH vz8 2/2] x86: don't enable cpuid faults if /proc/vz/cpuid_override unused

2020-11-02 Thread Andrey Ryabinin
We don't need to enable cpuid faults if /proc/vz/cpuid_override
was never used. If task was attached to ve before a write to
'cpuid_override' it will not get cpuid faults now. It shouldn't
be a problem since the proper use of 'cpuid_override' requires
stopping all containers.

https://jira.sw.ru/browse/PSBM-121823
Signed-off-by: Andrey Ryabinin 
---
 arch/x86/kernel/cpuid_fault.c | 21 ++---
 kernel/ve/ve.c|  5 -
 2 files changed, 6 insertions(+), 20 deletions(-)

diff --git a/arch/x86/kernel/cpuid_fault.c b/arch/x86/kernel/cpuid_fault.c
index 1e8ffacc4412..cb6c2216fa8a 100644
--- a/arch/x86/kernel/cpuid_fault.c
+++ b/arch/x86/kernel/cpuid_fault.c
@@ -1,3 +1,4 @@
+#include 
 #include 
 #include 
 #include 
@@ -9,25 +10,7 @@
 #include 
 #include 
 
-struct cpuid_override_entry {
-   unsigned int op;
-   unsigned int count;
-   bool has_count;
-   unsigned int eax;
-   unsigned int ebx;
-   unsigned int ecx;
-   unsigned int edx;
-};
-
-#define MAX_CPUID_OVERRIDE_ENTRIES 16
-
-struct cpuid_override_table {
-   struct rcu_head rcu_head;
-   int size;
-   struct cpuid_override_entry entries[MAX_CPUID_OVERRIDE_ENTRIES];
-};
-
-static struct cpuid_override_table __rcu *cpuid_override __read_mostly;
+struct cpuid_override_table __rcu *cpuid_override __read_mostly;
 static DEFINE_SPINLOCK(cpuid_override_lock);
 
 static void cpuid_override_update(struct cpuid_override_table *new_table)
diff --git a/kernel/ve/ve.c b/kernel/ve/ve.c
index aad8ce69ca1f..0d4d0ab70369 100644
--- a/kernel/ve/ve.c
+++ b/kernel/ve/ve.c
@@ -9,6 +9,7 @@
  * 've.c' helper file performing VE sub-system initialization
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -801,6 +802,7 @@ static void ve_attach(struct cgroup_taskset *tset)
 {
struct cgroup_subsys_state *css;
struct task_struct *task;
+   extern struct cpuid_override_table __rcu *cpuid_override;
 
cgroup_taskset_for_each(task, css, tset) {
struct ve_struct *ve = css_to_ve(css);
@@ -816,7 +818,8 @@ static void ve_attach(struct cgroup_taskset *tset)
/* Leave parent exec domain */
task->parent_exec_id--;
 
-   set_tsk_thread_flag(task, TIF_CPUID_OVERRIDE);
+   if (cpuid_override_on())
+   set_tsk_thread_flag(task, TIF_CPUID_OVERRIDE);
task->task_ve = ve;
}
 }
-- 
2.26.2

___
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel


[Devel] [PATCH vz8 1/2] x86, cpuinfo: Fix race on parallel /proc/cpuinfo read

2020-11-02 Thread Andrey Ryabinin
If several threads read /proc/cpuinfo some can see in 'flags'
values from c->x86_capability, before __do_cpuid_fault() called
and masks applied. Fix this by forming 'flags' on stack first
and copy them in per_cpu(cpu_flags, cpu) as a last step.

https://jira.sw.ru/browse/PSBM-121823
Signed-off-by: Andrey Ryabinin 
---
 arch/x86/kernel/cpu/proc.c | 17 +
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c
index 4fe1577d5e6f..4cc2951e34fb 100644
--- a/arch/x86/kernel/cpu/proc.c
+++ b/arch/x86/kernel/cpu/proc.c
@@ -69,11 +69,11 @@ static DEFINE_PER_CPU(struct cpu_flags, cpu_flags);
 static void init_cpu_flags(void *dummy)
 {
int cpu = smp_processor_id();
-   struct cpu_flags *flags = _cpu(cpu_flags, cpu);
+   struct cpu_flags flags;
struct cpuinfo_x86 *c = _data(cpu);
unsigned int eax, ebx, ecx, edx;
 
-   memcpy(flags->val, c->x86_capability, NCAPINTS * sizeof(u32));
+   memcpy(, c->x86_capability, sizeof(flags));
 
/*
 * Clear feature bits masked using cpuid masking/faulting.
@@ -81,26 +81,27 @@ static void init_cpu_flags(void *dummy)
 
if (c->cpuid_level >= 0x0001) {
__do_cpuid_fault(0x0001, 0, , , , );
-   flags->val[4] &= ecx;
-   flags->val[0] &= edx;
+   flags.val[4] &= ecx;
+   flags.val[0] &= edx;
}
 
if (c->cpuid_level >= 0x0007) {
__do_cpuid_fault(0x0007, 0, , , , );
-   flags->val[9] &= ebx;
+   flags.val[9] &= ebx;
}
 
if ((c->extended_cpuid_level & 0x) == 0x8000 &&
c->extended_cpuid_level >= 0x8001) {
__do_cpuid_fault(0x8001, 0, , , , );
-   flags->val[6] &= ecx;
-   flags->val[1] &= edx;
+   flags.val[6] &= ecx;
+   flags.val[1] &= edx;
}
 
if (c->cpuid_level >= 0x000d) {
__do_cpuid_fault(0x000d, 1, , , , );
-   flags->val[10] &= eax;
+   flags.val[10] &= eax;
}
+   memcpy(_cpu(cpu_flags, cpu), , sizeof(flags));
 }
 
 static int show_cpuinfo(struct seq_file *m, void *v)
-- 
2.26.2

___
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel