From 4dc0eab5a04d7b5698522dfb2ddfb8b0974c52b4 Mon Sep 17 00:00:00 2001 From: Amos Albert <47343901+Albertchamberlain@users.noreply.github.com> Date: Tue, 12 May 2020 18:58:56 +0800 Subject: [PATCH 1/5] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7571a69..8221455 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ |└ [2.10](https://github.com/MintCN/linux-insides-zh/blob/master/Initialization/linux-initialization-10.md)||未开始| | 3. [Interrupts](https://github.com/MintCN/linux-insides-zh/tree/master/Interrupts)||正在进行| |├ [3.0](https://github.com/MintCN/linux-insides-zh/blob/master/Interrupts/README.md)|[@littleneko](https://github.com/littleneko)|更新至[57279321](https://github.com/0xAX/linux-insides/commit/5727932167a2ff6a1e647081c85d081d4ed8b508)| -|├ [3.1](https://github.com/MintCN/linux-insides-zh/blob/master/Interrupts/linux-interrupts-1.md)||未开始| +|├ [3.1](https://github.com/MintCN/linux-insides-zh/blob/master/Interrupts/linux-interrupts-1.md)||正在进行| |├ [3.2](https://github.com/MintCN/linux-insides-zh/blob/master/Interrupts/linux-interrupts-2.md)|[@narcijie](https://github.com/narcijie)|更新至[4d635117](https://github.com/0xAX/linux-insides/commit/4d6351172486e5c046a7d3db2286fc0d0d0d7789)| |├ [3.3](https://github.com/MintCN/linux-insides-zh/blob/master/Interrupts/linux-interrupts-3.md)||未开始| |├ [3.4](https://github.com/MintCN/linux-insides-zh/blob/master/Interrupts/linux-interrupts-4.md)||未开始| From 6caee5f0e3ee85e38e22791e5ce884711e76b02d Mon Sep 17 00:00:00 2001 From: Amos Albert <47343901+Albertchamberlain@users.noreply.github.com> Date: Tue, 12 May 2020 19:14:02 +0800 Subject: [PATCH 2/5] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8221455..7571a69 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ |└ [2.10](https://github.com/MintCN/linux-insides-zh/blob/master/Initialization/linux-initialization-10.md)||未开始| | 3. [Interrupts](https://github.com/MintCN/linux-insides-zh/tree/master/Interrupts)||正在进行| |├ [3.0](https://github.com/MintCN/linux-insides-zh/blob/master/Interrupts/README.md)|[@littleneko](https://github.com/littleneko)|更新至[57279321](https://github.com/0xAX/linux-insides/commit/5727932167a2ff6a1e647081c85d081d4ed8b508)| -|├ [3.1](https://github.com/MintCN/linux-insides-zh/blob/master/Interrupts/linux-interrupts-1.md)||正在进行| +|├ [3.1](https://github.com/MintCN/linux-insides-zh/blob/master/Interrupts/linux-interrupts-1.md)||未开始| |├ [3.2](https://github.com/MintCN/linux-insides-zh/blob/master/Interrupts/linux-interrupts-2.md)|[@narcijie](https://github.com/narcijie)|更新至[4d635117](https://github.com/0xAX/linux-insides/commit/4d6351172486e5c046a7d3db2286fc0d0d0d7789)| |├ [3.3](https://github.com/MintCN/linux-insides-zh/blob/master/Interrupts/linux-interrupts-3.md)||未开始| |├ [3.4](https://github.com/MintCN/linux-insides-zh/blob/master/Interrupts/linux-interrupts-4.md)||未开始| From 36438a63acdd733dc921b627765e95cde1a1dd38 Mon Sep 17 00:00:00 2001 From: Albertchamberlain <2476271447@qq.com> Date: Tue, 12 May 2020 19:21:10 +0800 Subject: [PATCH 3/5] =?UTF-8?q?<=E6=9B=B4=E6=96=B0ReadMe=E7=8A=B6=E6=80=81?= =?UTF-8?q?>?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7571a69..8221455 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ |└ [2.10](https://github.com/MintCN/linux-insides-zh/blob/master/Initialization/linux-initialization-10.md)||未开始| | 3. [Interrupts](https://github.com/MintCN/linux-insides-zh/tree/master/Interrupts)||正在进行| |├ [3.0](https://github.com/MintCN/linux-insides-zh/blob/master/Interrupts/README.md)|[@littleneko](https://github.com/littleneko)|更新至[57279321](https://github.com/0xAX/linux-insides/commit/5727932167a2ff6a1e647081c85d081d4ed8b508)| -|├ [3.1](https://github.com/MintCN/linux-insides-zh/blob/master/Interrupts/linux-interrupts-1.md)||未开始| +|├ [3.1](https://github.com/MintCN/linux-insides-zh/blob/master/Interrupts/linux-interrupts-1.md)||正在进行| |├ [3.2](https://github.com/MintCN/linux-insides-zh/blob/master/Interrupts/linux-interrupts-2.md)|[@narcijie](https://github.com/narcijie)|更新至[4d635117](https://github.com/0xAX/linux-insides/commit/4d6351172486e5c046a7d3db2286fc0d0d0d7789)| |├ [3.3](https://github.com/MintCN/linux-insides-zh/blob/master/Interrupts/linux-interrupts-3.md)||未开始| |├ [3.4](https://github.com/MintCN/linux-insides-zh/blob/master/Interrupts/linux-interrupts-4.md)||未开始| From 95bc785248ed94f497ea753176b99f453a78d780 Mon Sep 17 00:00:00 2001 From: Albertchamberlain <2476271447@qq.com> Date: Tue, 12 May 2020 19:49:24 +0800 Subject: [PATCH 4/5] =?UTF-8?q?<=E4=B8=8A=E6=B8=B83.1=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E5=90=8E=E7=9A=84=E4=B8=AD=E6=96=87=E7=89=88=E6=9C=AC>?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Interrupts/linux-interrupts-1.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/Interrupts/linux-interrupts-1.md b/Interrupts/linux-interrupts-1.md index 4eeafd7..257a290 100644 --- a/Interrupts/linux-interrupts-1.md +++ b/Interrupts/linux-interrupts-1.md @@ -37,7 +37,7 @@ Introduction BUG_ON((unsigned)n > 0xFF); ``` -你可以在 Linux 内核源码中关于中断设置的地方找到这个检查(例如:`set_intr_gate`, `void set_system_intr_gate` 在 [arch/x86/include/asm/desc.h](https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/desc.h)中)。从 `0` 到 `31` 的 32 个中断标识码被处理器保留,用作处理架构定义的异常和中断。你可以在 Linux 内核初始化程序的第二部分 - [早期中断和异常处理](http://xinqiu.gitbooks.io/linux-insides-cn/content/Initialization/linux-initialization-2.html)中找到这个表和关于这些中断标识码的描述。从 `32` 到 `255` 的中断标识码设计为用户定义中断并且不被系统保留。这些中断通常分配给外部 I/O 设备,使这些设备可以发送中断给处理器。 +你可以在 Linux 内核源码中关于中断设置的地方找到这个定义(例如:`set_intr_gate`, `void set_system_intr_gate` 在 [arch/x86/include/asm/desc.h](https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/desc.h)中)。从 `0` 到 `31` 的 32 个中断标识码被处理器保留,用作处理架构定义的异常和中断。你可以在 Linux 内核初始化程序的第二部分 - [早期中断和异常处理](http://xinqiu.gitbooks.io/linux-insides-cn/content/Initialization/linux-initialization-2.html)中找到这个表和关于这些中断标识码的描述。从 `32` 到 `255` 的中断标识码设计为用户定义中断并且不被系统保留。这些中断通常分配给外部 I/O 设备,使这些设备可以发送中断给处理器。 现在,我们来讨论中断的类型。笼统地来讲,我们可以把中断分为两个主要类型: @@ -381,12 +381,14 @@ void load_percpu_segment(int cpu) ... ... ... - loadsegment(gs, 0); - wrmsrl(MSR_GS_BASE, (unsigned long)per_cpu(irq_stack_union.gs_base, cpu)); + __loadsegment_simple(gs, 0); + wrmsrl(MSR_GS_BASE, cpu_kernelmode_gs_base(cpu)); + ... + load_stack_canary_segment(); } ``` -就像我们所知道的一样,`gs` 寄存器指向中断栈的栈底: +正如我们所知的一样,`gs` 寄存器指向中断栈的栈底: ```assembly movl $MSR_GS_BASE,%ecx @@ -394,14 +396,14 @@ void load_percpu_segment(int cpu) movl initial_gs+4(%rip),%edx wrmsr - GLOBAL(initial_gs) - .quad INIT_PER_CPU_VAR(irq_stack_union) +SYM_DATA(initial_gs, +.quad INIT_PER_CPU_VAR(fixed_percpu_data)) ``` -现在我们可以看到 `wrmsr` 指令,这个指令从 `edx:eax` 加载数据到 被 `ecx` 指向的[MSR寄存器]((http://en.wikipedia.org/wiki/Model-specific_register))。在这里MSR寄存器是 `MSR_GS_BASE`,它保存了被 `gs` 寄存器指向的内存段的基址。`edx:eax` 指向 `initial_gs` 的地址,它就是 `irq_stack_union` 的基址。 +现在我们可以看到 `wrmsr` 指令,这个指令从 `edx:eax` 加载数据到 被 `ecx` 指向的[MSR寄存器]((http://en.wikipedia.org/wiki/Model-specific_register))。在这里MSR寄存器是 `MSR_GS_BASE`,它保存了被 `gs` 寄存器指向的内存段的基址。`edx:eax` 指向 `initial_gs` ,的地址,它就是 `fixed_percpu_data` 的基址。 我们还知道,`x86_64` 有一个叫 `中断栈表(Interrupt Stack Table)` 或者 `IST` 的组件,当发生不可屏蔽中断、双重错误等等的时候,这个组件提供了切换到新栈的功能。这可以到达7个 `IST` per-cpu 入口。其中一些如下; -There can be up to seven `IST` entries per-cpu. Some of them are: + * `DOUBLEFAULT_STACK` * `NMI_STACK` From 481bdfb2c5d07b52a4662abeea9e2e043bd777cd Mon Sep 17 00:00:00 2001 From: Albertchamberlain <2476271447@qq.com> Date: Tue, 12 May 2020 20:19:03 +0800 Subject: [PATCH 5/5] =?UTF-8?q?<=E4=B8=8A=E6=B8=B83.1=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E5=90=8E=E7=9A=84=E4=B8=AD=E6=96=87=E6=9B=B4=E6=96=B0=E7=89=88?= =?UTF-8?q?=E6=9C=AC>?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CONTRIBUTORS.md | 4 ++- Interrupts/linux-interrupts-1.md | 42 +++++++++++++++++--------------- README.md | 2 +- 3 files changed, 26 insertions(+), 22 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 26a9f3e..f1aecba 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -42,4 +42,6 @@ [@NeoCui](https://github.com/NeoCui) -[@narcijie](https://github.com/narcijie) \ No newline at end of file +[@narcijie](https://github.com/narcijie) + +[@Albertchamberlain](https://github.com/Albertchamberlain) diff --git a/Interrupts/linux-interrupts-1.md b/Interrupts/linux-interrupts-1.md index 257a290..586d95f 100644 --- a/Interrupts/linux-interrupts-1.md +++ b/Interrupts/linux-interrupts-1.md @@ -422,34 +422,36 @@ SYM_DATA(initial_gs, 所有被 `IST` 切换到新栈的中断门描述符都由 `set_intr_gate_ist` 函数初始化。例如: ```C -set_intr_gate_ist(X86_TRAP_NMI, &nmi, NMI_STACK); -... -... -... -set_intr_gate_ist(X86_TRAP_DF, &double_fault, DOUBLEFAULT_STACK); +static const __initconst struct idt_data def_idts[] = { + ... + INTG(X86_TRAP_NMI, nmi), + ... + INTG(X86_TRAP_DF, double_fault), ``` -其中 `&nmi` 和 `&double_fault` 是中断函数的入口地址: +其中 `&nmi` 和 `&double_fault` 在以下位置创建入口点: + +[arch/x86/kernel/entry_64.S](https://github.com/torvalds/linux/blob/master/arch/x86/entry/entry_64.S)中 + +```assembly +idtentry double_fault do_double_fault has_error_code=1 paranoid=2 read_cr2=1 +... +... +... +SYM_CODE_START(nmi) +... +... +... +SYM_CODE_END(nmi) +SYM_CODE_END(nmi) +``` +在以下位置给出了中断处理程序的声明 [arch/x86/include/asm/traps.h](https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/traps.h): ```C asmlinkage void nmi(void); asmlinkage void double_fault(void); ``` -定义在 [arch/x86/kernel/entry_64.S](https://github.com/torvalds/linux/blob/master/arch/x86/kernel/entry_64.S)中 - -```assembly -idtentry double_fault do_double_fault has_error_code=1 paranoid=2 -... -... -... -ENTRY(nmi) -... -... -... -END(nmi) -``` - 当一个中断或者异常发生时,新的 `ss` 选择器被强制置为 `NULL`,并且 `ss` 选择器的 `rpl` 域被设置为新的 `cpl`。旧的 `ss`、`rsp`、寄存器标志、`cs`、`rip` 被压入新栈。在 64 位模型下,中断栈帧大小固定为 8 字节,所以我们可以得到下面的栈: ``` diff --git a/README.md b/README.md index 8221455..ccdcbe6 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ |└ [2.10](https://github.com/MintCN/linux-insides-zh/blob/master/Initialization/linux-initialization-10.md)||未开始| | 3. [Interrupts](https://github.com/MintCN/linux-insides-zh/tree/master/Interrupts)||正在进行| |├ [3.0](https://github.com/MintCN/linux-insides-zh/blob/master/Interrupts/README.md)|[@littleneko](https://github.com/littleneko)|更新至[57279321](https://github.com/0xAX/linux-insides/commit/5727932167a2ff6a1e647081c85d081d4ed8b508)| -|├ [3.1](https://github.com/MintCN/linux-insides-zh/blob/master/Interrupts/linux-interrupts-1.md)||正在进行| +|├ [3.1](https://github.com/MintCN/linux-insides-zh/blob/master/Interrupts/linux-interrupts-1.md)|[@Albertchamberlain](https://github.com/Albertchamberlain)|更新至[e58c06bf](https://github.com/0xAX/linux-insides/commit/e58c06bfca60d4af25d92562de1ee9959992fc68)| |├ [3.2](https://github.com/MintCN/linux-insides-zh/blob/master/Interrupts/linux-interrupts-2.md)|[@narcijie](https://github.com/narcijie)|更新至[4d635117](https://github.com/0xAX/linux-insides/commit/4d6351172486e5c046a7d3db2286fc0d0d0d7789)| |├ [3.3](https://github.com/MintCN/linux-insides-zh/blob/master/Interrupts/linux-interrupts-3.md)||未开始| |├ [3.4](https://github.com/MintCN/linux-insides-zh/blob/master/Interrupts/linux-interrupts-4.md)||未开始|