diff options
Diffstat (limited to 'arch/x86/kernel/cpu/bugs.c')
-rw-r--r-- | arch/x86/kernel/cpu/bugs.c | 27 |
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 | ||
533 | static int ssb_prctl_set(unsigned long ctrl) | 533 | static 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 | ||
551 | static int ssb_prctl_get(void) | 555 | static 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 | ||
567 | int arch_prctl_spec_ctrl_set(unsigned long which, unsigned long ctrl) | 571 | int 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 | ||
580 | int arch_prctl_spec_ctrl_get(unsigned long which) | 585 | int 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 | } |