seL4 Faults(八)

Faults

  • 学习什么是线程错误
  • 理解线程错误和处理器硬件错误是不同的
  • 理解什么是错误处理器
  • 理解内核对于一个有错误的线程做了什么
  • 了解如何设置内核将在其上传递故障消息的端点(master与 MCS)。
  • 在错误故障后学习如何恢复线程。

Background: What is a fault, and what is a fault handler?

故障处理程序是一个单独的指令流,CPU 可以跳转到该指令流以纠正当前线程中的异常情况,然后返回到前一个指令流。
在 seL4 中,故障被建模为由程序员指定的独立“故障处理”线程。在宏内核中,故障通常不会传递给用户空间的处理程序,而是由宏内核本身处理。
一般来说,尝试恢复执行故障线程而不纠正异常只会无限地重新触发故障,直到异常被清除。

Thread faults vs other sources of faults

运行中的系统有多种故障来源;它们包括:

  • 当 CPU 在指令流中遇到异常(也称为“处理器异常”)时,CPU 本身会生成故障事件。
  • 发生某些硬件异常(例如机器检查或不可屏蔽中断)时,硬件产生的故障事件。
  • 当当前线程遇到异常时,seL4 内核生成的故障事件。

本教程仅关注 seL4 内核生成的那些故障事件。从这里开始,我们将把它们称为“线程错误”,以减少歧义。

How does thread fault handling work?

在 seL4 中,当线程生成线程故障时,内核将阻止故障线程的执行,并尝试通过与该线程关联的特殊端点(称为“fault handler”endpoint)传递消息。
故障处理程序端点的唯一特殊之处是一个线程只能拥有其中一个。否则,它的创建和管理方式与任何其他类型的 seL4 端点对象相同。
在故障端点另一端侦听的线程称为“故障处理程序”。内核期望故障处理程序将纠正导致故障线程的异常,然后告诉内核何时可以安全地再次尝试执行故障线程。
要告诉内核恢复故障线程的执行,故障处理程序可以:

  • 在故障处理程序端点上调用回复操作(使用seL4_Reply())并确保seL4_MessageInfo_t标记中的标签设置为0;
  • 使用 seL4_TCB_Resume() 明确告诉内核恢复执行故障线程。

请注意,如果处理程序在回复消息中设置消息寄存器,内核可能会将这些解释为某种含义:某些故障回复接受参数。所有故障的回复消息格式请参见seL4手册
如果故障处理程序没有正确纠正故障线程中的异常,恢复故障线程只会导致内核重新生成故障。

Reasons for thread faults:

线程错误可能因不同的原因而产生。当发生故障时,内核会将描述故障原因的信息作为 IPC 消息传递。在撰写本文时,seL4 内核的 Master 版本可能会产生以下错误:

  • 能力故障:由于无效的能力访问而触发的故障。
  • VM 故障:页表状态不一致或线程访问内存不正确而引发的故障。
  • 未知系统调用故障:通过执行内核未知的系统调用调用而触发。
  • 调试故障:当发生断点、观察点或单步调试事件时触发。

此外,MCS内核还添加了以下故障类型:

  • 超时错误:当线程消耗完其所有预算并且当前期间仍有进一步执行要做时触发。

Thread fault messages:

当产生故障时,内核将通过故障端点传递 IPC 消息。该 IPC 消息包含告诉故障处理程序发生故障的原因的信息以及有关故障的周围上下文信息,这可能有助于故障处理程序纠正异常。
每个异常都有自己的消息格式,因为描述每个异常所需的信息会有所不同。有关seL4内核针对每个故障异常发送的IPC消息内容的更多信息,请参阅seL4手册。
本教程的其余部分将尝试教读者如何接收和处理 seL4 线程故障。

Setting up a fault endpoint for a thread:

在故障端点上传递故障消息的情况下,内核充当 IPC“发送者”,故障处理程序充当接收者。
这意味着当将能力分配给故障端点对象时,必须给内核分配一个指向该对象的能力,同时也必须给处理程序分配一个指向该对象的能力。

Kernel end vs handler end:

程序员在配置 TCB 时为线程指定使用故障处理程序的能力。因此,程序员还可以在内核能力上为故障端点对象设置一个徽章。
当内核使用带有标记的端点能力发送故障 IPC 消息时,该标记会以与发送方能力上有标记的任何其他 IPC 相同的方式传递到接收方。
敏锐的读者可能已经意识到,这意味着内核的故障端点能力上的标记可用于区分来自不同故障线程的故障消息,以便单个处理程序可以处理来自多个线程的故障。请参阅 IPC 教程,了解带有标记的故障端点的工作原理。

Differences between MCS and Master kernel:

主内核和 MCS 内核之间通知内核故障端点能力的方式存在细微差别。
不管怎样,在两个版本的内核上,要通知内核线程的故障端点,请调用通常的 seL4_TCB_SetSpace()。
有关详细信息,请参阅 MCS 教程。

Exercises

本教程有一个由 CapDL 加载程序设置的地址空间,其中包含共享同一 CSpace 的两个线程。其中一个线程是故障处理程序,而另一个线程则触发虚拟内存故障。
您将被引导完成以下主要步骤:

  1. 为故障线程添加标记并配置故障处理程序。
  2. 让故障线程触发线程故障。
  3. 在故障处理程序中处理故障。
  4. 恢复发生故障的线程的执行。

Description of the tutorial program:

本教程介绍了不同虚拟地址空间中的两个线程。一个线程是“故障者”,另一个线程是“处理程序”。错误者将生成错误,处理程序将“处理”它。
为了让处理程序能够处理故障,处理程序必须设置一个故障处理端点,并告诉内核将故障线程生成的所有故障 IPC 消息发送给自己。因此,这是我们采取的第一步。
然而,我们必须确保只有在处理程序线程设置了故障处理端点并准备好从内核接收故障IPC消息之后才会触发故障。
如果故障线程产生故障并且没有线程来处理IPC消息,则内核将简单地挂起故障线程。
因此,我们将故障线程 seL4_call() 设置为跨端点的处理程序线程,并告诉它处理程序应将故障处理端点能力放入哪个槽中。在处理程序设置了处理程序端点后,处理程序将向故障者发送seL4_Reply(),让其知道处理程序已准备好处理故障IPC消息。
之后,我们在错误器中触发错误,在处理程序中处理错误,然后恢复错误器,练习就结束了。

Setting up the endpoint to be used for thread fault IPC messages.(设置用于线程故障IPC消息的端点)

第一个练习是使用故障端点配置故障器的 TCB。这项练习旨在实现两个学习成果:

  • 说明提供给内核的端点的末尾可以标记,并且当内核发送故障 IPC 消息时,内核将返回该标记值。
  • 解释 Master 内核和 MCS 内核在向内核告知故障端点方面的差异。

现在,故障线程被阻塞在端点上,等待处理程序告诉它将故障处理端点放在它自己的(故障者的)CSpace(对于主内核)中的位置
为了设置故障处理程序端点,我们首先要对其进行标记,以便当内核向我们发送故障 IPC 消息时,我们将能够识别故障者。故障处理程序可以处理来自多个线程的故障,因此徽章使处理程序能够识别他们正在处理的故障程序。
要标记端点,请使用 seL4_CNode_Mint() 系统调用:

error = seL4_CNode_Mint(handler_cspace_root,badged_faulter_fault_ep_cap,seL4_WordBits,handler_cspace_root,faulter_fault_ep_cap,seL4_WordBits,seL4_AllRights, FAULTER_BADGE_VALUE);

由于我们使用的是 Master 内核,因此您还需要将标记能力复制到故障者的 CSpace 中(有关配置故障端点时 Master 和 MCS 内核之间差异的说明,请参阅 MCS 教程):

 error = seL4_CNode_Copy(faulter_cspace_root,foreign_badged_faulter_empty_slot_cap,seL4_WordBits,handler_cspace_root,badged_faulter_fault_ep_cap,seL4_WordBits,seL4_AllRights);

最后,我们告诉内核故障端点的能力地址,以便内核可以将故障IPC消息传递给处理程序。由于我们使用的是 Master 内核,因此我们需要传递一个可以从错误线程的 CSpace 中解析的 CPtr:

error = seL4_TCB_SetSpace(faulter_tcb_cap,foreign_badged_faulter_empty_slot_cap,faulter_cspace_root,0,faulter_vspace_root,0);

在这里插入图片描述
简单来说上面的流程就是,先使用Mint方法复制一个端点能力,并赋予其徽章。然后使用copy方法将这个带徽章的能力复制到故障者的CSpace中,然后设置这个线程的故障端点、CSpace以及VSpace(当然这两个没有改变)。
为什么还能改变线程的能力空间和虚拟地址空间呢?虽然线程可能已经有一个 CSpace,但是 seL4_TCB_SetSpace 是用来显式地重新绑定或确认 CSpace 的根节点。在某些情况下,可能希望改变线程的 CSpace,或者确保线程可以在不同的能力空间上下文中执行。VSpace 代表线程的地址空间布局。当你调用 seL4_TCB_SetSpace 时,通过设置这个参数,你明确指定该线程使用哪个 VSpace。虽然在初始化线程时已经绑定了 VSpace,但在某些场景下可能需要更改它。例如,在虚拟化环境中,某些线程可能需要切换到不同的虚拟地址空间(不同的 VSpace)以访问不同的内存布局,或者在权限变化时需要重新指定 VSpace。

Receiving the IPC message from the kernel:

内核将会给等待在故障端点上的所有线程传递IPC消息。使用seL4_Recv()阻塞等待IPC消息,同样也可以用于等待其他的IPC消息:

foreign_faulter_capfault_cap = seL4_GetMR(seL4_CapFault_Addr);

Finding out information about the generated thread fault:

在线程故障IPC消息中,内核将发送有关故障的信息,包括访问触发线程故障的能力地址。 seL4 手册提供了有关 IPC 缓冲区中哪些消息寄存器包含有关故障的信息的详细信息,如果您愿意,libsel4 源代码也有确切的代码值。
在我们这里的示例中,我们的示例代码生成了一个 Cap 错误,因此根据 seL4 手册,我们可以使用 IPC 消息中的偏移量 seL4_CapFault_Addr 找到 Cap 错误地址,如上面的代码片段所示。所以,you know,seL4_CapFault_Addr 是已经定义好的常量。

Handling a thread fault:

现在我们知道了在故障线程中生成故障的能力地址,我们可以通过将随机能力放入该插槽来“处理”故障,然后当故障线程重新尝试访问该插槽时,这次它将成功并且不会产生线程错误。
因此,在这里我们将端点能力复制到故障槽中:

error = seL4_CNode_Copy(faulter_cspace_root,foreign_faulter_capfault_cap,seL4_WordBits,handler_cspace_root,sequencing_ep_cap,seL4_WordBits,seL4_AllRights);

Resuming a faulting thread:

最后,为了唤醒故障线程并尝试再次执行,我们对其进行 seL4_Reply() :

seL4_Reply(seL4_MessageInfo_new(0, 0, 0, 0));

贴出来handler的代码


#include <assert.h>
#include <stdio.h>
#include <sel4/sel4.h>
#include <utils/util.h>
#include <autoconf.h>#define FAULTER_BADGE_VALUE     (0xBEEF)
#define PROGNAME                "Handler: "
/* We signal on this notification to let the fauler know when we're ready to* receive its fault message.*/
extern seL4_CPtr sequencing_ep_cap;extern seL4_CPtr faulter_fault_ep_cap;extern seL4_CPtr handler_cspace_root;
extern seL4_CPtr badged_faulter_fault_ep_cap;extern seL4_CPtr faulter_tcb_cap;
extern seL4_CPtr faulter_vspace_root;
extern seL4_CPtr faulter_cspace_root;int main(void)
{int error;seL4_Word tmp_badge;seL4_CPtr foreign_badged_faulter_empty_slot_cap;seL4_CPtr foreign_faulter_capfault_cap;seL4_MessageInfo_t seq_msginfo;printf(PROGNAME "Handler thread running!\n"PROGNAME "About to wait for empty slot from faulter.\n");seq_msginfo = seL4_Recv(sequencing_ep_cap, &tmp_badge);foreign_badged_faulter_empty_slot_cap = seL4_GetMR(0);printf(PROGNAME "Received init sequence msg: slot in faulter's cspace is ""%lu.\n",foreign_badged_faulter_empty_slot_cap);/* Mint the fault ep with a badge */error = seL4_CNode_Mint(handler_cspace_root,badged_faulter_fault_ep_cap,seL4_WordBits,handler_cspace_root,/* EXERCISE: Which capability should be the source argument here? */faulter_fault_ep_cap,seL4_WordBits,seL4_AllRights, FAULTER_BADGE_VALUE);ZF_LOGF_IF(error != 0, PROGNAME "Failed to mint ep cap with badge!");printf(PROGNAME "Successfully minted fault handling ep into local cspace.\n");/* This step is only necessary on the master kernel. On the MCS kernel it* can be skipped because we do not need to copy the badged fault EP into* the faulting thread's cspace on the MCS kernel.*/error = seL4_CNode_Copy(faulter_cspace_root,/* EXERCISE: What should the destination be for this cap copy? */foreign_badged_faulter_empty_slot_cap,seL4_WordBits,handler_cspace_root,badged_faulter_fault_ep_cap,seL4_WordBits,seL4_AllRights);ZF_LOGF_IF(error != 0, PROGNAME "Failed to copy badged ep cap into faulter's cspace!");printf(PROGNAME "Successfully copied badged fault handling ep into ""faulter's cspace.\n"PROGNAME "(Only necessary on Master kernel.)\n");error = seL4_TCB_SetSpace(faulter_tcb_cap,foreign_badged_faulter_empty_slot_cap,faulter_cspace_root,0,faulter_vspace_root,0);seL4_Reply(seL4_MessageInfo_new(0, 0, 0, 0));// handler阻塞等待在自己的badged端点上面seL4_Recv(badged_faulter_fault_ep_cap,&tmp_badge);foreign_faulter_capfault_cap = seL4_GetMR(seL4_CapFault_Addr);error = seL4_CNode_Copy(faulter_cspace_root,foreign_faulter_capfault_cap,seL4_WordBits,handler_cspace_root,sequencing_ep_cap,seL4_WordBits,seL4_AllRights);seL4_Reply(seL4_MessageInfo_new(0, 0, 0, 0));return 0;
}

最后输出如下:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1560162.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

SROP验证

文章目录 SROPsignal机制 SROP的利用原理&#xff1a;获取shellsystem call chains条件&#xff1a;sigreturn 测试 例题&#xff1a; SROP signal机制 signal 机制是类 unix 系统中进程之间相互传递信息的一种方法。一般&#xff0c;我们也称其为软中断信号&#xff0c;或者软…

【onnx模型转kmodel】记录和踩坑——nncase-v1.9使用

最近几天一直在找相关资料&#xff0c;坑太多&#xff0c;也可能我菜的成分更多一点吧&#xff01;记录下来&#xff0c;以观后用&#xff1b; 背景 我手里有一个正点原子的K210的开发板&#xff1b; 刚刚安装了wsl2下的ubuntu22.04 我手里有正点原子的源码&#xff0c;但是…

项目管理监控难题解析:为何监控至关重要

项目管理中的监控环节常常被视为一项艰巨的任务&#xff0c;但它却是确保项目成功的关键所在。为何监控在项目管理中如此重要呢&#xff1f;让我们一同深入解析这个难题。 一、目前项目管理监控存在的问题 在项目管理的实践中&#xff0c;监控环节常常暴露出一系列问题&#x…

西门子S7-SMART运动控制向导

打开“运动控制”向导&#xff0c;“工具”->“向导”->“运动控制” 图 1.打开“运动控制”向导 选择需要配置的轴 图 2.选择需要配置的轴 为所选择的轴命名 图 3.为所选择的轴命名 输入系统的测量系统&#xff08;“工程量”或者“脉冲数/转”&#xff…

u_boot内核编译-生成uImage

内核编译 顶层目录&#xff0c;都在这个目录下进行操作 这是我们芯片的默认配置文件 第一步 拷贝一个默认的配置 以下两张是def文件内容 第二步 &#xff1a;打开可视化界面&#xff0c;前面的* 需要用空格点击两下&#xff0c;不改变原设置&#xff0c;大那是需要进行编辑操…

PDF全能免费转换 3.15 | 多功能PDF处理工具

主打就是免费好用&#xff01;1. PDF转Word/PPT/Excel/txt、图片等&#xff1b;2. PDF压缩、合并&#xff1b;3. 多图合并成长图、合并成PDF&#xff1b;4. 身份证扫描、文件扫描、证件扫描等&#xff1b;5. 证件照换底色&#xff1b;6. 热门tab页&#xff1b;7. 美化照片。 大…

【LLM论文日更】| BGE-M3E embedding模型

论文&#xff1a;https://arxiv.org/pdf/2402.03216代码&#xff1a;GitHub - FlagOpen/FlagEmbedding: Retrieval and Retrieval-augmented LLMs机构&#xff1a;BAAI领域&#xff1a;embedding model发表&#xff1a; ​ 研究背景 研究问题&#xff1a;这篇文章要解决的问…

(JAVA)熟悉队列的进阶结构 - 优先队列

1. 优先队列 ​ 普通队列是一种先进先出的数据结构&#xff0c;元素在队列尾追加&#xff0c;而从队列头删除。 ​ 在某些情况下&#xff0c;我们可能需要找出队列中的最大值或者最小值&#xff0c;例如使用一个队列保存计算机的任务&#xff0c;一般情况下计算机的任务都是有…

pytest框架之fixture测试夹具详解

前言 大家下午好呀&#xff0c;今天呢来和大家唠唠pytest中的fixtures夹具的详解&#xff0c;废话就不多说了咱们直接进入主题哈。 一、fixture的优势 ​ pytest框架的fixture测试夹具就相当于unittest框架的setup、teardown&#xff0c;但相对之下它的功能更加强大和灵活。 …

谁说电商选品找货源没有捷径,只要你用对工具!

最近跟很多同行聊&#xff0c;都在抱怨选品难的问题&#xff0c;都说7分靠选品&#xff0c;3分靠运营&#xff0c;对于选品来说&#xff0c;并没有捷径可走&#xff0c;但其实是有很多不同的角度的。 现在市面上大部分开发做的选品&#xff0c;“选品方法”或“产品分析方法”…

【含文档】基于Springboot+Android的校园论坛系统(含源码+数据库+lw)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 系统定…

前端省市区组件

官网 Element UI 级联 中国省市区数据. Latest version: 5.0.2, last published: 2 years ago. Start using element-china-area-data in your project by running npm i element-china-area-data. There are 114 other projects in the npm registry using element-china-are…

SpringBoot开发——SpringSecurity安全框架17个业务场景案例(三)

文章目录 一、Spring Security 常用应用场景介绍二、Spring Security场景案例12 表达式支持(Expression-Based)12.1 Spring Security 配置12.2 业务逻辑代码12.3 控制器13、安全上下文(Security Context)13.1 Spring Security 配置13.2 业务逻辑代码13.3 控制器14、安全过滤…

Python入门笔记(四)

文章目录 第九章 集合set9.1 创建集合&#xff1a;set()、集合生成式9.2 集合性质9.3 一些函数&#xff1a;issubset()、issuperset()、isdisjoint()9.4 集合增加元素&#xff1a;add()、update()9.5 集合删除元素&#xff1a;remove()、discard()、pop()、clear()9.6 创建不能…

用IntStream生成0到n的流,并找出不在numSet中的数字列表

这是用IntStream生成0到n的流&#xff0c;并找出不在numSet中的数字-CSDN博客的升级版 给你一个含 n 个整数的数组 nums &#xff0c;其中 nums[i] 在区间 [1, n] 内。请你找出所有在 [1, n] 范围内但没有出现在 nums 中的数字&#xff0c;并以数组的形式返回结果。 先看这题低…

数据结构与算法——Java实现 32.堆

人的想法和感受是会随着时间的认知改变而改变&#xff0c; 原来你笃定不会变的事&#xff0c;也会在最后一刻变得释然 —— 24.10.10 堆 堆是基于二叉树实现的数据结构 大顶堆每个分支的上一个节点的权值要大于它的孩子节点 小顶堆每个分支的上一个节点的权值要小于它的孩子…

Linux系统通过编辑crontab来设置定时任务---定时关机

在Linux系统中&#xff0c;crontab 是用来设置周期性被执行的指令的守护进程。通过编辑 crontab&#xff0c;您可以安排定时任务&#xff0c;比如定时关机、定时备份文件、定时运行脚本等。以下是如何编辑 crontab 来设置定时任务的步骤&#xff1a; 打开终端&#xff1a;您可以…

25.第二阶段x86游戏实战2-背包属性补充

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 本人写的内容纯属胡编乱造&#xff0c;全都是合成造假&#xff0c;仅仅只是为了娱乐&#xff0c;请不要…

k8s 1.28.2 集群部署 MinIO 分布式存储

文章目录 [toc]MinIO 介绍MinIO 生产硬件要求MinIO 存储要求MinIO 内存要求MinIO 网络要求MinIO 部署架构分布式 MinIO复制的 MinIO 部署 MinIO创建目录节点打标签创建 namespace创建 pv创建 MinIO配置 ingress问题记录通过代理服务器访问 MinIO 的 Object Browser 界面一直显示…

免费获取的8个SVG图标库,轻松下载与复制!

SVG图标相比传统的JPG、PNG图标具有诸多优势&#xff0c;适用于各种类型的图像&#xff0c;不仅能在不同尺寸下保持清晰度&#xff0c;还具备高度压缩性和轻量特性&#xff0c;支持静态和动态效果。因此&#xff0c;SVG格式在网页设计中往往是优选。尽管如今有很多免费的图标库…