问题标签 [vdso]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
linux - time() 不使用 vdso?
我写了一个程序,使用 time() 函数,
我gdb的时候:</p>
我们可以看到 time() 使用 vsyscall,而不使用 vdso,为什么?
我还测试了 gettimeofday() ,它使用 vdso ...
linux - 如何在 vvar.h 中为我的新 VSDO 函数正确创建一个新变量?
我正在尝试vvar.h
在我的新 VDSO 函数附近声明一个新变量并定义它。这样我就可以在我的 vdso 函数中使用这个变量。
我有一个关于 VVar 的问题。根据 中的描述arch/x86/include/asm/vvar.h
,当我在这里声明一个新变量为DECLARE_VVAR(0, int, count)
时,我应该使用DEFINE_VVAR(type, name)
在其他地方定义这个变量。
问题是在我在其他地方定义了这个变量之后,比如DEFINE_VVAR(int, count)
,当我试图为这个变量分配一个整数值时count
,它失败了。这是因为在内核版本 5.2#define DEFINE_VVAR(type, name)
更改#define DEFINE_VVAR(type, name) type name
为#define DEFINE_VVAR(type, name) type name[CS_BASES]
. 现在这个变量count
是一个整数数组而不是整数类型。因此我不能给它分配一个整数值。你知道如何解决吗?
VVAR.h:https ://elixir.bootlin.com/linux/v5.12/source/arch/x86/include/asm/vvar.h#L43
c - 如何修改 vdso 变量(vvar)?
最近我正在研究linux中的vdso。我试图修改vvar
部分中的数据,但失败了。以下是我尝试过的。
根据lwn描述,有两个地址vvar
:
第一个是常规内核空间地址,其值大于 PAGE_OFFSET。如果您查看 System.map 文件,您会发现该符号的地址类似于 ffffffff81c76080。
第二个地址位于称为“vvar 页面”的区域中。该页面的基地址(VVAR_ADDRESS)在内核中定义为 0xffffffffff5ff000,接近 64 位地址空间的末尾。此页面对用户空间代码只读。
通过首地址修改:通过查看_vdso_data
in的地址很容易找到首地址/boot/System.map-kernel-version
。获得地址后,我在内核模块中修改了它的成员(__unused
)(因此,没有权限问题)。然后,我检查了__unused
来自用户空间的程序,它仍然存在0
,这意味着我未能从内核空间修改它。
通过第二地址修改:第二地址可以通过辅助向量找到。得到 的地址后vdso
,就可以找到vvar
section。我将此地址传递给内核模块并修改其成员__unused
。发生错误,显示权限错误问题。(原因应该vvar
是只读内存,检查通过cat /proc/pid/maps
)
我认为第一种方法几乎是解决方案,但似乎vvar
该地址并未映射到所有进程vvar
部分。有什么想法吗?提前致谢。
[编辑]:第一种方法更接近解决方案。我修改了cr0位,从而允许写入。即使我成功编写它,它仍然无法从 linux 内核中读取(通过获取 vdso_data__arch_get_k_vdso_data
并访问我之前在用户空间 + 内核模块中修改的成员)
time - How bad can the vDSO affect time()?
I have processes running on 10 computers which I expect to run in unison within about 30 ms.
In order to implement that feat, I (try to) synchronize the computers by sending a tick message to all the computers. Then I use a wait to for certain date which is the next 30 ms mark (so at a given second S + N × 30 ms).
For the sleep, I use the following command:
For the synchronization, however, I determine S by getting that tick message mentioned above comparing a timestamp in the tick. To do so, I use the time()
function like so:
Out of the 10 computers, there is nearly always 1 or 2 which are visually off by much more than 30ms. I would expect an error of ±30ms (while playing a video, this is equivalent to 1 frame at 30 fps—i.e. one frame early or one frame late instead of being right on time; as it stands, I have computers that are nearly 1 second off even though I'm supposed to re-align their timing every 30ms).
Note: I know that the software is not running so slowly that it can't do everything it needs to do in 30ms; I have counters which I display and the count is correct (i.e. 31 hits per second).
Could it be that there is a bug in the vDSO implementation of time(2)
compared to other time functions (a.k.a. clock_gettime(2)
) that it could give me a precision discrepancy of up to 1 sec. instead of a few ms?
P.S.: I'm running on NVidia Jetson Xavier computers based on ARM 64. So that specific implementation would be concerned, not the Intel based Linux Kernel.
Extra Note: I have ntpd
running and the difference in time between all the computers is usually under 0.3 ms:
The delay, 0.217, represents the maximum discrepancy between those machines (one of which is the master clock, a.k.a. 10.0.2.1). The only pool
command I put in the slave machines is:
to actually make sure all the computers use the same clock.
c - 如何使用系统调用更改 vDSO 内容
我正在尝试实现一个syscall
能够x86
修改vDSO
. 鉴于vDSO
内容对于用户空间是只读的,我相信 asyscall
是需要的。否则会导致分段错误。但是,我目前无法成功。
我的计划:
系统调用kernel/sys.c
将syscall
读取在_vdso_data
中声明arch/x86/include/asm/vvar.h
和定义的内容arch/x86/include/asm/vdso/vsyscall.h
。然后它将变量修改为__unused
用户输入的一些数字。
vDSO 在arch/x86/entry/vdso/vclock_gettime.c
我知道在时序函数中定义与时间无关的东西是个坏主意,但这是我现在正在测试的。该__vdso_query()
函数将读取数据并返回__unused
变量的值。
测试计划
预期成绩
我想在返回0
之前syscall
和10
之后查看,因为如果一切都按照计划进行,将会改变。syscall
__vdso_query()
syscall
_vdso_data[0].__unused
当前结果
目前,内容始终0
与syscall
.
问题
如何_vdso_data
正确访问
我尝试通过两种方式访问_vdso_data
:__arch_sync_vdso_data()
和extern
.
- 当我尝试使用
__arch_get_k_vdso_data
函数 where defined inasm/vdso/vsyscall.h
来访问时_vdso_data
,我遇到了一些变量重新定义错误。如果我同时包含vsyscall.h
andkernel/sys.c
,arch/x86/entry/vdso/vclock_gettime.c
它似乎DEFINE_VVAR(struct vdso_data, _vdso_data);
会被调用两次并导致_vdso_data
. 我试图在它周围放置#ifndef
、#def
和#endif
宏,但错误仍然存在。 - 我尝试的另一件事是仅声明实现中显示的
_vdso_data
asextern
变量syscall
。如果我这样做,重新定义错误就消失了。代码编译并正常运行,没有错误或分段错误,但结果没有改变。
__arch_sync_vdso_data()
功能
我在内核源代码中阅读了一些示例用法__arch_sync_vdso_data
,我发现人们最终使用函数来编写_vdso_data
。但是,我认为这个函数实际上是空的generic-asm
,我能找到的唯一定义是 on Arm
。不确定这将如何工作x86
以及是否需要。
在网上很难找到 vdso 资源,我已经阅读了所有最近的帖子。我非常感谢您的帮助和提前感谢。