bugfix: 修复smp启动的时候,损坏0号核心的idle进程的内核栈的问题 (#711)

---------

Co-authored-by: longjin <longjin@DragonOS.org>
Co-authored-by: heyicong <heyicong@dragonos.org>
This commit is contained in:
曾俊
2024-04-10 19:00:32 +08:00
committed by GitHub
parent 9365e8017b
commit 3959e94df3
14 changed files with 69 additions and 36 deletions

View File

@ -1,4 +1,5 @@
#include "../common/asm.h"
#include <asm/apu_boot.h>
.align 0x1000 // 4k
@ -112,9 +113,9 @@ _apu_code64_vector:
.long _apu_code64 - _apu_boot_base
.word 0x18,0
.align 0x1000
_apu_boot_tmp_stack_start:
// .org 0x400
.align 0x1000
ENTRY(_apu_boot_tmp_stack_start)
.skip APU_BOOT_TMP_STACK_SIZE
_apu_boot_tmp_stack_end:
ENTRY(_apu_boot_end)

View File

@ -3,6 +3,7 @@
// 2022/01/20
#include "common/asm.h"
#include <asm/apu_boot.h>
// multiboot2
// How many bytes from the start of the file we search for the header.
@ -249,7 +250,6 @@ ENTRY(_start64)
lidt IDT_POINTER(%rip)
//lidt $IDT_POINTER
movq GDT_POINTER(%rip), %r12
movq head_stack_start(%rip), %rsp
// apu
movq $0x1b, %rcx // IA32_APIC_BASE.BSP[8]apu
@ -257,6 +257,9 @@ ENTRY(_start64)
bt $8, %rax
jnc load_apu_cr3
// BSP
movq head_stack_start(%rip), %rsp
// 2.
//
mov $__PML4E, %eax
@ -318,11 +321,11 @@ load_cr3:
load_apu_cr3:
// ap使
// smp__APU_START_CR3
// __APU_START_CR3
movq $__APU_START_CR3, %rax
movq 0(%rax), %rax
movq %rax, %cr3
movq _apu_boot_tmp_stack_top_addr(%rip), %rsp
jmp to_switch_seg
to_switch_seg:
@ -348,7 +351,21 @@ entry64:
movq %rax, %gs
movq %rax, %ss
movq head_stack_start(%rip), %rsp //rsp
// apu,·
movq $0x1b, %rcx // IA32_APIC_BASE.BSP[8]apu
rdmsr
bt $8, %rax
jnc __set_ap_tmp_stack_start2
__set_bsp_stack_start2:
movq head_stack_start(%rip), %rsp
jmp __set_stack_start2_ok
__set_ap_tmp_stack_start2:
// ap
movq _apu_boot_tmp_stack_top_addr(%rip), %rsp
jmp __set_stack_start2_ok
__set_stack_start2_ok:
// GDTIDT
leaq GDT_Table(%rip), %r8
@ -485,6 +502,9 @@ go_to_ignore_int:
ENTRY(head_stack_start)
.quad BSP_IDLE_STACK_SPACE + 32768
ENTRY(_apu_boot_tmp_stack_top_addr)
.quad _apu_boot_tmp_stack_start + APU_BOOT_TMP_STACK_SIZE
//
.align 0x1000 //4k
__PML4E:

View File

@ -0,0 +1,2 @@
#pragma once
#define APU_BOOT_TMP_STACK_SIZE 1024

View File

@ -300,13 +300,14 @@ unsafe extern "C" fn do_general_protection(regs: &'static TrapFrame, error_code:
""
};
kerror!(
"do_general_protection(13), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}
"do_general_protection(13), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t rflags: {:#x}\t CPU: {}, \tpid: {:?}
{}{}{}
Segment Selector Index: {:#x}\n
",
error_code,
regs.rsp,
regs.rip,
regs.rflags,
smp_get_processor_id().data(),
ProcessManager::current_pid(),
msg1, msg2, msg3,

View File

@ -460,9 +460,6 @@ unsafe extern "sysv64" fn switch_to_inner(prev: *mut ArchPCBInfo, next: *mut Arc
// mov fs, [rsi + {off_fs}]
// mov gs, [rsi + {off_gs}]
push rbp
push rax
mov [rdi + {off_rbp}], rbp
mov rbp, [rsi + {off_rbp}]
@ -509,17 +506,9 @@ unsafe extern "sysv64" fn switch_to_inner(prev: *mut ArchPCBInfo, next: *mut Arc
);
}
/// 从`switch_to_inner`返回后,执行这个函数
///
/// 也就是说,当进程再次被调度时,会从这里开始执行
#[inline(never)]
unsafe extern "sysv64" fn switch_back() {
asm!(concat!(
"
pop rax
pop rbp
"
))
#[naked]
unsafe extern "sysv64" fn switch_back() -> ! {
asm!("ret", options(noreturn));
}
pub unsafe fn arch_switch_to_user(path: String, argv: Vec<String>, envp: Vec<String>) -> ! {

View File

@ -46,11 +46,12 @@ struct ApStartStackInfo {
#[no_mangle]
unsafe extern "C" fn smp_ap_start() -> ! {
CurrentIrqArch::interrupt_disable();
let vaddr = if let Some(t) = smp_cpu_manager()
.cpuhp_state(smp_get_processor_id())
.thread()
{
t.kernel_stack().stack_max_address().data() - 16
t.kernel_stack_force_ref().stack_max_address().data() - 16
} else {
// 没有设置ap核心的栈那么就进入死循环。
loop {
@ -214,15 +215,16 @@ impl SMPArch for X86_64SMPArch {
}
fn start_cpu(cpu_id: ProcessorId, _cpu_hpstate: &CpuHpCpuState) -> Result<(), SystemError> {
kdebug!("start_cpu: cpu_id: {:#x}\n", cpu_id.data());
Self::copy_smp_start_code();
fence(Ordering::SeqCst);
ipi_send_smp_init();
fence(Ordering::SeqCst);
ipi_send_smp_startup(cpu_id)?;
fence(Ordering::SeqCst);
ipi_send_smp_startup(cpu_id)?;
fence(Ordering::SeqCst);
return Ok(());