~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/loongarch/kernel/vdso.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /arch/loongarch/kernel/vdso.c (Architecture m68k) and /arch/sparc/kernel/vdso.c (Architecture sparc)


  1 // SPDX-License-Identifier: GPL-2.0            << 
  2 /*                                                  1 /*
  3  * Author: Huacai Chen <chenhuacai@loongson.cn !!   2  *  Copyright (C) 2001 Andrea Arcangeli <andrea@suse.de> SuSE
  4  * Copyright (C) 2020-2022 Loongson Technology !!   3  *  Copyright 2003 Andi Kleen, SuSE Labs.
                                                   >>   4  *
                                                   >>   5  *  Thanks to hpa@transmeta.com for some useful hint.
                                                   >>   6  *  Special thanks to Ingo Molnar for his early experience with
                                                   >>   7  *  a different vsyscall implementation for Linux/IA32 and for the name.
  5  */                                                 8  */
  6                                                     9 
  7 #include <linux/binfmts.h>                     !!  10 #include <linux/time.h>
  8 #include <linux/elf.h>                         << 
  9 #include <linux/err.h>                         << 
 10 #include <linux/init.h>                        << 
 11 #include <linux/ioport.h>                      << 
 12 #include <linux/kernel.h>                      << 
 13 #include <linux/mm.h>                          << 
 14 #include <linux/random.h>                      << 
 15 #include <linux/sched.h>                       << 
 16 #include <linux/slab.h>                        << 
 17 #include <linux/time_namespace.h>              << 
 18 #include <linux/timekeeper_internal.h>             11 #include <linux/timekeeper_internal.h>
 19                                                    12 
 20 #include <asm/page.h>                          !!  13 #include <asm/vvar.h>
 21 #include <asm/vdso.h>                          << 
 22 #include <vdso/helpers.h>                      << 
 23 #include <vdso/vsyscall.h>                     << 
 24 #include <vdso/datapage.h>                     << 
 25 #include <generated/vdso-offsets.h>            << 
 26                                                << 
 27 extern char vdso_start[], vdso_end[];          << 
 28                                                << 
 29 /* Kernel-provided data used by the VDSO. */   << 
 30 static union vdso_data_store generic_vdso_data << 
 31                                                << 
 32 static union {                                 << 
 33         u8 page[LOONGARCH_VDSO_DATA_SIZE];     << 
 34         struct loongarch_vdso_data vdata;      << 
 35 } loongarch_vdso_data __page_aligned_data;     << 
 36                                                << 
 37 struct vdso_data *vdso_data = generic_vdso_dat << 
 38 struct vdso_pcpu_data *vdso_pdata = loongarch_ << 
 39 struct vdso_rng_data *vdso_rng_data = &loongar << 
 40                                                << 
 41 static int vdso_mremap(const struct vm_special << 
 42 {                                              << 
 43         current->mm->context.vdso = (void *)(n << 
 44                                                << 
 45         return 0;                              << 
 46 }                                              << 
 47                                                    14 
 48 static vm_fault_t vvar_fault(const struct vm_s !!  15 void update_vsyscall_tz(void)
 49                              struct vm_area_st << 
 50 {                                                  16 {
 51         unsigned long pfn;                     !!  17         if (unlikely(vvar_data == NULL))
 52         struct page *timens_page = find_timens !!  18                 return;
 53                                                << 
 54         switch (vmf->pgoff) {                  << 
 55         case VVAR_GENERIC_PAGE_OFFSET:         << 
 56                 if (!timens_page)              << 
 57                         pfn = sym_to_pfn(vdso_ << 
 58                 else                           << 
 59                         pfn = page_to_pfn(time << 
 60                 break;                         << 
 61 #ifdef CONFIG_TIME_NS                          << 
 62         case VVAR_TIMENS_PAGE_OFFSET:          << 
 63                 /*                             << 
 64                  * If a task belongs to a time << 
 65                  * VVAR is mapped with the VVA << 
 66                  * VVAR page is mapped with th << 
 67                  * See also the comment near t << 
 68                  */                            << 
 69                 if (!timens_page)              << 
 70                         return VM_FAULT_SIGBUS << 
 71                 else                           << 
 72                         pfn = sym_to_pfn(vdso_ << 
 73                 break;                         << 
 74 #endif /* CONFIG_TIME_NS */                    << 
 75         case VVAR_LOONGARCH_PAGES_START ... VV << 
 76                 pfn = sym_to_pfn(&loongarch_vd << 
 77                 break;                         << 
 78         default:                               << 
 79                 return VM_FAULT_SIGBUS;        << 
 80         }                                      << 
 81                                                    19 
 82         return vmf_insert_pfn(vma, vmf->addres !!  20         vvar_data->tz_minuteswest = sys_tz.tz_minuteswest;
                                                   >>  21         vvar_data->tz_dsttime = sys_tz.tz_dsttime;
 83 }                                                  22 }
 84                                                    23 
 85 struct loongarch_vdso_info vdso_info = {       !!  24 void update_vsyscall(struct timekeeper *tk)
 86         .vdso = vdso_start,                    << 
 87         .code_mapping = {                      << 
 88                 .name = "[vdso]",              << 
 89                 .mremap = vdso_mremap,         << 
 90         },                                     << 
 91         .data_mapping = {                      << 
 92                 .name = "[vvar]",              << 
 93                 .fault = vvar_fault,           << 
 94         },                                     << 
 95         .offset_sigreturn = vdso_offset_sigret << 
 96 };                                             << 
 97                                                << 
 98 static int __init init_vdso(void)              << 
 99 {                                                  25 {
100         unsigned long i, cpu, pfn;             !!  26         struct vvar_data *vdata = vvar_data;
101                                                    27 
102         BUG_ON(!PAGE_ALIGNED(vdso_info.vdso)); !!  28         if (unlikely(vdata == NULL))
                                                   >>  29                 return;
103                                                    30 
104         for_each_possible_cpu(cpu)             !!  31         vvar_write_begin(vdata);
105                 vdso_pdata[cpu].node = cpu_to_ !!  32         vdata->vclock_mode = tk->tkr_mono.clock->archdata.vclock_mode;
                                                   >>  33         vdata->clock.cycle_last = tk->tkr_mono.cycle_last;
                                                   >>  34         vdata->clock.mask = tk->tkr_mono.mask;
                                                   >>  35         vdata->clock.mult = tk->tkr_mono.mult;
                                                   >>  36         vdata->clock.shift = tk->tkr_mono.shift;
106                                                    37 
107         vdso_info.size = PAGE_ALIGN(vdso_end - !!  38         vdata->wall_time_sec = tk->xtime_sec;
108         vdso_info.code_mapping.pages =         !!  39         vdata->wall_time_snsec = tk->tkr_mono.xtime_nsec;
109                 kcalloc(vdso_info.size / PAGE_ << 
110                                                    40 
111         pfn = __phys_to_pfn(__pa_symbol(vdso_i !!  41         vdata->monotonic_time_sec = tk->xtime_sec +
112         for (i = 0; i < vdso_info.size / PAGE_ !!  42                                     tk->wall_to_monotonic.tv_sec;
113                 vdso_info.code_mapping.pages[i !!  43         vdata->monotonic_time_snsec = tk->tkr_mono.xtime_nsec +
                                                   >>  44                                       (tk->wall_to_monotonic.tv_nsec <<
                                                   >>  45                                        tk->tkr_mono.shift);
114                                                    46 
115         return 0;                              !!  47         while (vdata->monotonic_time_snsec >=
116 }                                              !!  48                (((u64)NSEC_PER_SEC) << tk->tkr_mono.shift)) {
117 subsys_initcall(init_vdso);                    !!  49                 vdata->monotonic_time_snsec -=
118                                                !!  50                                 ((u64)NSEC_PER_SEC) << tk->tkr_mono.shift;
119 #ifdef CONFIG_TIME_NS                          !!  51                 vdata->monotonic_time_sec++;
120 struct vdso_data *arch_get_vdso_data(void *vva << 
121 {                                              << 
122         return (struct vdso_data *)(vvar_page) << 
123 }                                              << 
124                                                << 
125 /*                                             << 
126  * The vvar mapping contains data for a specif << 
127  * task changes namespace we must unmap its vv << 
128  * Subsequent faults will map in data for the  << 
129  *                                             << 
130  * For more details see timens_setup_vdso_data << 
131  */                                            << 
132 int vdso_join_timens(struct task_struct *task, << 
133 {                                              << 
134         struct mm_struct *mm = task->mm;       << 
135         struct vm_area_struct *vma;            << 
136                                                << 
137         VMA_ITERATOR(vmi, mm, 0);              << 
138                                                << 
139         mmap_read_lock(mm);                    << 
140         for_each_vma(vmi, vma) {               << 
141                 if (vma_is_special_mapping(vma << 
142                         zap_vma_pages(vma);    << 
143         }                                          52         }
144         mmap_read_unlock(mm);                  << 
145                                                    53 
146         return 0;                              !!  54         vdata->wall_time_coarse_sec = tk->xtime_sec;
147 }                                              !!  55         vdata->wall_time_coarse_nsec =
148 #endif                                         !!  56                         (long)(tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift);
149                                                    57 
150 static unsigned long vdso_base(void)           !!  58         vdata->monotonic_time_coarse_sec =
151 {                                              !!  59                 vdata->wall_time_coarse_sec + tk->wall_to_monotonic.tv_sec;
152         unsigned long base = STACK_TOP;        !!  60         vdata->monotonic_time_coarse_nsec =
                                                   >>  61                 vdata->wall_time_coarse_nsec + tk->wall_to_monotonic.tv_nsec;
153                                                    62 
154         if (current->flags & PF_RANDOMIZE) {   !!  63         while (vdata->monotonic_time_coarse_nsec >= NSEC_PER_SEC) {
155                 base += get_random_u32_below(V !!  64                 vdata->monotonic_time_coarse_nsec -= NSEC_PER_SEC;
156                 base = PAGE_ALIGN(base);       !!  65                 vdata->monotonic_time_coarse_sec++;
157         }                                          66         }
158                                                    67 
159         return base;                           !!  68         vvar_write_end(vdata);
160 }                                              << 
161                                                << 
162 int arch_setup_additional_pages(struct linux_b << 
163 {                                              << 
164         int ret;                               << 
165         unsigned long size, data_addr, vdso_ad << 
166         struct mm_struct *mm = current->mm;    << 
167         struct vm_area_struct *vma;            << 
168         struct loongarch_vdso_info *info = cur << 
169                                                << 
170         if (mmap_write_lock_killable(mm))      << 
171                 return -EINTR;                 << 
172                                                << 
173         /*                                     << 
174          * Determine total area size. This inc << 
175          * and the data pages.                 << 
176          */                                    << 
177         size = VVAR_SIZE + info->size;         << 
178                                                << 
179         data_addr = get_unmapped_area(NULL, vd << 
180         if (IS_ERR_VALUE(data_addr)) {         << 
181                 ret = data_addr;               << 
182                 goto out;                      << 
183         }                                      << 
184                                                << 
185         vma = _install_special_mapping(mm, dat << 
186                                        VM_READ << 
187                                        &info-> << 
188         if (IS_ERR(vma)) {                     << 
189                 ret = PTR_ERR(vma);            << 
190                 goto out;                      << 
191         }                                      << 
192                                                << 
193         vdso_addr = data_addr + VVAR_SIZE;     << 
194         vma = _install_special_mapping(mm, vds << 
195                                        VM_READ << 
196                                        &info-> << 
197         if (IS_ERR(vma)) {                     << 
198                 ret = PTR_ERR(vma);            << 
199                 goto out;                      << 
200         }                                      << 
201                                                << 
202         mm->context.vdso = (void *)vdso_addr;  << 
203         ret = 0;                               << 
204                                                << 
205 out:                                           << 
206         mmap_write_unlock(mm);                 << 
207         return ret;                            << 
208 }                                                  69 }
209                                                    70 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php