Skip to content

Commit 0081856

Browse files
committed
Add VDSO functionality under the aarch64 architecture
1 parent beee77f commit 0081856

22 files changed

+891
-2
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,7 @@ tags
5050
CMakeLists.txt
5151
cmake-build-debug
5252
*.mk
53+
54+
# vDSO
55+
vdso_sys.os
56+
vdso.lds

components/lwp/Kconfig

+1
Original file line numberDiff line numberDiff line change
@@ -81,5 +81,6 @@ if RT_USING_LWP
8181
endif
8282

8383
rsource "terminal/Kconfig"
84+
rsource "vdso/Kconfig"
8485
endif
8586

components/lwp/SConscript

+8-2
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,16 @@ if platform in platform_file.keys(): # support platforms
2626
if arch in support_arch.keys() and cpu in support_arch[arch]:
2727
asm_path = 'arch/' + arch + '/' + cpu + '/*_' + platform_file[platform]
2828
arch_common = 'arch/' + arch + '/' + 'common/*.c'
29+
if not GetDepend('RT_USING_VDSO'):
30+
vdso_files = ['vdso_data.c', 'vdso.c']
31+
src += [f for f in Glob(arch_common) if os.path.basename(str(f)) not in vdso_files]
32+
else:
33+
src += Glob(arch_common)
2934
if not GetDepend('ARCH_MM_MMU'):
3035
excluded_files = ['ioremap.c', 'lwp_futex.c', 'lwp_mm_area.c', 'lwp_pmutex.c', 'lwp_shm.c', 'lwp_user_mm.c']
31-
src += [f for f in Glob('*.c') if os.path.basename(str(f)) not in excluded_files] + Glob(asm_path) + Glob(arch_common)
36+
src += [f for f in Glob('*.c') if os.path.basename(str(f)) not in excluded_files] + Glob(asm_path)
3237
else:
33-
src += Glob('*.c') + Glob(asm_path) + Glob(arch_common)
38+
src += Glob('*.c') + Glob(asm_path)
3439
src += Glob('arch/' + arch + '/' + cpu + '/*.c')
3540
CPPPATH = [cwd]
3641
CPPPATH += [cwd + '/arch/' + arch + '/' + cpu]
@@ -43,4 +48,5 @@ CPPPATH += ['./terminal/']
4348

4449
group = DefineGroup('lwP', src, depend = ['RT_USING_SMART'], CPPPATH = CPPPATH)
4550

