The commit is pushed to "branch-rh9-5.14.vz9.1.x-ovz" and will appear at 
https://src.openvz.org/scm/ovz/vzkernel.git
after ark-5.14
------>
commit c8c1127af9b178d216c9bc31f6a9101084905b14
Author: Andrey Ryabinin <ryabinin....@gmail.com>
Date:   Fri Oct 1 19:38:47 2021 +0300

    ia32: add 32-bit vdso virtualization.
    
    Similarly to the 64-bit vdso, make 32-bit vdso mapping per-ve.
    This will allow per container modification of the linux version
    in .note section of vdso and monotonic time.
    
    https://jira.sw.ru/browse/PSBM-121668
    Signed-off-by: Andrey Ryabinin <aryabi...@virtuozzo.com>
    
    (cherry-picked from vz8 commit b21e7696d61f ("ia32: add 32-bit vdso
    virtualization."))
    
    Signed-off-by: Nikita Yushchenko <nikita.yushche...@virtuozzo.com>
---
 arch/x86/entry/vdso/vma.c    |  4 ++--
 arch/x86/kernel/process_64.c |  2 +-
 include/linux/ve.h           |  1 +
 kernel/ve/ve.c               | 36 ++++++++++++++++++++++--------------
 4 files changed, 26 insertions(+), 17 deletions(-)

diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c
index e58417321af2..4d731f37ff6a 100644
--- a/arch/x86/entry/vdso/vma.c
+++ b/arch/x86/entry/vdso/vma.c
@@ -74,7 +74,7 @@ static void vdso_fix_landing(const struct vdso_image *image,
                struct vm_area_struct *new_vma)
 {
 #if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION
-       if (in_ia32_syscall() && image == &vdso_image_32) {
+       if (in_ia32_syscall() && image == get_exec_env()->vdso_32) {
                struct pt_regs *regs = current_pt_regs();
                unsigned long vdso_land = image->sym_int80_landing_pad;
                unsigned long old_land_addr = vdso_land +
@@ -382,7 +382,7 @@ static int load_vdso32(void)
        if (vdso32_enabled != 1)  /* Other values all mean "disabled" */
                return 0;
 
-       return map_vdso(&vdso_image_32, 0);
+       return map_vdso(get_exec_env()->vdso_32, 0);
 }
 #endif
 
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 206cdb4793f5..56f864581cc0 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -826,7 +826,7 @@ long do_arch_prctl_64(struct task_struct *task, int option, 
unsigned long arg2)
 # endif
 # if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION
        case ARCH_MAP_VDSO_32:
-               return prctl_map_vdso(&vdso_image_32, arg2);
+               return prctl_map_vdso(get_exec_env()->vdso_32, arg2);
 # endif
        case ARCH_MAP_VDSO_64:
                return prctl_map_vdso(get_exec_env()->vdso_64, arg2);
diff --git a/include/linux/ve.h b/include/linux/ve.h
index 741867427f57..57e6e440bc0f 100644
--- a/include/linux/ve.h
+++ b/include/linux/ve.h
@@ -74,6 +74,7 @@ struct ve_struct {
        struct task_struct      *umh_task;
 
        struct vdso_image       *vdso_64;
+       struct vdso_image       *vdso_32;
 };
 
 #define VE_MEMINFO_DEFAULT     1       /* default behaviour */
diff --git a/kernel/ve/ve.c b/kernel/ve/ve.c
index 6a3248efaf07..0dabbb544898 100644
--- a/kernel/ve/ve.c
+++ b/kernel/ve/ve.c
@@ -56,6 +56,7 @@ struct ve_struct ve0 = {
 #endif
        .meminfo_val            = VE_MEMINFO_SYSTEM,
        .vdso_64                = (struct vdso_image*)&vdso_image_64,
+       .vdso_32                = (struct vdso_image*)&vdso_image_32,
 };
 EXPORT_SYMBOL(ve0);
 
@@ -563,13 +564,12 @@ void ve_exit_ns(struct pid_namespace *pid_ns)
        up_write(&ve->op_sem);
 }
 
-static int copy_vdso(struct ve_struct *ve)
+static int copy_vdso(struct vdso_image **vdso_dst, const struct vdso_image 
*vdso_src)
 {
-       const struct vdso_image *vdso_src = &vdso_image_64;
        struct vdso_image *vdso;
        void *vdso_data;
 
-       if (ve->vdso_64)
+       if (*vdso_dst)
                return 0;
 
        vdso = kmemdup(vdso_src, sizeof(*vdso), GFP_KERNEL);
@@ -586,10 +586,22 @@ static int copy_vdso(struct ve_struct *ve)
 
        vdso->data = vdso_data;
 
-       ve->vdso_64 = vdso;
+       *vdso_dst = vdso;
        return 0;
 }
 
+static void ve_free_vdso(struct ve_struct *ve)
+{
+       if (ve->vdso_64 && ve->vdso_64 != &vdso_image_64) {
+               free_pages_exact(ve->vdso_64->data, ve->vdso_64->size);
+               kfree(ve->vdso_64);
+       }
+       if (ve->vdso_32 && ve->vdso_32 != &vdso_image_32) {
+               free_pages_exact(ve->vdso_32->data, ve->vdso_32->size);
+               kfree(ve->vdso_32);
+       }
+}
+
 static struct cgroup_subsys_state *ve_create(struct cgroup_subsys_state 
*parent_css)
 {
        struct ve_struct *ve = &ve0;
@@ -623,7 +635,11 @@ static struct cgroup_subsys_state *ve_create(struct 
cgroup_subsys_state *parent_
        if (err)
                goto err_log;
 
-       err = copy_vdso(ve);
+       err = copy_vdso(&ve->vdso_64, &vdso_image_64);
+       if (err)
+               goto err_vdso;
+
+       err = copy_vdso(&ve->vdso_32, &vdso_image_32);
        if (err)
                goto err_vdso;
 
@@ -634,6 +650,7 @@ static struct cgroup_subsys_state *ve_create(struct 
cgroup_subsys_state *parent_
        return &ve->css;
 
 err_vdso:
+       ve_free_vdso(ve);
        ve_log_destroy(ve);
 err_log:
        free_percpu(ve->sched_lat_ve.cur);
@@ -673,15 +690,6 @@ static void ve_offline(struct cgroup_subsys_state *css)
        ve->ve_name = NULL;
 }
 
-static void ve_free_vdso(struct ve_struct *ve)
-{
-       if (ve->vdso_64 == &vdso_image_64)
-               return;
-
-       free_pages_exact(ve->vdso_64->data, ve->vdso_64->size);
-       kfree(ve->vdso_64);
-}
-
 static void ve_destroy(struct cgroup_subsys_state *css)
 {
        struct ve_struct *ve = css_to_ve(css);
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to