免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2173 | 回复: 5
打印 上一主题 下一主题

[内核入门] current宏的疑问[己解答] [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-07-13 17:30 |只看该作者 |倒序浏览
本帖最后由 hellolwq 于 2012-07-16 12:57 编辑

x86 64下面,使用内核2.6.30。
current宏用于内核模块获取当前运行的进程结构体,展开为:
  1. movq %%gs:0xb000,%0
复制代码
比如得到地址可能是:ffff88007d0c9870

但是将段寄存器gs打印出来,发现其值为0,
16位段描述符号的TI位如果为0则为GDT,这里GS为全0,只能是GDT里面的第一项,也就是空描述符那项。
手册里面明明写着使用空描述符赋值可以,用来寻址就报错啊。。。


询问同事,提到linux下gs是被弃用的,使用的是MSR_GS_BASE。
发现有俩问题:
1、如果GS被弃用,为什么内核代码使得的是movq %%gs:0xb000,%0
2、将MSR_GS_BASE读出来的值,跟%%gs:0xb000对不上。[后面证实这里能匹配上的。]
3、代码上显示MSR_GS_BASE存储的是 (unsigned long)per_cpu(irq_stack_union.gs_base, cpu)
  1. void load_percpu_segment(int cpu)
  2. {
  3. #ifdef CONFIG_X86_32
  4.         loadsegment(fs, __KERNEL_PERCPU);
  5. #else
  6.         loadsegment(gs, 0);
  7.         wrmsrl(MSR_GS_BASE, (unsigned long)per_cpu(irq_stack_union.gs_base, cpu));
  8. #endif
  9.         load_stack_canary_segment();
  10. }
复制代码
盼高手指条出路,内核似海,回头无岸。


在stackoverflow发的帖子上有个朋友给出了AMD上面的实现说明。
http://stackoverflow.com/questio ... 4/11497742#11497742

我在Intel手册找到类似的描述。
大部分段寄存器在64位下被忽略,fs和gs有点特殊,用来寻址的时候,实际使用的是对应的[fs,gs].base,而这些值是映射到其对应的MSR_[GS|FS]_BASE上的。

3.4.4  Segment Loading Instructions in IA-32e Mode
[...]
When FS and GS segment overrides are used in 64-bit mode, their respective base
addresses are used in the linear address calculation: (FS or GS).base + index +
displacement. FS.base and GS.base are then expanded to the full linear-address size
supported by the implementation. The resu lting effective address calculation can
wrap across positive and negative addresses; the resulting linear address must be
canonical.
In 64-bit mode, memory accesses using FS -segment and GS-segment overrides are
not checked for a runtime limit nor subjected to attribute-checking. Normal segment
loads (MOV to Sreg and POP Sreg) into FS and GS load a standard 32-bit base value
in the hidden portion of the segment descriptor register. The base address bits above
the standard 32 bits are cleared to 0 to  allow consistency for implementations that
use less than 64 bits.
The hidden descriptor register fields for FS.base and GS.base are physically mapped
to MSRs in order to load all address bits supported by a 64-bit implementation. Soft-ware with CPL = 0 (privileged software) can load all supported linear-address bits
into FS.base or GS.base using WRMSR. Addresses written into the 64-bit FS.base and
GS.base registers must be in canonical form. A WRMSR instruction that attempts to
write a non-canonical address to those registers causes a #GP fault.
...

论坛徽章:
0
2 [报告]
发表于 2012-07-13 23:18 |只看该作者
  友情帮顶

论坛徽章:
2
CU大牛徽章
日期:2013-04-17 11:46:28CU大牛徽章
日期:2013-04-17 11:46:39
3 [报告]
发表于 2012-07-14 00:04 |只看该作者
用的是哪个版本?

论坛徽章:
0
4 [报告]
发表于 2012-07-15 17:42 |只看该作者
回复 2# luoyan_xy


   

论坛徽章:
0
5 [报告]
发表于 2012-07-15 17:42 |只看该作者
x86 64 2.6.30。
盼高手赐教!
cdtits 发表于 2012-07-14 00:04
用的是哪个版本?

论坛徽章:
0
6 [报告]
发表于 2012-07-16 10:02 |只看该作者
经高人指点,找到问题的解决办法,但是关于%%gs为0却能继续使用的原因仍然未知,不知道是否为CPU特性?
  1. //内核自带的current宏
  2. println("current:%p",current);

  3. //gs确实保存在MSR_GS_BASE中
  4. gs_base = x86_rdmsr64(MSR_GS_BASE);
  5. println("MSR_GS_BASE:%p",gs_base);
  6. cur_task = (unsigned long*)(gs_base + 0xb000);//0xb000为per_cpu__current_task偏移量
  7. println("cur_task:%p",*cur_task);
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP