The commit is pushed to "branch-rh8-4.18.0-193.6.3.vz8.4.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git after rh8-4.18.0-193.6.3.vz8.4.14 ------> commit bf217233180e2f0c74e2ad92bea5f102f27681f7 Author: Andrey Ryabinin <aryabi...@virtuozzo.com> Date: Thu Oct 29 14:17:09 2020 +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> --- arch/x86/entry/vdso/vma.c | 4 ++-- arch/x86/kernel/process_64.c | 2 +- include/linux/ve.h | 1 + kernel/ve/ve.c | 35 +++++++++++++++++++++-------------- 4 files changed, 25 insertions(+), 17 deletions(-) diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c index c48deffc1473..538c6730f436 100644 --- a/arch/x86/entry/vdso/vma.c +++ b/arch/x86/entry/vdso/vma.c @@ -56,7 +56,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 + @@ -281,7 +281,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 a010d4b9d126..dddd22215141 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -686,7 +686,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 1c37b81321df..fe14d237b37d 100644 --- a/include/linux/ve.h +++ b/include/linux/ve.h @@ -95,6 +95,7 @@ struct ve_struct { struct cn_private *cn; #endif 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 6cc31fae5b1d..9bf1515a6c3a 100644 --- a/kernel/ve/ve.c +++ b/kernel/ve/ve.c @@ -58,6 +58,7 @@ struct ve_struct ve0 = { .netns_max_nr = INT_MAX, .meminfo_val = VE_MEMINFO_SYSTEM, .vdso_64 = (struct vdso_image*)&vdso_image_64, + .vdso_32 = (struct vdso_image*)&vdso_image_32, }; EXPORT_SYMBOL(ve0); @@ -540,13 +541,12 @@ static __u64 ve_setup_iptables_mask(__u64 init_mask) } #endif -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); @@ -563,10 +563,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) { + kfree(ve->vdso_64->data); + kfree(ve->vdso_64); + } + if (ve->vdso_32 && ve->vdso_32 != &vdso_image_32) { + kfree(ve->vdso_32->data); + kfree(ve->vdso_32); + } +} + static struct cgroup_subsys_state *ve_create(struct cgroup_subsys_state *parent_css) { struct ve_struct *ve = &ve0; @@ -592,7 +604,10 @@ static struct cgroup_subsys_state *ve_create(struct cgroup_subsys_state *parent_ if (err) goto err_log; - if (copy_vdso(ve)) + if (copy_vdso(&ve->vdso_64, &vdso_image_64)) + goto err_vdso; + + if (copy_vdso(&ve->vdso_32, &vdso_image_32)) goto err_vdso; ve->features = VE_FEATURES_DEF; @@ -619,6 +634,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); @@ -658,15 +674,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; - - kfree(ve->vdso_64->data); - 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