eBPF指令集_sse3指令集

eBPF指令集_sse3指令集eBPF指令集是一个通用的RISC指令集,11个64位寄存器,一个程序计数器和512字节的栈空间构成。

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

寄存器及调用约定

通用的RISC指令集,11个64位寄存器,一个程序计数器和512字节的栈空间构成。

10个通用寄存器+1个只读FP(帧指针寄存器),所有寄存器64bit宽。操作模式默认为64位,32位子寄存器只能通过特殊的算数逻辑单元ALU操作访问。

栈帧的边界由SP和FP限定

SP一直指向栈顶

每个进程的栈空间为一帧,FP指向当前进程栈空间的栈底。

  • R0:函数返回值、程序退出值

  • R1-R5:函数调用参数

  • R6-R9:被调用者保存函数(调用保留的)寄存器

  • R10:只读FP用于访问栈

R0-R5是临时寄存器,eBPF程序在调用之间将它们从寄存器转移到内存或从内存转移到寄存器。(spill/fill,解释见https://www.geeksforgeeks.org/what-is-spilling/)

指令编码

  • 基础指令编码:一条指令64bit

  • 宽指令编码:在基础指令编码后附加一个64bit的立即数,一共128bit

基础指令编码结构:

32 bits (MSB) 16 bits 4 bits 4 bits 8 bits (LSB)
immediate offset source register destination register opcode

指令分类

Opcode低三位:

指令分类 class value description
算数指令 BPF_ALU 0x04 32-bit 算数操作
BPF_ALU64 0x07 64-bit 算数操作
跳转指令 BPF_JMP 0x05 64-bit 跳转操作
BPF_JMP32 0x06 32-bit 跳转操作
载入指令 BPF_LD 0x00 non-standard load operations
BPF_LDX 0x01 载入寄存器操作
存储指令 BPF_ST 0x02 存储立即数操作
BPF_STX 0x03 存储寄存器操作

算数和跳转指令

包括:BPF_ALU, BPF_ALU64, BPF_JMP and BPF_JMP32

opcode分为三部分

4 bits (MSB) 1 bit 3 bits (LSB)
operation code source instruction class

第四位编码了source操作数:

source value description
BPF_K 0x00 使用 32-bit 立即数作为源操作数
BPF_X 0x08 使用 ‘src_reg’ 寄存器作为源操作数

算数指令

operation code编码的操作

code value description
BPF_ADD 0x00 dst += src
BPF_SUB 0x10 dst -= src
BPF_MUL 0x20 dst *= src
BPF_DIV 0x30 dst /= src
BPF_OR 0x40 dst |= src
BPF_AND 0x50 dst &= src
BPF_LSH 0x60 dst <<= src
BPF_RSH 0x70 dst >>= src
BPF_NEG 0x80 dst = ~src
BPF_MOD 0x90 dst %= src
BPF_XOR 0xa0 dst ^= src
BPF_MOV 0xb0 dst = src
BPF_ARSH 0xc0 sign extending shift right
BPF_END 0xd0 byte swap operations (see separate section below)

例子:

BPF_XOR | BPF_K | BPF_ALU == src_reg = (u32) src_reg ^ (u32) imm32

字节交换指令

仅对目标寄存器进行操作,不使用源寄存器或立即数

source字段用于选择转换的字节序

source value description
BPF_TO_LE 0x00 转换主机字节序到小端
BPF_TO_BE 0x08 转换主机字节序到大端

立即数字段用于编码交换操作的宽度,可以是16/32/64

例子

BPF_ALU | BPF_TO_LE | BPF_END with imm = 16

dst_reg = htole16(dst_reg)

跳转指令

code value description notes
BPF_JA 0x00 PC += off BPF_JMP only
BPF_JEQ 0x10 PC += off if dst == src
BPF_JGT 0x20 PC += off if dst > src unsigned
BPF_JGE 0x30 PC += off if dst >= src unsigned
BPF_JSET 0x40 PC += off if dst & src
BPF_JNE 0x50 PC += off if dst != src
BPF_JSGT 0x60 PC += off if dst > src signed
BPF_JSGE 0x70 PC += off if dst >= src signed
BPF_CALL 0x80 function call
BPF_EXIT 0x90 function / program return BPF_JMP only
BPF_JLT 0xa0 PC += off if dst < src unsigned
BPF_JLE 0xb0 PC += off if dst <= src unsigned
BPF_JSLT 0xc0 PC += off if dst < src signed
BPF_JSLE 0xd0 PC += off if dst <= src signed

载入和存储指令

包括:BPF_LD, BPF_LDX, BPF_ST and BPF_STX

Opcode结构:

3 bits (MSB) 2 bits 3 bits (LSB)
mode size instruction class

size修饰符

size modifier value description
BPF_W 0x00 word (4 bytes)
BPF_H 0x08 half word (2 bytes)
BPF_B 0x10 byte
BPF_DW 0x18 double word (8 bytes)

mode修饰符

mode modifier value description
BPF_IMM 0x00 64-bit immediate instructions
BPF_ABS 0x20 legacy BPF packet access (absolute)
BPF_IND 0x40 legacy BPF packet access (indirect)
BPF_MEM 0x60 regular load and store operations,寄存器和内存间传递数据的标准载入和存储指令
BPF_ATOMIC 0xc0 atomic operations,原子操作

举例

把立即数的值放到dst_reg+off的内存位置

BPF_MEM | <size> | BPF_ST == *(size *) (dst_reg + off) = imm32

原子操作

在内存上的操作,不会被中断或破坏,使用mode修饰符BPF_ATOMIC,只支持32位和64位操作,不支持8/16位。

立即数字段用于编码实际的原子操作:

imm value description
BPF_ADD 0x00 atomic add
BPF_OR 0x40 atomic or
BPF_AND 0x50 atomic and
BPF_XOR 0xa0 atomic xor

例子:

BPF_ATOMIC | BPF_W | BPF_STX with imm = BPF_ADD

*(u32 *)(dst_reg + off16) += src_reg

除了简单原子操作,还有一个修饰符和两个复杂原子操作

imm value description
BPF_FETCH 0x01 modifier: return old value
BPF_XCHG 0xe0 | BPF_FETCH atomic exchange
BPF_CMPXCHG 0xf0 | BPF_FETCH atomic compare and exchange

如果设置了BPF_FETCH,会使用修改前内存中的值覆盖src_reg

BPF_XCHG以原子操作交换src_reg的值和dst_reg + off地址的值

BPF_CMPXCHG以原子操作将dst_reg + off地址的值和R0进行比较,如果相等,dst_reg + off地址的值将替换为src_reg。操作前dst_reg + off地址的值会被扩展零,然后加载回R0。

clang可以生成原子指令通过默认的
-mcpu=v3

如果较低版本的
-mcpu被设置,clang只能生成不带
BPF_FETCH
BPF_ADD

如果需要启用原子特征,并保持较低版本的
-mcpu,可以使用
-Xclang -target-feature -Xclang +alu32

64位立即数指令

带有BPF_IMMmode修饰符的指令,对额外的64位立即数使用宽指令编码:

BPF_LD | BPF_DW | BPF_IMM means dst_reg = imm64

传统的BPF Packet访问指令

用于访问数据包数据,并且只能在程序上下文是指向网络数据包的指针时使用。

两种指令形式

  • BPF_ABS | <size> | BPF_LDBPF_ABS访问由立即数指定的绝对偏移的数据包数据
  • BPF_IND | <size> | BPF_LDBPF_IND访问除立即数外还包括寄存器值作为偏移的数据包数据。

七个隐式操作数:

  • R6,隐式输入,指向 struct sk_buff 的指针
  • R0,隐式输出,从数据包中获取的数据
  • R1-5,临时寄存器,在调用BPF_ABS | BPF_LDBPF_IND | BPF_LD后被破坏

隐式的程序退出条件:当eBPF程序试图访问数据包边界外的数据时,执行将被终止。

例子:

BPF_IND | BPF_W | BPF_LD

R0 = ntohl(*(u32 *) (((struct sk_buff *) R6)->data + src_reg + imm32))

参考

eBPF Instruction Set ‒ The Linux Kernel documentation

BPF and XDP Reference Guide — Cilium 1.11.3 documentation

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/190954.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • mysql 1146 错误处理

    mysql 1146 错误处理在进行mysql 相关的备份,会出现1146错误。问题出现是因为之前把   mysql/data/ibdata1,ib_logfile0,ib_logfile1,ib_logfile2 文件删除了,mysql重启之后会自动生成这些文件的。但是之前的innodb引擎,就不能再访问了。特别注意一下: 删除ibdata1 文件的时候,必须要记得  这5张i…

    2022年6月12日
    53
  • [TensorFlow 学习笔记-02]配置PyCharm IDE环境「建议收藏」

    [TensorFlow 学习笔记-02]配置PyCharm IDE环境「建议收藏」工欲善其事必先利其器,IDE我选择的是PyCharm。[本地环境]操作系统:Windows7bit[PyCharm下载地址]下载地址:http://www.jetbrains.com/pycharm/download/#section=windows选择版本:Community,具体如下图所示:**[安装PyCharm]**采用默认安装方式,安装成功后,首次出现如下界面,Cr

    2022年8月26日
    2
  • 运行疑难解答时出错0x8000FFFF_vs2010由于缺少调试目标

    运行疑难解答时出错0x8000FFFF_vs2010由于缺少调试目标发生错误,需要终止调试。有关更多详细信息,请参阅Microsoft帮助和支持网站。HRESULT=0x8000ffff。ErrorCode=0x0。工程目录太深会导致上述错误发生,把整个工程文件往外移即可

    2022年9月24日
    0
  • 如何计算经纬度之间的距离_根据经纬度算距离

    如何计算经纬度之间的距离_根据经纬度算距离用php计算两个指定的经纬度地点之间的距离,代码:/***求两个已知经纬度之间的距离,单位为米*@paramlng1,lng2经度*@paramlat1,lat2纬度*@returnfloat距离,单位米*@editwww.jbxue.com**/functiongetdistance($lng1,$lat1,$lng2,$lat2){//将角度转为狐度$radLat1=deg2r…

    2022年9月2日
    2
  • idea快速删除一行_idea查找文件内容快捷键

    idea快速删除一行_idea查找文件内容快捷键使用eclipse,有时候出现多个空行时,习惯使用快捷键:Ctrl+D,删除当前一行。最近使用idea开发,发现手动删除空行,很麻烦,特意查了一下,发现是快捷键:Ctrl+Y。如下图所示:使用Ctrl+Y后删除当前行另外:可以使用设置,讲idea的快捷键设置为eclipse模式…

    2022年9月6日
    2
  • 微信公众号之自定义菜单

    微信公众号之自定义菜单今天是“微信开发会客厅”栏目的第一期,我的微信自媒体“刘琪的商业观察”有幸请到了几位自定义菜单的“尝鲜者”,请他们谈谈对。 “订酒店”公众号负责人、快捷酒店管家产品经理朱坤的看法比较具有典型性,他表示:“如果说是惊喜还谈不上,毕竟微信团队的人太少了,而且事情非常多,所以开放和相关功能的开发肯定是慢慢来的。不过,这也传递了一个很重要的信号与信心,那就是,每个公号都会成为一个独立的具体

    2022年5月13日
    78

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号