【92】实测:访问不存在的function导致UR


前言

协议规定访问不存在的function会导致UR,今天我们就来实测一下。

这篇文章主要设计下面几个方面:

1、X86上的memory config

2、config方式访问不存在的设备导致UR

3、UR和advisory  non fatal转换

4、header log解析

一、协议规定

    协议规定如果device 不支持收到的request type,那么request就unsupported request。如果request需要completion,那么completion的status就是UR。

【92】实测:访问不存在的function导致UR_第1张图片

【92】实测:访问不存在的function导致UR_第2张图片

【92】实测:访问不存在的function导致UR_第3张图片

        【92】实测:访问不存在的function导致UR_第4张图片   

【92】实测:访问不存在的function导致UR_第5张图片

  传统的PCI设备,device通过assert DEVSEL#来“claims” bus上的request(请求者通过把target devie的address放到address bus来初始化一个transaction,然后完成者通过assert DEVSEL#来response这个request(claim the transaction)。DEVSEL#就是用来表示该devcie已经被选中作为PCI request的target device。当device assert DEVSEL#,就表示该device已经decode了request的address,并且准备对这个request进行response)。如果在一段时间后,没有device来claim一个请求,请求者需要terminate这个request,这就是Master Abort。由于PCIe是一个点对点的互联协议,没有对应的机制来claim request,因此,request的receiver需要决定该request是否被claim。如果request不能被claim,那么该request被认为是Unsupported Request的,这就是PCIe协议中对等于传统的Master Abort termination机制

    对于Type0的device,对于memory或者I/O request, function的地址范围决定了是否要claim 该request,也就是常说的基于地址的路由机制。

    对于configuration request,request 中的format/type(type 0 request format)显示device是否是request的target。如果request的地址(completer ID(byte 8-9))是一个没有实现的function,那么,device同样不会claim 这个configuration request

【92】实测:访问不存在的function导致UR_第6张图片

    Spec上说的极其拗口,其实非常简单,对于configuration request,如果request中的completer ID是device没有实现的function,那么devcie就认为该request是Unsupported Request

   协议读百遍不如上手一练,以知促行方能知行合一,我们来实际验证一下。

二、实际验证

1.X86 memory config介绍

    X86的config介绍见下面文章:

【14】PCIe架构下memory空间、IO空间、PCIe配置空间简介_linjiasen的博客-CSDN博客

 1.1 PCIe tree【92】实测:访问不存在的function导致UR_第7张图片

2.验证过程

2.1 清零系统启动过程中的错误

     系统启动过程中会进行全function的枚举,这样会导致EP设备的出现错误,我们手动清零2:0.0和2:0.1的Device Status Register和Uncorrectable Error Status Register/Correctable Error Status Register

    清零后lspci -s 0:1.1 -vvvv、lspci -s 2:0.0 -vvvvv、lspci -s 2:0.1 -vvvvv的配置空间,方便后面操作后对比

root@mt-System-Product-Name:~# setpci -s 2:0.0 CAP_EXP+0xa.b
09
root@mt-System-Product-Name:~# setpci -s 2:0.0 CAP_EXP+0xa.b=0x9
root@mt-System-Product-Name:~# setpci -s 2:0.0 CAP_EXP+0xa.b
00
root@mt-System-Product-Name:~# setpci -s 2:0.1 CAP_EXP+0xa.b
09
root@mt-System-Product-Name:~# setpci -s 2:0.1 CAP_EXP+0xa.b=0x9
root@mt-System-Product-Name:~# setpci -s 2:0.1 CAP_EXP+0xa.b
00
root@mt-System-Product-Name:~#
root@mt-System-Product-Name:~# setpci -s 2:0.0 ECAP_AER+0x10.l
00002000
root@mt-System-Product-Name:~# setpci -s 2:0.0 ECAP_AER+0x10.l=0x2000
root@mt-System-Product-Name:~# setpci -s 2:0.0 ECAP_AER+0x10.l
00000000
root@mt-System-Product-Name:~# setpci -s 2:0.0 ECAP_AER+0x4.l
00000000
root@mt-System-Product-Name:~# setpci -s 2:0.1 ECAP_AER+0x4.l
00000000
root@mt-System-Product-Name:~# setpci -s 2:0.1 ECAP_AER+0x10.l
00002000
root@mt-System-Product-Name:~# setpci -s 2:0.1 ECAP_AER+0x10.l=0x2000
root@mt-System-Product-Name:~# setpci -s 2:0.1 ECAP_AER+0x10.l
00000000

【92】实测:访问不存在的function导致UR_第8张图片

2.2 configuration read 2:0.0的reg

