summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/uintr_core.c68
1 files changed, 36 insertions, 32 deletions
diff --git a/arch/x86/kernel/uintr_core.c b/arch/x86/kernel/uintr_core.c
index 607f9df83049..06640d5c9e80 100644
--- a/arch/x86/kernel/uintr_core.c
+++ b/arch/x86/kernel/uintr_core.c
@@ -309,16 +309,16 @@ static void teardown_uitt(void)
if (fpregs_state_valid(fpu, smp_processor_id())) {
/* Modify only the relevant bits of the MISC MSR */
- rdmsrl(MSR_IA32_UINTR_MISC, msr64); //
- msr64 &= GENMASK_ULL(63, 32);
- wrmsrl(MSR_IA32_UINTR_MISC, msr64);
- wrmsrl(MSR_IA32_UINTR_TT, 0ULL);
+ rdmsrl(MSR_IA32_UINTR_MISC, msr64); // 读取 MSR_IA32_UINTR_MISC
+ msr64 &= GENMASK_ULL(63, 32);// 31-0 位清零, uitt_size = 0 了
+ wrmsrl(MSR_IA32_UINTR_MISC, msr64); // 写入 MSR_IA32_UINTR_MISC
+ wrmsrl(MSR_IA32_UINTR_TT, 0ULL); // 全0 相当于 UITTADDR=0, 也没有 SENDUIPI 了
} else {// 若浮点寄存器无效
struct uintr_state *p;
p = get_xsave_addr(&fpu->state.xsave, XFEATURE_UINTR);
if (p) {
- p->uitt_size = 0;
+ p->uitt_size = 0; // 同上
p->uitt_addr = 0;
}
}
@@ -348,12 +348,12 @@ static int init_uitt(void)
fpregs_lock(); //
if (fpregs_state_valid(fpu, smp_processor_id())) { // 浮点寄存器有效
- wrmsrl(MSR_IA32_UINTR_TT, (u64)ui_send->uitt_ctx->uitt | 1);
- /* Modify only the relevant bits of the MISC MSR */
- rdmsrl(MSR_IA32_UINTR_MISC, msr64);
- msr64 &= GENMASK_ULL(63, 32);
- msr64 |= UINTR_MAX_UITT_NR;
- wrmsrl(MSR_IA32_UINTR_MISC, msr64);
+ wrmsrl(MSR_IA32_UINTR_TT, (u64)ui_send->uitt_ctx->uitt | 1); // UITTADDR
+ /* Modify only the relevant bits of the MISC MSR *///只改相关位
+ rdmsrl(MSR_IA32_UINTR_MISC, msr64); // 映射 MSR_IA32_UINTR_MISC 到 msr64
+ msr64 &= GENMASK_ULL(63, 32); // 前 32 位清零(UITTSZ = 0), 其他位置数据不变.
+ msr64 |= UINTR_MAX_UITT_NR; //
+ wrmsrl(MSR_IA32_UINTR_MISC, msr64); // 写入 MSR_IA32_UINTR_MISC
} else { // 浮点寄存器无效,写入 xsave
struct xregs_state *xsave;
struct uintr_state *p;
@@ -362,8 +362,8 @@ static int init_uitt(void)
xsave->header.xfeatures |= XFEATURE_MASK_UINTR;
p = get_xsave_addr(&fpu->state.xsave, XFEATURE_UINTR);
if (p) {
- p->uitt_size = UINTR_MAX_UITT_NR;
- p->uitt_addr = (u64)ui_send->uitt_ctx->uitt | 1;
+ p->uitt_size = UINTR_MAX_UITT_NR; // 设置 UITTSZ 大小
+ p->uitt_addr = (u64)ui_send->uitt_ctx->uitt | 1; // 设置 UITTADDR
}
}
@@ -510,7 +510,7 @@ int uintr_receiver_wait(void)
return -EOPNOTSUPP;
upid_ctx = current->thread.ui_recv->upid_ctx; // 取出当前进程的 upid_ctx
- upid_ctx->upid->nc.nv = UINTR_KERNEL_VECTOR;
+ upid_ctx->upid->nc.nv = UINTR_KERNEL_VECTOR; // 设置 upid_ctx 的 upid->nc.nv 为内核向量
upid_ctx->waiting = true; // 标记为 等待中
spin_lock_irqsave(&uintr_wait_lock, flags); // 锁
list_add(&upid_ctx->node, &uintr_wait_list); // 加入到等待队列
@@ -591,9 +591,9 @@ int do_uintr_unregister_handler(void)
// 仅清除接收者相关的状态 发送者相关的状态不会被修改
if (fpregs_state_valid(fpu, smp_processor_id())) { // 浮点寄存器状态有效
/* Modify only the relevant bits of the MISC MSR */
- rdmsrl(MSR_IA32_UINTR_MISC, msr64);
+ rdmsrl(MSR_IA32_UINTR_MISC, msr64); //
msr64 &= ~GENMASK_ULL(39, 32);
- wrmsrl(MSR_IA32_UINTR_MISC, msr64);
+ wrmsrl(MSR_IA32_UINTR_MISC, msr64); //
wrmsrl(MSR_IA32_UINTR_PD, 0ULL);
wrmsrl(MSR_IA32_UINTR_RR, 0ULL);
wrmsrl(MSR_IA32_UINTR_STACKADJUST, 0ULL);
@@ -621,7 +621,7 @@ int do_uintr_unregister_handler(void)
// 抑制通知,以便不再基于此 UPID 生成进一步的中断
set_bit(UPID_SN, (unsigned long *)&ui_recv->upid_ctx->upid->nc.status); //关掉 UPID status 使能
uintr_remove_task_wait(t); // 从等待列表中移除当前进程
- put_upid_ref(ui_recv->upid_ctx); // upid_ctx->refs - 1, 且应用技术为 0 时释放 upid_ctx
+ put_upid_ref(ui_recv->upid_ctx); // upid_ctx->refs - 1, 且计数为 0 时释放 upid_ctx
kfree(ui_recv); // 释放 ui_recv
t->thread.ui_recv = NULL; // 置空
@@ -680,16 +680,16 @@ int do_uintr_register_handler(u64 handler)
if (fpregs_state_valid(fpu, cpu)) { //如果当前进程的浮点寄存器有效
//都是新增加的硬件寄存器,归硬件直接操作.
- wrmsrl(MSR_IA32_UINTR_HANDLER, handler); // handler 放到 MSR_IA32_UINTR_HANDLER 寄存器
- wrmsrl(MSR_IA32_UINTR_PD, (u64)ui_recv->upid_ctx->upid); // upid 放到 MSR_IA32_UINTR_PD 寄存器
+ wrmsrl(MSR_IA32_UINTR_HANDLER, handler); // handler 内存地址 放到 MSR_IA32_UINTR_HANDLER 寄存器
+ wrmsrl(MSR_IA32_UINTR_PD, (u64)ui_recv->upid_ctx->upid); // upid 地址 放到 MSR_IA32_UINTR_PD 寄存器
/* Set value as size of ABI redzone */
- wrmsrl(MSR_IA32_UINTR_STACKADJUST, 128);
+ wrmsrl(MSR_IA32_UINTR_STACKADJUST, 128); // 用户中断堆栈的调整值??
- /* Modify only the relevant bits of the MISC MSR */
- rdmsrl(MSR_IA32_UINTR_MISC, misc_msr);
- misc_msr |= (u64)UINTR_NOTIFICATION_VECTOR << 32;
- wrmsrl(MSR_IA32_UINTR_MISC, misc_msr);
+ /* Modify only the relevant bits of the MISC MSR */ //更新 UINV
+ rdmsrl(MSR_IA32_UINTR_MISC, misc_msr); // 读取 MSR_IA32_UINTR_MISC 寄存器的值
+ misc_msr |= (u64)UINTR_NOTIFICATION_VECTOR << 32; // UINTR_NOTIFICATION_VECTOR 的值换入 63:32 的位置 其实是 UINV 了.或者说是 中断编号
+ wrmsrl(MSR_IA32_UINTR_MISC, misc_msr); // 回写
} else { // 当前进程的浮点寄存器无效
struct xregs_state *xsave;
struct uintr_state *p;
@@ -699,10 +699,10 @@ int do_uintr_register_handler(u64 handler)
p = get_xsave_addr(&fpu->state.xsave, XFEATURE_UINTR);
printk("----uintr xsave addr is %px\n",p);
if (p) {
- p->handler = handler;
- p->upid_addr = (u64)ui_recv->upid_ctx->upid;
- p->stack_adjust = 128;
- p->uinv = UINTR_NOTIFICATION_VECTOR;
+ p->handler = handler; // 中断处理函数地址
+ p->upid_addr = (u64)ui_recv->upid_ctx->upid; // upid 地址
+ p->stack_adjust = 128; // 用户中断堆栈的调整值??
+ p->uinv = UINTR_NOTIFICATION_VECTOR; // 中断编号
printk("the xsave addr is %p\n handler: 0x%llx | upid_addr: 0x%llx | uif: %d\n", p, handler,p->upid_addr,p->uif_pad3);
}
}
@@ -764,13 +764,15 @@ int do_uintr_register_vector(struct uintr_receiver_info *r_info)
}
/* Suppress notifications since this task is being context switched out */
+// 线程切出时调用, 线程不在前台就不再允许接收通知.
void switch_uintr_prepare(struct task_struct *prev)
{
struct uintr_upid *upid;
if (is_uintr_receiver(prev) && !is_uintr_waiting(prev)) {
+ printk("receiver task %d blocking \n",prev->pid);
upid = prev->thread.ui_recv->upid_ctx->upid;
- set_bit(UPID_SN, (unsigned long *)&upid->nc.status);
+ set_bit(UPID_SN, (unsigned long *)&upid->nc.status); // 禁用通知
}
}
@@ -779,6 +781,7 @@ void switch_uintr_prepare(struct task_struct *prev)
* reloaded i.e. TIF_NEED_FPU_LOAD is clear.
* Called from arch_exit_to_user_mode_prepare() with interrupts disabled.
*/
+// 线程切入时调用, 恢复寄存器状态
void switch_uintr_return(void)
{
struct uintr_upid *upid;
@@ -806,8 +809,8 @@ void switch_uintr_return(void)
/* Modify only the relevant bits of the MISC MSR */
rdmsrl(MSR_IA32_UINTR_MISC, misc_msr);
- if (!(misc_msr & GENMASK_ULL(39, 32))) {
- misc_msr |= (u64)UINTR_NOTIFICATION_VECTOR << 32;
+ if (!(misc_msr & GENMASK_ULL(39, 32))) { // 如果 UINV 位没有设置
+ misc_msr |= (u64)UINTR_NOTIFICATION_VECTOR << 32; // 恢复 UINV 位为 UINTR_NOTIFICATION_VECTOR|中断编号
wrmsrl(MSR_IA32_UINTR_MISC, misc_msr);
}
@@ -835,8 +838,9 @@ void switch_uintr_return(void)
*/
if (READ_ONCE(upid->puir)){ // 有未处理的用户中断请求
+ printk("receiver task %d resuming \n",current->pid);
printk("sending self ipi\n");
- apic->send_IPI_self(UINTR_NOTIFICATION_VECTOR);
+ apic->send_IPI_self(UINTR_NOTIFICATION_VECTOR); // 发送自己的中断,进入 UINTR_NOTIFICATION_VECTOR 对应中断
}
}
}