51+
group = group + SConscript(os.path.join('vdso', 'SConscript'))
4652
Return('group')
+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/*
2+
* Copyright (c) 2006-2024 RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2024-07-04 rcitach init ver.
9+
*/
10+
11+
#include <rtthread.h>
12+
#include <mmu.h>
13+
#include <gtimer.h>
14+
#include <lwp_user_mm.h>
15+
16+
#include "vdso.h"
17+
#include "vdso_datapage.h"
18+
#define DBG_TAG "vdso"
19+
#define DBG_LVL DBG_INFO
20+
#include <rtdbg.h>
21+
22+
enum vdso_abi {
23+
VDSO_ABI_AA64,
24+
};
25+
enum vvar_pages {
26+
VVAR_DATA_PAGE_OFFSET,
27+
VVAR_TIMENS_PAGE_OFFSET,
28+
VVAR_NR_PAGES,
29+
};
30+
struct vdso_abi_info {
31+
const char *name;
32+
const char *vdso_code_start;
33+
const char *vdso_code_end;
34+
unsigned long vdso_pages;
35+
36+
};
37+
38+
static struct vdso_abi_info vdso_info[] = {
39+
[VDSO_ABI_AA64] = {
40+
.name = "vdso_aarch64",
41+
.vdso_code_start = __vdso_text_start,
42+
.vdso_code_end = __vdso_text_end,
43+
},
44+
};
45+
46+
static union {
47+
struct vdso_data data[CS_BASES];
48+
uint8_t page[ARCH_PAGE_SIZE];
49+
} vdso_data_store __page_aligned_data;
50+
struct vdso_data *vdso_data = vdso_data_store.data;
51+
int init_ret_flag = RT_EOK;
52+
53+
static int __setup_additional_pages(enum vdso_abi abi, struct rt_lwp *lwp)
54+
{
55+
RT_ASSERT(lwp != RT_NULL);
56+
57+
int ret;
58+
void *vdso_base = RT_NULL;
59+
unsigned long vdso_data_len, vdso_text_len;
60+
61+
vdso_data_len = VVAR_NR_PAGES * ARCH_PAGE_SIZE;
62+
vdso_text_len = vdso_info[abi].vdso_pages << ARCH_PAGE_SHIFT;
63+
64+
vdso_base = lwp_map_user_phy(lwp, RT_NULL, rt_kmem_v2p((void *)vdso_data), vdso_data_len, 0);
65+
if(vdso_base != RT_NULL)
66+
{
67+
ret = RT_EOK;
68+
}
69+
else
70+
{
71+
ret = RT_ERROR;
72+
}
73+
vdso_base += vdso_data_len;
74+
vdso_base = lwp_map_user_phy(lwp, vdso_base, rt_kmem_v2p((void *)vdso_info[abi].vdso_code_start), vdso_text_len, 0);
75+
76+
lwp->vdso_vbase = vdso_base;
77+
return ret;
78+
}
79+
80+
int arch_setup_additional_pages(struct rt_lwp *lwp)
81+
{
82+
int ret;
83+
if (init_ret_flag != RT_EOK) return -RT_ERROR;
84+
ret = __setup_additional_pages(VDSO_ABI_AA64, lwp);
85+
86+
return ret;
87+
}
88+
89+
static void __initdata(void)
90+
{
91+
struct tm time_vdso = SOFT_RTC_VDSOTIME_DEFAULT;
92+
vdso_data->realtime_initdata = timegm(&time_vdso);
93+
}
94+
95+
int validate_vdso_elf(void)
96+
{
97+
if (rt_memcmp(vdso_info[VDSO_ABI_AA64].vdso_code_start, ELF_HEAD, ELF_HEAD_LEN)) {
98+
LOG_E("vDSO is not a valid ELF object!");
99+
init_ret_flag = -RT_ERROR;
100+
return -RT_ERROR;
101+
}
102+
vdso_info[VDSO_ABI_AA64].vdso_pages = (
103+
vdso_info[VDSO_ABI_AA64].vdso_code_end -
104+
vdso_info[VDSO_ABI_AA64].vdso_code_start) >>
105+
ARCH_PAGE_SHIFT;
106+
107+
__initdata();
108+
return RT_EOK;
109+
}
110+
INIT_COMPONENT_EXPORT(validate_vdso_elf);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright (c) 2006-2024 RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2024-07-04 rcitach init ver.
9+
*/
10+
11+
#include <rtthread.h>
12+
#include <gtimer.h>
13+
#include <ktime.h>
14+
#include <time.h>
15+
#include <vdso_datapage.h>
16+
#include <vdso_data.h>
17+
18+
void rt_vdso_update_glob_time(void)
19+
{
20+
struct vdso_data *vdata = get_k_vdso_data();
21+
struct timespec *vdso_ts;
22+
uint64_t initdata = vdata->realtime_initdata;
23+
rt_vdso_write_begin(vdata);
24+
25+
vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_REALTIME];
26+
rt_ktime_boottime_get_ns(vdso_ts);
27+
vdso_ts->tv_sec = initdata + vdso_ts->tv_sec;
28+
29+
vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_MONOTONIC];
30+
rt_ktime_boottime_get_ns(vdso_ts);
31+
32+
vdata->cycle_last = rt_hw_get_cntpct_val();
33+
rt_vdso_write_end(vdata);
34+
}

components/lwp/lwp.h

+5
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,10 @@ struct rt_lwp
197197
unsigned int asid;
198198
#endif
199199
struct rusage rt_rusage;
200+
201+
#ifdef RT_USING_VDSO
202+
void *vdso_vbase;
203+
#endif
200204
};
201205

202206

@@ -373,6 +377,7 @@ void lwp_jobctrl_on_exit(struct rt_lwp *lwp);
373377
#define AT_RANDOM 25
374378
#define AT_HWCAP2 26
375379
#define AT_EXECFN 31
380+
#define AT_SYSINFO_EHDR 33
376381

377382
struct process_aux_item
378383
{

components/lwp/lwp_elf.c

+15
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@
2525
#include <lwp_user_mm.h>
2626
#endif
2727

28+
#ifdef RT_USING_VDSO
29+
#include <vdso.h>
30+
#endif
31+
2832
#define DBG_TAG "load.elf"
2933
#ifdef ELF_DEBUG_ENABLE
3034
#define DBG_LVL DBG_LOG
@@ -607,6 +611,17 @@ static int elf_aux_fill(elf_load_info_t *load_info)
607611
ELF_AUX_ENT(aux_info, AT_CLKTCK, 0);
608612
ELF_AUX_ENT(aux_info, AT_SECURE, 0);
609613

614+
#ifdef RT_USING_VDSO
615+
if(RT_EOK == arch_setup_additional_pages(load_info->lwp))
616+
{
617+
ELF_AUX_ENT(aux_info, AT_SYSINFO_EHDR, (size_t)load_info->lwp->vdso_vbase);
618+
}
619+
else
620+
{
621+
LOG_W("vdso map error,VDSO currently only supports aarch64 architecture!");
622+
}
623+
#endif
624+
610625
return 0;
611626
}
612627

components/lwp/vdso/Kconfig

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
menuconfig RT_USING_VDSO
2+
bool "vDSO"
3+
default y
4+
depends on RT_USING_SMART
5+

