if (!current->reported_split_lock)
pr_warn_ratelimited("#AC: %s/%d took a split_lock trap at address: 0x%lx\n",
current->comm, current->pid, ip);
current->reported_split_lock = 1;
if (saved_sld_mitigate) { /* *miseryfactor#1: *sleep10msbeforetryingtoexecutesplitlock.
*/ if (msleep_interruptible(10) > 0) return; /* *Miseryfactor#2: *onlyallowonebuslockeddisabledcoreatatime.
*/ if (down_interruptible(&buslock_sem) == -EINTR) return;
}
cpu = get_cpu();
work = saved_sld_mitigate ? &sl_reenable_unlock : per_cpu_ptr(&sl_reenable, cpu);
schedule_delayed_work_on(cpu, work, 2);
/* Disable split lock detection on this CPU to make progress */
sld_update_msr(false);
put_cpu();
}
if (!boot_cpu_has(X86_FEATURE_BUS_LOCK_DETECT)) return;
rdmsrq(MSR_IA32_DEBUGCTLMSR, val);
if ((boot_cpu_has(X86_FEATURE_SPLIT_LOCK_DETECT) &&
(sld_state == sld_warn || sld_state == sld_fatal)) ||
sld_state == sld_off) { /* *Warnandfatalarehandledby#ACforsplitlockif#ACfor *splitlockissupported.
*/
val &= ~DEBUGCTLMSR_BUS_LOCK_DETECT;
} else {
val |= DEBUGCTLMSR_BUS_LOCK_DETECT;
}
wrmsrq(MSR_IA32_DEBUGCTLMSR, val);
}
bool handle_user_split_lock(struct pt_regs *regs, long error_code)
{ if ((regs->flags & X86_EFLAGS_AC) || sld_state == sld_fatal) returnfalse;
split_lock_warn(regs->ip); returntrue;
}
void handle_bus_lock(struct pt_regs *regs)
{ switch (sld_state) { case sld_off: break; case sld_ratelimit: /* Enforce no more than bld_ratelimit bus locks/sec. */ while (!__ratelimit(&bld_ratelimit))
msleep(20); /* Warn on the bus lock. */
fallthrough; case sld_warn:
pr_warn_ratelimited("#DB: %s/%d took a bus_lock trap at address: 0x%lx\n",
current->comm, current->pid, regs->ip); break; case sld_fatal:
force_sig_fault(SIGBUS, BUS_ADRALN, NULL); break;
}
}
staticvoid sld_state_show(void)
{ if (!boot_cpu_has(X86_FEATURE_BUS_LOCK_DETECT) &&
!boot_cpu_has(X86_FEATURE_SPLIT_LOCK_DETECT)) return;
switch (sld_state) { case sld_off:
pr_info("disabled\n"); break; case sld_warn: if (boot_cpu_has(X86_FEATURE_SPLIT_LOCK_DETECT)) {
pr_info("#AC: crashing the kernel on kernel split_locks and warning on user-space split_locks\n"); if (cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "x86/splitlock", NULL, splitlock_cpu_offline) < 0)
pr_warn("No splitlock CPU offline handler\n");
} elseif (boot_cpu_has(X86_FEATURE_BUS_LOCK_DETECT)) {
pr_info("#DB: warning on user-space bus_locks\n");
} break; case sld_fatal: if (boot_cpu_has(X86_FEATURE_SPLIT_LOCK_DETECT)) {
pr_info("#AC: crashing the kernel on kernel split_locks and sending SIGBUS on user-space split_locks\n");
} elseif (boot_cpu_has(X86_FEATURE_BUS_LOCK_DETECT)) {
pr_info("#DB: sending SIGBUS on user-space bus_locks%s\n",
boot_cpu_has(X86_FEATURE_SPLIT_LOCK_DETECT) ? " from non-WB" : "");
} break; case sld_ratelimit: if (boot_cpu_has(X86_FEATURE_BUS_LOCK_DETECT))
pr_info("#DB: setting system wide bus lock rate limit to %u/sec\n", bld_ratelimit.burst); break;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.