aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/cpu/bugs.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/cpu/bugs.c')
-rw-r--r--arch/x86/kernel/cpu/bugs.c27
1 files changed, 16 insertions, 11 deletions
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index fc9187b6fae7..e3afb610f2ad 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -530,31 +530,35 @@ static void ssb_select_mitigation()
530 530
531#undef pr_fmt 531#undef pr_fmt
532 532
533static int ssb_prctl_set(unsigned long ctrl) 533static int ssb_prctl_set(struct task_struct *task, unsigned long ctrl)
534{ 534{
535 bool rds = !!test_tsk_thread_flag(current, TIF_RDS); 535 bool rds = !!test_tsk_thread_flag(task, TIF_RDS);
536 536
537 if (ssb_mode != SPEC_STORE_BYPASS_PRCTL) 537 if (ssb_mode != SPEC_STORE_BYPASS_PRCTL)
538 return -ENXIO; 538 return -ENXIO;
539 539
540 if (ctrl == PR_SPEC_ENABLE) 540 if (ctrl == PR_SPEC_ENABLE)
541 clear_tsk_thread_flag(current, TIF_RDS); 541 clear_tsk_thread_flag(task, TIF_RDS);
542 else 542 else
543 set_tsk_thread_flag(current, TIF_RDS); 543 set_tsk_thread_flag(task, TIF_RDS);
544 544
545 if (rds != !!test_tsk_thread_flag(current, TIF_RDS)) 545 /*
546 * If being set on non-current task, delay setting the CPU
547 * mitigation until it is next scheduled.
548 */
549 if (task == current && rds != !!test_tsk_thread_flag(task, TIF_RDS))
546 speculative_store_bypass_update(); 550 speculative_store_bypass_update();
547 551
548 return 0; 552 return 0;
549} 553}
550 554
551static int ssb_prctl_get(void) 555static int ssb_prctl_get(struct task_struct *task)
552{ 556{
553 switch (ssb_mode) { 557 switch (ssb_mode) {
554 case SPEC_STORE_BYPASS_DISABLE: 558 case SPEC_STORE_BYPASS_DISABLE:
555 return PR_SPEC_DISABLE; 559 return PR_SPEC_DISABLE;
556 case SPEC_STORE_BYPASS_PRCTL: 560 case SPEC_STORE_BYPASS_PRCTL:
557 if (test_tsk_thread_flag(current, TIF_RDS)) 561 if (test_tsk_thread_flag(task, TIF_RDS))
558 return PR_SPEC_PRCTL | PR_SPEC_DISABLE; 562 return PR_SPEC_PRCTL | PR_SPEC_DISABLE;
559 return PR_SPEC_PRCTL | PR_SPEC_ENABLE; 563 return PR_SPEC_PRCTL | PR_SPEC_ENABLE;
560 default: 564 default:
@@ -564,24 +568,25 @@ static int ssb_prctl_get(void)
564 } 568 }
565} 569}
566 570
567int arch_prctl_spec_ctrl_set(unsigned long which, unsigned long ctrl) 571int arch_prctl_spec_ctrl_set(struct task_struct *task, unsigned long which,
572 unsigned long ctrl)
568{ 573{
569 if (ctrl != PR_SPEC_ENABLE && ctrl != PR_SPEC_DISABLE) 574 if (ctrl != PR_SPEC_ENABLE && ctrl != PR_SPEC_DISABLE)
570 return -ERANGE; 575 return -ERANGE;
571 576
572 switch (which) { 577 switch (which) {
573 case PR_SPEC_STORE_BYPASS: 578 case PR_SPEC_STORE_BYPASS:
574 return ssb_prctl_set(ctrl); 579 return ssb_prctl_set(task, ctrl);
575 default: 580 default:
576 return -ENODEV; 581 return -ENODEV;
577 } 582 }
578} 583}
579 584
580int arch_prctl_spec_ctrl_get(unsigned long which) 585int arch_prctl_spec_ctrl_get(struct task_struct *task, unsigned long which)
581{ 586{
582 switch (which) { 587 switch (which) {
583 case PR_SPEC_STORE_BYPASS: 588 case PR_SPEC_STORE_BYPASS:
584 return ssb_prctl_get(); 589 return ssb_prctl_get(task);
585 default: 590 default:
586 return -ENODEV; 591 return -ENODEV;
587 } 592 }