components/lwp/vdso/SConscript

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import os
2+
import rtconfig
3+
import subprocess
4+
from building import *
5+
Import('RTT_ROOT')
6+
7+
group = []
8+
9+
cwd = GetCurrentDir()
10+
CPPPATH = [cwd, cwd + "/kernel"]
11+
12+
if not GetDepend(['RT_USING_VDSO']):
13+
Return('group')
14+
15+
if rtconfig.ARCH != "aarch64":
16+
src = Glob('*.c')
17+
group = DefineGroup('VDSO', src, depend = ['RT_USING_SMART','RT_USING_VDSO'], CPPPATH = CPPPATH)
18+
Return('group')
19+
20+
list = os.listdir(cwd)
21+
src = Glob('kernel/*.c')
22+
src +=Glob('kernel/*.S')
23+
24+
if not os.path.exists(cwd + "/user/vdso.lds"):
25+
Preprocessing("user/vdso.lds.S", ".lds", CPPPATH=[cwd])
26+
27+
#aarch64 vdso xmake
28+
# vdso_file = os.path.join(cwd, 'usr', 'xmake.lua')
29+
# command = ["xmake", "-F", vdso_file]
30+
# clean = ["xmake", "clean"]
31+
32+
vdso_file = os.path.join(cwd, 'user', 'SConstruct')
33+
command = ["scons", "-f", vdso_file]
34+
clean = ["scons", "-f", vdso_file, "--clean"]
35+
36+
if not GetOption('clean'):
37+
result = subprocess.run(command)
38+
else:
39+
result = subprocess.run(clean)
40+
41+
if result.returncode == 0:
42+
print("Command executed successfully")
43+
else:
44+
print("Command failed with exit code:", result.returncode)
45+
exit(1)
46+
47+
group = DefineGroup('VDSO', src, depend = ['RT_USING_SMART','RT_USING_VDSO'], CPPPATH = CPPPATH)
48+
Return('group')

components/lwp/vdso/kernel/vdso.h

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright (c) 2006-2024 RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2024-07-04 rcitach init ver.
9+
*/
10+
11+
#ifndef _VDSO_H
12+
#define _VDSO_H
13+
14+
#include <lwp.h>
15+
#include <mmu.h>
16+
#include <vdso_config.h>
17+
#include <vdso_datapage.h>
18+
19+
#ifdef __cplusplus
20+
extern "C" {
21+
#endif
22+
23+
extern char __vdso_text_start[];
24+
extern char __vdso_text_end[];
25+
26+
#define ELF_HEAD "\177ELF"
27+
#define ELF_HEAD_LEN 4
28+
#define MAX_PAGES 5
29+
30+
#define __page_aligned_data __attribute__((section(".data.vdso.datapage"))) __attribute__((aligned(VDSO_PAGE_SIZE)))
31+
32+
int arch_setup_additional_pages(struct rt_lwp *lwp);
33+
void rt_vdso_update_glob_time(void);
34+
35+
#ifdef __cplusplus
36+
}
37+
#endif
38+
39+
#endif /* _VDSO_H */
+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright (c) 2006-2024 RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2024-07-04 rcitach init ver.
9+
*/
10+
11+
#ifndef _VDSO_KDATA_H
12+
#define _VDSO_KDATA_H
13+
14+
#include <rtatomic.h>
15+
#include <vdso_datapage.h>
16+
17+
#ifdef __cplusplus
18+
extern "C" {
19+
#endif
20+
21+
extern struct vdso_data *vdso_data;
22+
23+
rt_inline
24+
struct vdso_data *_get_k_vdso_data(void)
25+
{
26+
return vdso_data;
27+
}
28+
#define get_k_vdso_data _get_k_vdso_data
29+
30+
rt_inline
31+
void rt_vdso_write_begin(struct vdso_data *vd)
32+
{
33+
rt_atomic_add(&vd[CS_HRES_COARSE].seq, 1);
34+
rt_atomic_add(&vd[CS_RAW].seq, 1);
35+
}
36+
37+
rt_inline
38+
void rt_vdso_write_end(struct vdso_data *vd)
39+
{
40+
rt_atomic_add(&vd[CS_HRES_COARSE].seq, 1);
41+
rt_atomic_add(&vd[CS_RAW].seq, 1);
42+
}
43+
44+
#ifdef __cplusplus
45+
}
46+
#endif
47+
48+
#endif /* _VDSO_KDATA_H */
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Copyright (c) 2006-2023, RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2024-07-04 rcitach init ver.
9+
*/
10+
11+
#include <vdso_config.h>
12+
13+
.globl __vdso_text_start, __vdso_text_end
14+
.section .rodata
15+
.balign VDSO_PAGE_SIZE
16+
__vdso_text_start:
17+
.incbin VDSO_PATH
18+
.balign VDSO_PAGE_SIZE
19+
__vdso_text_end:
20+
21+
.previous

0 commit comments

Comments
 (0)