root@mt-System-Product-Name:~# cat /proc/iomem | grep mmcon -i
e0000000-efffffff : PCI MMCONFIG 0000 [bus 00-ff]
root@mt-System-Product-Name:~#
root@mt-System-Product-Name:~#
root@mt-System-Product-Name:~# busybox devmem 0xe0200000
0x01061ED5
root@mt-System-Product-Name:~# setpci -s 2:0.0 0x0.l
01061ed5
root@mt-System-Product-Name:~# busybox devmem 0xe0200030
0xA6000002
root@mt-System-Product-Name:~# setpci -s 2:0.0 0x30.l
a6000002
root@mt-System-Product-Name:~# lspci -s 2:0.0 -v
02:00.0 3D controller: Moore Threads Technology Co.,Ltd MTT S60
        Subsystem: Moore Threads Technology Co.,Ltd MTT S60
        Flags: bus master, fast devsel, latency 0, IRQ 255
        Memory at a4000000 (32-bit, non-prefetchable) [size=32M]
        Memory at 6000000000 (64-bit, prefetchable) [size=16G]
        Expansion ROM at a6000000 [disabled] [size=2M] 

在这里插入图片描述

我们看到PCI MMCONFIG的起始地址是0xe0000000,按照table 7-1的address map,可以算出2:0.0的配置空间起始地址是0xe0200000(0xe0000000+0x2<<20),busybox devmem 0xe0200000获取的值是0x01061ED5和setpci -s 2:0.0 0x0.l一致,是GPU的deviceid和vendor

busybox devmem 0xe0200030获取的值和setpci -s 2:0.0 0x30.l一致,是EXP ROM BAR reg。

configuration read后lspci -s 0:1.1 -vvvv、lspci -s 2:0.0 -vvvvv、lspci -s 2:0.1 -vvvvv的配置空间,方便后面操作后对比

【92】实测:访问不存在的function导致UR_第9张图片

我们对比2.1 清零系统启动过程中的错误2.2 configuration read 2:0.0的reg操作后lspci -s 0:1.1 -vvvv、lspci -s 2:0.0 -vvvvv、lspci -s 2:0.1 -vvvvv的结果,没有任何变化,说明2.2 configuration read 2:0.0的reg的操作没有引起错误。

2.3 configuration read 2:0.1的reg

root@mt-System-Product-Name:~# busybox devmem 0xe0201000
0x01FF1ED5
root@mt-System-Product-Name:~# setpci -s 2:0.1 0x0.l
01ff1ed5
root@mt-System-Product-Name:~#
root@mt-System-Product-Name:~# busybox devmem 0xe0201010
0xA2000000
root@mt-System-Product-Name:~# setpci -s 2:0.1 0x10.l
a2000000

【92】实测:访问不存在的function导致UR_第10张图片

configuration read后lspci -s 0:1.1 -vvvv、lspci -s 2:0.0 -vvvvv、lspci -s 2:0.1 -vvvvv的配置空间,方便后面操作后对比

 我们对比2.1 清零系统启动过程中的错误2.3 configuration read 2:0.1的reg操作后lspci -s 0:1.1 -vvvv、lspci -s 2:0.0 -vvvvv、lspci -s 2:0.1 -vvvvv的结果,没有任何变化,说明2.3 configuration read 2:0.0的reg的操作没有引起错误。

2.4 configuration read 2:0.2的reg导致UR转advisory non fatal错误

    现在外面要用configuration read一个没有实现的function的reg了。

root@mt-System-Product-Name:~# busybox devmem 0xe0202000
0xFFFFFFFF

我们看到返回一个全1的值

configuration read后lspci -s 0:1.1 -vvvv、lspci -s 2:0.0 -vvvvv、lspci -s 2:0.1 -vvvvv的配置空间,方便后面操作后对比

我们发现出现的UR的错误,这个UR的错误被转换成了advisory non fatal的correctable的错误

【92】实测:访问不存在的function导致UR_第11张图片

【92】实测:访问不存在的function导致UR_第12张图片

2.5 手动清零2.4中访问导致的错误,并设置severity为1

root@mt-System-Product-Name:~# setpci -s 2:0.0 ECAP_AER+0x10.l
00002000
root@mt-System-Product-Name:~# setpci -s 2:0.0 ECAP_AER+0x10.l=0x2000
root@mt-System-Product-Name:~# setpci -s 2:0.0 ECAP_AER+0x10.l
00000000
root@mt-System-Product-Name:~# setpci -s 2:0.1 ECAP_AER+0x10.l
00002000
root@mt-System-Product-Name:~# setpci -s 2:0.1 ECAP_AER+0x10.l=0x2000
root@mt-System-Product-Name:~# setpci -s 2:0.1 ECAP_AER+0x10.l
00000000
root@mt-System-Product-Name:~# setpci -s 2:0.0 ECAP_AER+0x4.l
00000000
root@mt-System-Product-Name:~# setpci -s 2:0.1 ECAP_AER+0x4.l
00000000
root@mt-System-Product-Name:~#
root@mt-System-Product-Name:~#
root@mt-System-Product-Name:~# setpci -s 2:0.0 CAP_EXP+0xa.b
09
root@mt-System-Product-Name:~# setpci -s 2:0.0 CAP_EXP+0xa.b=0x9
root@mt-System-Product-Name:~# setpci -s 2:0.0 CAP_EXP+0xa.b
00
root@mt-System-Product-Name:~# setpci -s 2:0.1 CAP_EXP+0xa.b
09
root@mt-System-Product-Name:~# setpci -s 2:0.1 CAP_EXP+0xa.b=0x9
root@mt-System-Product-Name:~# setpci -s 2:0.1 CAP_EXP+0xa.b
00
root@mt-System-Product-Name:~#
root@mt-System-Product-Name:~#
root@mt-System-Product-Name:~# setpci -s 2:0.0 ECAP_AER+0xc.l
00462030
root@mt-System-Product-Name:~# setpci -s 2:0.0 ECAP_AER+0xc.l=0xffffffff
root@mt-System-Product-Name:~# setpci -s 2:0.0 ECAP_AER+0xc.l
005ff031
root@mt-System-Product-Name:~#
root@mt-System-Product-Name:~# setpci -s 2:0.1 ECAP_AER+0xc.l
00462030
root@mt-System-Product-Name:~# setpci -s 2:0.1 ECAP_AER+0xc.l=0xffffffff
root@mt-System-Product-Name:~# setpci -s 2:0.1 ECAP_AER+0xc.l
005ff030

【92】实测:访问不存在的function导致UR_第13张图片

清零错误并设置severity后lspci -s 0:1.1 -vvvv、lspci -s 2:0.0 -vvvvv、lspci -s 2:0.1 -vvvvv的配置空间,方便后面操作后对比

我们发现2.4中访问导致的错误被清零了,并且UR错误的severity被置1了

【92】实测:访问不存在的function导致UR_第14张图片

【92】实测:访问不存在的function导致UR_第15张图片


2.6 configuration read 2:0.2的reg(offset:0x0)导致UR

 现在我们要用configuration read一个没有实现的function的reg(offset:0x0)了。

root@mt-System-Product-Name:~# busybox devmem 0xe0202000
0xFFFFFFFF

我们看到返回一个全1的值

configuration read后lspci -s 0:1.1 -vvvv、lspci -s 2:0.0 -vvvvv、lspci -s 2:0.1 -vvvvv的配置空间,方便后面操作后对比

我们发现出现的UR的错误

【92】实测:访问不存在的function导致UR_第16张图片

【92】实测:访问不存在的function导致UR_第17张图片

我们拿header log来解析一下,看看UR是不是我们刚才访问导致的,同时验证下X86的config read。

HeaderLog: 04000001 0000000f 02020000 00000000

04000001:对应的configuration read type0,说明请求是针对type的configuration read

【92】实测:访问不存在的function导致UR_第18张图片 02020000: completer ID的bus是0x02,device是0x00,function是0x2

【92】实测:访问不存在的function导致UR_第19张图片

 2.7 configuration read 2:0.2的reg(offset:0x30)导致UR

为了验证到reg number对应的字段和head log reg更新,我们先手动清除上次访问导致的GPU的错误,清除错误后lspci -s 0:1.1 -vvvv、lspci -s 2:0.0 -vvvvv、lspci -s 2:0.1 -vvvvv的配置空间,方便后面操作后对比

root@mt-System-Product-Name:~# setpci -s 2:0.0 ECAP_AER+0x10.l
00000000
root@mt-System-Product-Name:~# setpci -s 2:0.1 ECAP_AER+0x10.l
00000000
root@mt-System-Product-Name:~# setpci -s 2:0.1 ECAP_AER+0x4.l
00100000
root@mt-System-Product-Name:~# setpci -s 2:0.1 ECAP_AER+0x4.l=0x00100000
root@mt-System-Product-Name:~# setpci -s 2:0.1 ECAP_AER+0x4.l
00000000
root@mt-System-Product-Name:~# setpci -s 2:0.0 ECAP_AER+0x4.l
00100000
root@mt-System-Product-Name:~# setpci -s 2:0.0 ECAP_AER+0x4.l=0x00100000
root@mt-System-Product-Name:~# setpci -s 2:0.0 ECAP_AER+0x4.l
00000000
root@mt-System-Product-Name:~# setpci -s 2:0.0 CAP_EXP+0xa.b
0c
root@mt-System-Product-Name:~# setpci -s 2:0.0 CAP_EXP+0xa.b=0xc
root@mt-System-Product-Name:~# setpci -s 2:0.0 CAP_EXP+0xa.b
00
root@mt-System-Product-Name:~# setpci -s 2:0.1 CAP_EXP+0xa.b
0c
root@mt-System-Product-Name:~# setpci -s 2:0.1 CAP_EXP+0xa.b=0xc
root@mt-System-Product-Name:~# setpci -s 2:0.1 CAP_EXP+0xa.b
00

【92】实测:访问不存在的function导致UR_第20张图片

 现在我们要用configuration read一个没有实现的function的reg(offset:0x30)了。

root@mt-System-Product-Name:~# busybox devmem 0xe0202030
0xFFFFFFFF

我们看到返回一个全1的值

 我们发现出现的UR的错误【92】实测:访问不存在的function导致UR_第21张图片

 ​​​​​​【92】实测:访问不存在的function导致UR_第22张图片

 我们拿header log来解析一下。

02020030中的0x30就是访问的reg number

【92】实测:访问不存在的function导致UR_第23张图片

总结

    configuration read访问没有实现的function会导致UR的错误 

你可能感兴趣的:(PCIe协议及应用,UR,config,read,header,log解析)