回归验证第一期:第三代香山(昆明湖)Bug用例复现(进行中)
根据已发布的Bug任务,设计回归测试用例复现Bug
Created Jan 11, 2024 - Last updated: Jan 11, 2024
UT(单元测试)、IT(集成测试)和 ST(系统测试)是处理器验证的三个关键阶段,它们分别针对验证中的不同层次。其中UT是对处理器设计中的最小功能单元(模块)进行测试,确保其功能符合设计要求。然而在生产实际中,一些模块的Bug并非在UT阶段被发现,而是在后续的验证阶段发现并报告的。因此,我们需要在UT中构造测试用例将这些Bug复现出来,同时也需要在该Bug被修复后的版本重新运行测试用例,确保正确修复了该Bug。这个过程也叫做回归测试。
任务简介
本期任务将会提供18个待回归的Bug,参与者需使用指定工具链(picker,toffee(可选)),构建测试用例对Bug进行回归。
对于大多数的Bug,我们会提供详细的Bug描述,包括Bug所在的模块,发生原因,如何复现等,对于部分Bug,可能需要根据描述自行定位相关模块或搭建验证环境。根据工作量的不同,会获得不同等级的奖金。每完成1个Bug的回归并向UnityChipForXiangShan仓库提交Pull Request(PR),将获得100元的奖金作为奖励,若贡献bug验证基础环境,可以获得额外奖励。希望大家能够积极参与并完成任务!
测试内容
对每个Bug,需要您完成如下的工作:
1、环境构建
首先,根据UnityChipForXiangShan提供的测试环境,构建测试用例对Bug进行回归。
- 若描述中未明确模块,需要自行定位相关模块。
- 若仓库中目标模块不存在验证环境,请参考文档中的准备验证环境,添加测试部分,按照规范搭建验证环境。
2、用例构造
接下来,根据触发Bug的原因,构建相应的测试用例。此次任务会给您提供出现Bug的RTL和修复该Bug的commit日期
对于所构建的测试用用例,需要满足以下两方面的内容:
在出现Bug的RTL:可以运行该测试用例,且运行该测试用例进行测试不通过。
在仓库下载commit日期后的RTL:可以运行该测试用例,且该测试用例可以通过。
3、提交说明
最后撰写说明,描述该Bug所属于哪个模块,简述相关的测试环境和用例,以及如何运行测试。
完成上述工作后,将PR提交至UnityChipForXiangShan仓库。
任务奖励
每完成1个Bug的回归并向UnityChipForXiangShan仓库提交PR,对于第一个接受的PR,将获得100元的奖金作为奖励,若贡献bug验证基础环境,可以获得额外奖励。
待复现Bug
对于每个Bug,以下表格列出了对应的任务id、Bug描述、产生原因、出现Bug的RTL版本以及修复的commit日期等信息。更多详细内容可看issue或任务详情。
注:Commit:点击可跳转至修复该Bug的commit页面;RTL:点击可下载出现Bug时的RTL。
序号 | 任务id | Bug描述 | Commit | RTL | 原因 | issue | 贡献人 |
---|---|---|---|---|---|---|---|
1 | KMH22-242 | 访存发生misalign,未传递gpa,导致出错访存发生misalign,未传递gpa,导致出错 | 2024-09-12 | 24080301 | 访存发生misalign时,未传递gpa,导致出错访存发生misalign时,未传递gpa,导致出错 | 链接 | - |
2 | KMH22-118 | dcsr中stopcount和stoptime功能未实现 dcsr中stopcount和stoptime功能未实现 | 2024-11-14 | 24080301 | 未实现 dcsr中stopcount和stoptime功能,在设计代码中实现未实现 dcsr中stopcount和stoptime功能,在设计代码中实现 | 链接 | - |
3 | KMH22-351 | L1TLB重填gpaddr的时候计算错误L1TLB重填gpaddr的时候计算错误 | 2024-09-04 | 24082801 | 第一阶段地址翻译为Bare,第二阶段地址翻译为Sv39x4时,报GPF时mtval2为0,onlys2的情况下,L1TLB重填gpaddr的时候计算错误,使用了s1的ppn,应该使用s2的tag第一阶段地址翻译为Bare,第二阶段地址翻译为Sv39x4时,报GPF时mtval2为0,onlys2的情况下,L1TLB重填gpaddr的时候计算错误,使用了s1的ppn,应该使用s2的tag | 链接 | - |
4 | KMH22-397 | RAS误判推测栈阻塞。引起前端阻塞卡死RAS误判推测栈阻塞。引起前端阻塞卡死 | 2024-09-10 | 24082801 | redirect时发送到RAS模块的Call和ret信号存在问题,RAS实现阻塞的情况下,会误判推测栈阻塞。引起前端阻塞卡死redirect时发送到RAS模块的Call和ret信号存在问题,RAS实现阻塞的情况下,会误判推测栈阻塞。引起前端阻塞卡死 | 链接 | - |
5 | KMH22-398 | miss_req 不断在 mshr 中等待探测和重放时,refill_req 会阻塞 store_req 和probe_req,从而导致死锁miss_req 不断在 mshr 中等待探测和重放时,refill_req 会阻塞 store_req 和probe_req,从而导致死锁 | 2024-09-04 | 24082801 | 在以前的设计中,当 miss_req 不断在 mshr 中等待探测和重放时,refill_req 会阻塞 store_req 和probe_req,从而导致死锁。
现在删除无用的阻塞以修复此问题在以前的设计中,当 miss_req 不断在 mshr 中等待探测和重放时,refill_req 会阻塞 store_req 和probe_req,从而导致死锁。
现在删除无用的阻塞以修复此问题 | 链接 | - |
6 | KMH22-399 | unit-stride 地址硬编码 39 位,改成 Sv48 后高位丢失unit-stride 地址硬编码 39 位,改成 Sv48 后高位丢失 | 2024-09-16 | 24082801 | 在支持sv48后,向量访存存在位宽未修改适配的情况在支持sv48后,向量访存存在位宽未修改适配的情况 | 链接 | - |
7 | KMH22-400 | MMIO 和 cacheable 空间的 PCredit 未放在一起仲裁导致PCrdGrant 丢失MMIO 和 cacheable 空间的 PCredit 未放在一起仲裁导致PCrdGrant 丢失 | TBD | 24082801 | MMIO 和 cacheable 空间的 PCredit 应该放在一起仲裁MMIO 的 rxrsp 分配到哪一项 MMIO entry 是根据 TxnID 来判断的,但是 PCrdGrant 是没有 TxnID 的按照之前的 PCrdGrant 分配逻辑,如果某一个 transaction 先收到 PCrdGrant 再收到 RetryAck,这个 PCrdGrant 会丢失MMIO 和 cacheable 空间的 PCredit 应该放在一起仲裁MMIO 的 rxrsp 分配到哪一项 MMIO entry 是根据 TxnID 来判断的,但是 PCrdGrant 是没有 TxnID 的按照之前的 PCrdGrant 分配逻辑,如果某一个 transaction 先收到 PCrdGrant 再收到 RetryAck,这个 PCrdGrant 会丢失 | 链接 | - |
8 | KMH22-1547 | TLB 中的 PLRU 替换算法替换了近期访问的 TLB 项,导致 TLB 的 gpf 处理过程被破坏,引发卡死TLB 中的 PLRU 替换算法替换了近期访问的 TLB 项,导致 TLB 的 gpf 处理过程被破坏,引发卡死 | 2024-12-02 | 24103001 | L1TLB 不存储物理地址(gpaddr),但在发生虚拟机页面错误(GPF)时,gpaddr 是必须的。在这种情况下,L1TLB 需要发送一个页面表查找(PTW)请求来获取 gpaddr,我们称之为 getGpa。getGpa 机制只能处理一个 GPF TLB 请求(即第一个请求),并且期望相应的 TLB 条目仍然存在于 L1TLB 中。L1TLB 替换使用的是 PLRU(伪最近最少使用)算法,这可能会替换一些未必是最近最少使用的条目。我们发现一个情况,L1TLB 替换了那个 GPF TLB 条目,尽管该条目最近才被访问。这导致了 getGpa 机制中的死锁问题,最终导致整个核心冻结。为了解决这个问题,我们决定在 getGpa 机制工作时(即需要 gpaddr 时)阻止任何无关的 PTW 填充。在解决了这个问题后,我们发现,在某些情况下,其他的 PTW 响应没有被填充,其他 TLB 请求继续响应,触发 PTW 请求并占用 L2TLB 请求路径,阻止了 GPF PTW 请求的响应,最终导致处理器冻结。为了解决这个问题,我们决定在需要 gpaddr 时阻止任何无关的 PTW 请求L1TLB 不存储物理地址(gpaddr),但在发生虚拟机页面错误(GPF)时,gpaddr 是必须的。在这种情况下,L1TLB 需要发送一个页面表查找(PTW)请求来获取 gpaddr,我们称之为 getGpa。getGpa 机制只能处理一个 GPF TLB 请求(即第一个请求),并且期望相应的 TLB 条目仍然存在于 L1TLB 中。L1TLB 替换使用的是 PLRU(伪最近最少使用)算法,这可能会替换一些未必是最近最少使用的条目。我们发现一个情况,L1TLB 替换了那个 GPF TLB 条目,尽管该条目最近才被访问。这导致了 getGpa 机制中的死锁问题,最终导致整个核心冻结。为了解决这个问题,我们决定在 getGpa 机制工作时(即需要 gpaddr 时)阻止任何无关的 PTW 填充。在解决了这个问题后,我们发现,在某些情况下,其他的 PTW 响应没有被填充,其他 TLB 请求继续响应,触发 PTW 请求并占用 L2TLB 请求路径,阻止了 GPF PTW 请求的响应,最终导致处理器冻结。为了解决这个问题,我们决定在需要 gpaddr 时阻止任何无关的 PTW 请求 | 链接 | - |
9 | KMH22-1572 | Xvisor无法正确处理gpf,造成死循环Xvisor无法正确处理gpf,造成死循环 | 2024-11-14 | 24110801 | L1TLB增加了跨页时gpaddr的处理逻辑,但仅考虑了DTLB的情况,没有考虑到ITLB并不适用fullva等相关通路,使得例外时错误地传递了0作为htval。xvisor的例外处理程序依赖于htval来处理GPF例外,错误的htval使其卡死L1TLB增加了跨页时gpaddr的处理逻辑,但仅考虑了DTLB的情况,没有考虑到ITLB并不适用fullva等相关通路,使得例外时错误地传递了0作为htval。xvisor的例外处理程序依赖于htval来处理GPF例外,错误的htval使其卡死 | 链接 | - |
10 | KMH22-1786 | RTL在某些不可能修改向量状态的指令仍然将vs设置为dirtyRTL在某些不可能修改向量状态的指令仍然将vs设置为dirty | 2024-12-01 | 24111901 | do not set vs.dirty for some type of vecInstsdo not set vs.dirty for some type of vecInsts | 链接 | - |
11 | KMH22-1824 | vset不应该响应时钟中断,而vset被标记为了interrupt_safevset不应该响应时钟中断,而vset被标记为了interrupt_safe | 2024-12-07 | 24111901 | 修改 vset不响应时钟中断修改 vset不响应时钟中断 | 链接 | - |
12 | KMH22-1844 | 前端跨页取指令时例外处理错误前端跨页取指令时例外处理错误 | 2024-12-01 | 24112601 | 应该是ebsin的问题应该是ebsin的问题 | 链接 | - |
13 | KMH22-1861 | 非 V 模式下读取 vsie/vsip 和 V 模式下读取 sie/sip 的问题非 V 模式下读取 vsie/vsip 和 V 模式下读取 sie/sip 的问题 | 2024-12-06 | 24120301 | 当主机发生 VS 中断时,VM 会发生 S 中断。因此中断号需要同步。修复非 V 模式下读取 vsie/vsip 和 V 模式下读取 sie/sip 的问题。我们通过写入 mstatus/sstatus/vsstatus 的相应位来启用中断,因此我们需要在写入它们时更新 xtopi。徐泽凡L1TLB 尽管已经采取措施在 need_gpf 时请求阻止 ptw 回填,但在 need_gpf 即将拉高时未能阻止卡点进入的 ptw 回填请求当主机发生 VS 中断时,VM 会发生 S 中断。因此中断号需要同步。修复非 V 模式下读取 vsie/vsip 和 V 模式下读取 sie/sip 的问题。我们通过写入 mstatus/sstatus/vsstatus 的相应位来启用中断,因此我们需要在写入它们时更新 xtopi。徐泽凡L1TLB 尽管已经采取措施在 need_gpf 时请求阻止 ptw 回填,但在 need_gpf 即将拉高时未能阻止卡点进入的 ptw 回填请求 | 链接 | - |
14 | KMH22-1872 | vecExcpInfo.valid在中断来临时错误更新vecExcpInfo.valid在中断来临时错误更新 | 2024-12-06 | 24120301 | Rob 中,`vecExcpInfo.valid := exceptionHappen && exceptionDataRead.bits.vstartEn && exceptionDataRead.bits.isVecLoad && !exceptionDataRead.bits.isEnqExcp`。当该信号为高电平时,代表需要处理向量访存相关异常。此时,`backend`下的一个子模块`vecExcpMod`会进入一个状态机,暂时阻塞指令进入`Dispatch`。然而,当发生中断时,`exceptionHappen`也会为高电平,此时`exceptionDataRead`中的数据为无效数据。如果无效数据恰好导致`vecExcpInfo.valid`为高电平,则会使`vecExcpMod`模块错误地阻塞指令进入`Dispatch`,导致卡死。因此需要给该信号的赋值排除掉中断的情形,改为`vecExcpInfo.valid := exceptionHappen && !intrEnable && exceptionDataRead.bits.vstartEn && exceptionDataRead.bits.isVecLoad && !exceptionDataRead.bits.isEnqExcp`即可Rob 中,`vecExcpInfo.valid := exceptionHappen && exceptionDataRead.bits.vstartEn && exceptionDataRead.bits.isVecLoad && !exceptionDataRead.bits.isEnqExcp`。当该信号为高电平时,代表需要处理向量访存相关异常。此时,`backend`下的一个子模块`vecExcpMod`会进入一个状态机,暂时阻塞指令进入`Dispatch`。然而,当发生中断时,`exceptionHappen`也会为高电平,此时`exceptionDataRead`中的数据为无效数据。如果无效数据恰好导致`vecExcpInfo.valid`为高电平,则会使`vecExcpMod`模块错误地阻塞指令进入`Dispatch`,导致卡死。因此需要给该信号的赋值排除掉中断的情形,改为`vecExcpInfo.valid := exceptionHappen && !intrEnable && exceptionDataRead.bits.vstartEn && exceptionDataRead.bits.isVecLoad && !exceptionDataRead.bits.isEnqExcp`即可 | 链接 | - |
15 | KMH22-1947 | 中断时,vecExcpInfo.valid被错误更新,导致vecExcpInfo.bits可能为未初始化的值,导致x态传播或随机卡死。中断时,vecExcpInfo.valid被错误更新,导致vecExcpInfo.bits可能为未初始化的值,导致x态传播或随机卡死。 | 2024-12-06 | 24101101 | `vecExcpInfo.valid := exceptionHappen && exceptionDataRead.bits.vstartEn && exceptionDataRead.bits.isVecLoad && !exceptionDataRead.bits.isEnqExcp`。当该信号为高电平时,代表需要处理向量访存相关异常。此时,`backend`下的一个子模块`vecExcpMod`会进入一个状态机,暂时阻塞指令进入`Dispatch`。然而,当发生中断时,`exceptionHappen`也会为高电平,此时`exceptionDataRead`中的数据为无效数据。如果无效数据恰好导致`vecExcpInfo.valid`为高电平,则会使`vecExcpMod`模块错误地阻塞指令进入`Dispatch`,导致卡死。因此需要给该信号的赋值排除掉中断的情形,改为`vecExcpInfo.valid := exceptionHappen && !intrEnable && exceptionDataRead.bits.vstartEn && exceptionDataRead.bits.isVecLoad && !exceptionDataRead.bits.isEnqExcp`即可`vecExcpInfo.valid := exceptionHappen && exceptionDataRead.bits.vstartEn && exceptionDataRead.bits.isVecLoad && !exceptionDataRead.bits.isEnqExcp`。当该信号为高电平时,代表需要处理向量访存相关异常。此时,`backend`下的一个子模块`vecExcpMod`会进入一个状态机,暂时阻塞指令进入`Dispatch`。然而,当发生中断时,`exceptionHappen`也会为高电平,此时`exceptionDataRead`中的数据为无效数据。如果无效数据恰好导致`vecExcpInfo.valid`为高电平,则会使`vecExcpMod`模块错误地阻塞指令进入`Dispatch`,导致卡死。因此需要给该信号的赋值排除掉中断的情形,改为`vecExcpInfo.valid := exceptionHappen && !intrEnable && exceptionDataRead.bits.vstartEn && exceptionDataRead.bits.isVecLoad && !exceptionDataRead.bits.isEnqExcp`即可 | 链接 | - |
16 | KMH22-1957 | IF 在特定预取冲刷时未能同步冲刷 ITLB,导致 ITLB 陷入 need_gpf 状态而等不到之前的请求IF 在特定预取冲刷时未能同步冲刷 ITLB,导致 ITLB 陷入 need_gpf 状态而等不到之前的请求 | 2024-12-09 | 24120301 | IF 在特定预取冲刷时未能同步冲刷 ITLB,导致 ITLB 陷入 need_gpf 状态而等不到之前的请求IF 在特定预取冲刷时未能同步冲刷 ITLB,导致 ITLB 陷入 need_gpf 状态而等不到之前的请求 | 链接 | - |
17 | KMH22-1968 | 使用了错误idx来选择ecc使用了错误idx来选择ecc | 2024-12-12 | 24120901 | 使用了错误idx来选择ecc使用了错误idx来选择ecc | 链接 | - |
18 | KMH22-1971 | vecExceptionFlag标记位置位条件出错vecExceptionFlag标记位置位条件出错 | 2025-01-13 | 24120901 | vecExceptionFlag标记位置位条件出错vecExceptionFlag标记位置位条件出错 | 链接 | - |