提问
一般来说,我们使用ASID来标识进程的ID, 使用VMID来标识虚拟机ID,那么具体CPU/加速器/PCIe发起的一次操作,如何从硬件角度识别,并透传到后续模块呢?即如何标识不同的流?软硬件的编程接口是如何配合的?
CPU视角
ASID
首先,站在CPU视角,CPU通过TTBR0/TTBR1来控制不同EL等级下的内存域。当CPU下发操作的时候,通过访问地址的VA,确定当前应该使用TTBR0还是TTBR1:
![](https://img-blog.csdnimg.cn/img_convert/d5a3603674d6fa7eb7c1d4eb9a941156.webp?x-oss-process=image/format,png)
简而言之,换做Linux,TTBR0管用户态,TTBR1管内核态(包括EL2),无论哪个level的TTBR寄存器,基本的组成形式如下:
![](https://img-blog.csdnimg.cn/img_convert/0cb722e92925d075f8235c4ca33eff56.webp?x-oss-process=image/format,png)
其中寄存器域63-48合计16个bit标识ASID(这里存在一个卷绕的问题,内核巧妙的进行了处理)。
通过TTBR寄存器,可以识别不同的进程使用的页表,也就是说页表信息跟随进程绑定,我们在内核的task_struct里面可以看到这一点:
struct task_struct {
...
struct mm_struct *mm;
struct mm_struct *active_mm;
...
}
在进程切换的时候,我们可以看到ASID的切换: