seL4 Faults(八)

news2024/10/10 22:41:50

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.coloradmin.cn/o/2203373.html

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

相关文章

(21)Nakagami-m分布及其参数的意义

文章目录 前言一、Nakagami衰落的定义二、Nakagami衰落的形状参数m三、Nakagami衰落的尺度参数ω四、Nakagami随机变量的生成 前言 在无线信道中&#xff0c;由于电波的多径传播效应&#xff0c;接收到的信号强度会因为多条传播路径的相长或相消而发生起伏变化。这种现象被称为…

mysql迁移到达梦数据库报错:参数不兼容

1: 这个错误可能是某个字段‘定义超长’&#xff0c;尝试&#xff1a; 2: 如果还报错&#xff0c;指定和mysql同版本驱动

树状数组——学习心得

可以解决大部分区间上面的修改以及查询的问题&#xff0c;例如1.单点修改&#xff0c;单点查询&#xff0c;2.区间修改&#xff0c;单点查询&#xff0c;3.区间查询&#xff0c;区间修改&#xff0c;换言之&#xff0c;线段树能解决的问题&#xff0c;树状数组大部分也可以&…

全栈开发笔记

1.后端没问题 前端不显示返回数据&#xff1f; 返回数据被&#xff0c;axios拦截器拦截了 2.路径跳转显示空白&#xff1f; 没有配置router 3.后端部署到服务器上 无法通过外网访问接口&#xff1f; 检查服务器防火墙设置 即使服务监听正确&#xff0c;服务器本身的防火墙也可能…

【工作流引擎集成】springboot+Vue+activiti+mysql带工作流集成系统,直接用于业务开发,流程设计,工作流审批,会签

前言 activiti工作流引擎项目&#xff0c;企业erp、oa、hr、crm等企事业办公系统轻松落地&#xff0c;一套完整并且实际运用在多套项目中的案例&#xff0c;满足日常业务流程审批需求。 一、项目形式 springbootvueactiviti集成了activiti在线编辑器&#xff0c;流行的前后端…

前端_002_CSS扫盲

文章目录 概念选择器常用属性背景边框高度和宽度颜色文本字体链接表格里对齐显示相关溢出&#xff0c;滚动条属性 伪类和伪元素 概念 1.书写格式&#xff1a; 选择器{ 属性名:属性值 ; 属性名:属性值 ; } 2.文件后缀.css 选择器 元素选择器 [tag] id选择器 #[id_name] c…

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

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

开机启动项在哪里关闭?五个全面指南,教你关闭开机启动项!(新)

您是否发现您的电脑运行性能正在受一些无关紧要的应用程序所影响呢&#xff1f;也许您没有意识到&#xff0c;每当您登录电脑时&#xff0c;许多程序会在不知情的情况下自动启动。这些自动启动的程序不仅会拖慢系统的运行速度&#xff0c;还会占用大量的内存和cpu资源。为了改善…

QT:绘制事件和定时器

1.绘制时针 xx.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTimer> #include<QPainter> #include <QTime>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpubl…

YOLOv11进行图像与视频的目标检测

一、AI应用系统实战项目 项目名称项目名称1.人脸识别与管理系统2.车牌识别与管理系统3.手势识别系统4.人脸面部活体检测系统5.YOLOv8自动标注6.人脸表情识别系统7.行人跌倒检测系统8.PCB板缺陷检测系统9.安全帽检测系统10.生活垃圾分类检测11.火焰烟雾检测系统12.路面坑洞检测…

使用Qt Creator创建项目

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 使用Qt Creator创建项目 收录于专栏【Qt开发】 本专栏旨在分享学习Qt的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录 温馨提示: 1. 新…

Fastjson反序列化

Fastjson反序列化一共有三条利用链 TempLatesImpl&#xff1a;实战中不适用JdbcRowSetImpl&#xff1a;实际运用中较为广泛BasicDataSource&#xff08;BCEL&#xff09; 反序列化核心 反序列化是通过字符串或字节流&#xff0c;利用Java的反射机制重构一个对象。主要有两种…

Spring Boot 进阶-详解Spring Boot与其他框架整合

通过前面的文章,我们了解到了Spring、Spring Boot框架都是为Java企业级开发提供了一个基础框架,我们可以通过这个基础框架去整合其他的框架来实现我们具体的业务功能。 在网站上搜索一下,Spring Boot整合某某框架就会出现大量的教程,但是总会有一天你会遇到一个你没有教程的…

jenkins中的allure和email问题梳理

一、allure相关 1、我安装了jenkins之后需要再安装allure吗&#xff1f;在jenkins插件中心直接安装allure 1.Allure Jenkins Plugin 只是一个集成插件&#xff0c;它要求你在 Jenkins 服务器上安装 Allure 命令行工具&#xff08;Allure Commandline&#xff09;来实际生成报…

真的有被Transformer多头注意力惊艳到…

在这篇文章中&#xff0c;我们将深入探讨 Transformer 的核心部分-多头注意力&#xff08;Multi-head Attention&#xff09;。 这个机制能让 Transformer 同时从多个角度理解数据&#xff0c;提高处理信息的能力和效率。 01、Transformer 中如何使用注意力机制 Transformer…

[数据结构]带头双向循环链表的实现与应用

文章目录 一、引言二、链表的基本概念1、链表是什么2、链表与顺序表的区别3、带头双向循环链表 三、带头双向循环链表的实现1、结构体定义2、初始化3、销毁4、显示5、增删查改 四、分析带头双向循环链表1、存储方式2、优点3、缺点 五、总结1、练习题2、源代码 一、引言 链表作…

修复PDF打印速度慢

详细问题&#xff1a; 当您尝试将 PDF 文件打印到本地或网络打印机时&#xff0c;打印需要很长时间&#xff0c;因为发送打印作业后&#xff0c;打印机开始打印的速度非常慢&#xff0c;在打印任务中可以看到打印传输的数据在缓慢增长。 从其他程序打印时也不会出现打印速度慢…

c++的web框架Restbed介绍及在嵌入式Linux下的移植详解

随着物联网和嵌入式设备的普及&#xff0c;开发高性能的网络服务变得愈发重要。Restbed是一个用于构建RESTful APIs的轻量级C框架&#xff0c;因其简洁而强大的特性&#xff0c;成为开发者的热门选择。本文将介绍Restbed框架及其在嵌入式Linux平台上的移植方法。 一、Restbed框…

东方博宜 1176. 素数问题

东方博宜 1176. 素数问题 #include<iostream> using namespace std; int main() { int n ;while(cin >> n && n!0) {int count_n ;count_n 0 ;int k ;for( k 1 ; k < n ; k){int count_k ;count_k 0 ;int j ;for( j 2 ; j < k ; j){if (k % j …

基于SSM的大学生勤工助学管理系统(含源码+sql+视频导入教程+文档+PPT)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 基于SSM的大学生勤工助学管理系统1拥有三种角色&#xff1a;管理员、学生和用工部门&#xff0c;具体功能如下 1.1 背景描述 基于SSM框架&#xff08;SpringSpring MVCMyBatis&#xff09…