* [PATCH 4.4 097/107] x86/bugs: Rename SSBD_NO to SSB_NO
From: Greg Kroah-Hartman @ 2018-07-23 12:42 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Konrad Rzeszutek Wilk,
Thomas Gleixner, David Woodhouse, Srivatsa S. Bhat,
Matt Helsley (VMware), Alexey Makhalov, Bo Gan
In-Reply-To: <20180723122413.003644357@linuxfoundation.org>
4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
commit 240da953fcc6a9008c92fae5b1f727ee5ed167ab upstream
The "336996 Speculative Execution Side Channel Mitigations" from
May defines this as SSB_NO, hence lets sync-up.
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Srivatsa S. Bhat <srivatsa@csail.mit.edu>
Reviewed-by: Matt Helsley (VMware) <matt.helsley@gmail.com>
Reviewed-by: Alexey Makhalov <amakhalov@vmware.com>
Reviewed-by: Bo Gan <ganb@vmware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/x86/include/asm/msr-index.h | 2 +-
arch/x86/kernel/cpu/common.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -58,7 +58,7 @@
#define MSR_IA32_ARCH_CAPABILITIES 0x0000010a
#define ARCH_CAP_RDCL_NO (1 << 0) /* Not susceptible to Meltdown */
#define ARCH_CAP_IBRS_ALL (1 << 1) /* Enhanced IBRS support */
-#define ARCH_CAP_SSBD_NO (1 << 4) /*
+#define ARCH_CAP_SSB_NO (1 << 4) /*
* Not susceptible to Speculative Store Bypass
* attack, so no Speculative Store Bypass
* control required.
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -881,7 +881,7 @@ static void __init cpu_set_bug_bits(stru
rdmsrl(MSR_IA32_ARCH_CAPABILITIES, ia32_cap);
if (!x86_match_cpu(cpu_no_spec_store_bypass) &&
- !(ia32_cap & ARCH_CAP_SSBD_NO))
+ !(ia32_cap & ARCH_CAP_SSB_NO))
setup_force_cpu_bug(X86_BUG_SPEC_STORE_BYPASS);
if (x86_match_cpu(cpu_no_speculation))
^ permalink raw reply
* [PATCH 4.4 095/107] x86/bugs: Rework spec_ctrl base and mask logic
From: Greg Kroah-Hartman @ 2018-07-23 12:42 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Thomas Gleixner, Borislav Petkov,
David Woodhouse, Srivatsa S. Bhat, Matt Helsley (VMware),
Alexey Makhalov, Bo Gan
In-Reply-To: <20180723122413.003644357@linuxfoundation.org>
4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Gleixner <tglx@linutronix.de>
commit be6fcb5478e95bb1c91f489121238deb3abca46a upstream
x86_spec_ctrL_mask is intended to mask out bits from a MSR_SPEC_CTRL value
which are not to be modified. However the implementation is not really used
and the bitmask was inverted to make a check easier, which was removed in
"x86/bugs: Remove x86_spec_ctrl_set()"
Aside of that it is missing the STIBP bit if it is supported by the
platform, so if the mask would be used in x86_virt_spec_ctrl() then it
would prevent a guest from setting STIBP.
Add the STIBP bit if supported and use the mask in x86_virt_spec_ctrl() to
sanitize the value which is supplied by the guest.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Borislav Petkov <bp@suse.de>
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Srivatsa S. Bhat <srivatsa@csail.mit.edu>
Reviewed-by: Matt Helsley (VMware) <matt.helsley@gmail.com>
Reviewed-by: Alexey Makhalov <amakhalov@vmware.com>
Reviewed-by: Bo Gan <ganb@vmware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/x86/kernel/cpu/bugs.c | 26 +++++++++++++++++++-------
1 file changed, 19 insertions(+), 7 deletions(-)
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -41,7 +41,7 @@ EXPORT_SYMBOL_GPL(x86_spec_ctrl_base);
* The vendor and possibly platform specific bits which can be modified in
* x86_spec_ctrl_base.
*/
-static u64 x86_spec_ctrl_mask = ~SPEC_CTRL_IBRS;
+static u64 x86_spec_ctrl_mask = SPEC_CTRL_IBRS;
/*
* AMD specific MSR info for Speculative Store Bypass control.
@@ -67,6 +67,10 @@ void __init check_bugs(void)
if (boot_cpu_has(X86_FEATURE_MSR_SPEC_CTRL))
rdmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base);
+ /* Allow STIBP in MSR_SPEC_CTRL if supported */
+ if (boot_cpu_has(X86_FEATURE_STIBP))
+ x86_spec_ctrl_mask |= SPEC_CTRL_STIBP;
+
/* Select the proper spectre mitigation before patching alternatives */
spectre_v2_select_mitigation();
@@ -134,18 +138,26 @@ static enum spectre_v2_mitigation spectr
void
x86_virt_spec_ctrl(u64 guest_spec_ctrl, u64 guest_virt_spec_ctrl, bool setguest)
{
+ u64 msrval, guestval, hostval = x86_spec_ctrl_base;
struct thread_info *ti = current_thread_info();
- u64 msr, host = x86_spec_ctrl_base;
/* Is MSR_SPEC_CTRL implemented ? */
if (static_cpu_has(X86_FEATURE_MSR_SPEC_CTRL)) {
+ /*
+ * Restrict guest_spec_ctrl to supported values. Clear the
+ * modifiable bits in the host base value and or the
+ * modifiable bits from the guest value.
+ */
+ guestval = hostval & ~x86_spec_ctrl_mask;
+ guestval |= guest_spec_ctrl & x86_spec_ctrl_mask;
+
/* SSBD controlled in MSR_SPEC_CTRL */
if (static_cpu_has(X86_FEATURE_SPEC_CTRL_SSBD))
- host |= ssbd_tif_to_spec_ctrl(ti->flags);
+ hostval |= ssbd_tif_to_spec_ctrl(ti->flags);
- if (host != guest_spec_ctrl) {
- msr = setguest ? guest_spec_ctrl : host;
- wrmsrl(MSR_IA32_SPEC_CTRL, msr);
+ if (hostval != guestval) {
+ msrval = setguest ? guestval : hostval;
+ wrmsrl(MSR_IA32_SPEC_CTRL, msrval);
}
}
}
@@ -491,7 +503,7 @@ static enum ssb_mitigation __init __ssb_
switch (boot_cpu_data.x86_vendor) {
case X86_VENDOR_INTEL:
x86_spec_ctrl_base |= SPEC_CTRL_SSBD;
- x86_spec_ctrl_mask &= ~SPEC_CTRL_SSBD;
+ x86_spec_ctrl_mask |= SPEC_CTRL_SSBD;
wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base);
break;
case X86_VENDOR_AMD:
^ permalink raw reply
* Re: [BUG] merge-recursive overly aggressive when skipping updating the working tree
From: Ben Peart @ 2018-07-23 12:49 UTC (permalink / raw)
To: Elijah Newren, Junio C Hamano; +Cc: Git Mailing List, Kevin Willford, Ben Peart
In-Reply-To: <CABPp-BGVtP4-_LYh7SjSSoTwcm+ZiKbCRSuK0MCo_wvUWBj3vg@mail.gmail.com>
On 7/20/2018 7:02 PM, Elijah Newren wrote:
> On Fri, Jul 20, 2018 at 3:05 PM, Junio C Hamano <gitster@pobox.com> wrote:
>> Elijah Newren <newren@gmail.com> writes:
>>
>>> Ah, okay, that's helpful. So, if there are conflicts, it should be
>>> free to clear the skip_worktree flag. Since merge-recursive calls
>>> add_cacheinfo() for all entries it needs to update, which deletes the
>>> old cache entry and just makes new ones, we get that for free.
>>
>> Correct.
>>
>>> And conversely, if a file-level merge succeeds without conflicts then
>>> it clearly doesn't "need to materialize a working tree file", so it
>>> should NOT clear the skip_worktree flag for that path.
>>
>> That is not at all implied by what I wrote, though.
>>
>> If it can be done without too much effort, then it certainly is
>> nicer to keep the sparseness when we do not have to materialize the
>> working tree file. But at least in my mind, if it needs too many
>> special cases, hacks, and conditionals, then it is not worth the
>> complexity---if it is easier to write a correct code by allowing Git
>> to populate working tree files, it is perfectly fine to do so.
>>
>> In a sense, the sparse checkout "feature" itself is a hack by
>> itself, and that is why I think this part should be "best effort" as
>> well.
>
> That's good to know, but I don't think we can back out easily:
> - Clearing the skip_worktree bit: no big deal, as you mention above
> - Avoiding working tree updates when merge doesn't change them: very
> desirable[1]
> - Doing both: whoops
>
> [1] https://public-inbox.org/git/CA+55aFzLZ3UkG5svqZwSnhNk75=fXJRkvU1m_RHBG54NOoaZPA@mail.gmail.com/
>
>
> I don't want to regress the bug Linus reported, so to fix Ben's issue,
> when we detect that a path's contents/mode won't be modified by the
> merge, we can either:
> - Update the working tree file if the original cache entry had the
> skip_worktree flag set
> - Mark the new cache entry as skip_worktree if the original cache
> entry had the skip_worktree flag set
>
> Both should be about the same amount of work; the first seems weird
> and confusing for future readers of the code. The second makes sense,
> but probably should be accompanied with a note in the code about how
> there are other codepaths that could consider skip_worktree too.
>
> I'll see if I can put something together, but I have family flying in
> tomorrow, and then am out on vacation Mon-Sat next week, so...
>
I agree with the priorities around proposed behavior with this scenario.
It would be preferred that the skip worktree bit be preserved but the
behavior in 2.17 of clearing it and writing the file to the working
directory is much better than the current 2.18 behavior that makes the
user think they had somehow deleted the file just by doing the merge.
At this point, it isn't clear to the user what they should do to recover
without causing harm to the repo.
$ git status
HEAD detached at df2a63d
You are currently cherry-picking commit 7e6d412.
(all conflicts fixed: run "git cherry-pick --continue")
(use "git cherry-pick --abort" to cancel the cherry-pick operation)
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
deleted: foo
^ permalink raw reply
* [PATCH 4.4 098/107] x86/xen: Add call of speculative_store_bypass_ht_init() to PV paths
From: Greg Kroah-Hartman @ 2018-07-23 12:42 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Brian Woods, Juergen Gross,
Linus Torvalds, Peter Zijlstra, Thomas Gleixner, boris.ostrovsky,
xen-devel, Ingo Molnar, Srivatsa S. Bhat
In-Reply-To: <20180723122413.003644357@linuxfoundation.org>
4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Juergen Gross <jgross@suse.com>
commit 74899d92e66663dc7671a8017b3146dcd4735f3b upstream.
Commit:
1f50ddb4f418 ("x86/speculation: Handle HT correctly on AMD")
... added speculative_store_bypass_ht_init() to the per-CPU initialization sequence.
speculative_store_bypass_ht_init() needs to be called on each CPU for
PV guests, too.
Reported-by: Brian Woods <brian.woods@amd.com>
Tested-by: Brian Woods <brian.woods@amd.com>
Signed-off-by: Juergen Gross <jgross@suse.com>
Cc: <stable@vger.kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: boris.ostrovsky@oracle.com
Cc: xen-devel@lists.xenproject.org
Fixes: 1f50ddb4f4189243c05926b842dc1a0332195f31 ("x86/speculation: Handle HT correctly on AMD")
Link: https://lore.kernel.org/lkml/20180621084331.21228-1-jgross@suse.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Srivatsa S. Bhat <srivatsa@csail.mit.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/x86/xen/smp.c | 5 +++++
1 file changed, 5 insertions(+)
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -28,6 +28,7 @@
#include <xen/interface/vcpu.h>
#include <xen/interface/xenpmu.h>
+#include <asm/spec-ctrl.h>
#include <asm/xen/interface.h>
#include <asm/xen/hypercall.h>
@@ -87,6 +88,8 @@ static void cpu_bringup(void)
cpu_data(cpu).x86_max_cores = 1;
set_cpu_sibling_map(cpu);
+ speculative_store_bypass_ht_init();
+
xen_setup_cpu_clockevents();
notify_cpu_starting(cpu);
@@ -357,6 +360,8 @@ static void __init xen_smp_prepare_cpus(
}
set_cpu_sibling_map(0);
+ speculative_store_bypass_ht_init();
+
xen_pmu_init(0);
if (xen_smp_intr_init(0))
^ permalink raw reply
* Re: Hash algorithm analysis
From: Sitaram Chamarty @ 2018-07-23 12:48 UTC (permalink / raw)
To: demerphq, brian m. carlson, Johannes Schindelin, Jonathan Nieder,
Git, Linus Torvalds, agl, keccak
In-Reply-To: <CANgJU+X39NoEoMyLu+FX38=x19LrRqatz_dUpUAc+WFV+Uw+=A@mail.gmail.com>
On 07/23/2018 06:10 PM, demerphq wrote:
> On Sun, 22 Jul 2018 at 01:59, brian m. carlson
> <sandals@crustytoothpaste.net> wrote:
>> I will admit that I don't love making this decision by myself, because
>> right now, whatever I pick, somebody is going to be unhappy. I want to
>> state, unambiguously, that I'm trying to make a decision that is in the
>> interests of the Git Project, the community, and our users.
>>
>> I'm happy to wait a few more days to see if a consensus develops; if so,
>> I'll follow it. If we haven't come to one by, say, Wednesday, I'll make
>> a decision and write my patches accordingly. The community is free, as
>> always, to reject my patches if taking them is not in the interest of
>> the project.
>
> Hi Brian.
>
> I do not envy you this decision.
>
> Personally I would aim towards pushing this decision out to the git
> user base and facilitating things so we can choose whatever hash
> function (and config) we wish, including ones not invented yet.
>
> Failing that I would aim towards a hashing strategy which has the most
> flexibility. Keccak for instance has the interesting property that its
> security level is tunable, and that it can produce aribitrarily long
> hashes. Leaving aside other concerns raised elsewhere in this thread,
> these two features alone seem to make it a superior choice for an
> initial implementation. You can find bugs by selecting unusual hash
> sizes, including very long ones, and you can provide ways to tune the
> function to peoples security and speed preferences. Someone really
> paranoid can specify an unusually large round count and a very long
> hash.
>
> Also frankly I keep thinking that the ability to arbitrarily extend
> the hash size has to be useful /somewhere/ in git.
I would not suggest arbitrarily long hashes. Not only would it
complicate a lot of code, it is not clear that it has any real benefit.
Plus, the code contortions required to support arbitrarily long hashes
would be more susceptible to potential bugs and exploits, simply by
being more complex code. Why take chances?
I would suggest (a) hash size of 256 bits and (b) choice of any hash
function that can produce such a hash. If people feel strongly that 256
bits may also turn out to be too small (really?) then a choice of 256 or
512, but not arbitrary sizes.
Sitaram
also not a cryptographer!
^ permalink raw reply
* [PATCH 4.4 069/107] proc: Provide details on speculation flaw mitigations
From: Greg Kroah-Hartman @ 2018-07-23 12:42 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Kees Cook, Thomas Gleixner,
David Woodhouse, Srivatsa S. Bhat, Matt Helsley (VMware),
Alexey Makhalov, Bo Gan
In-Reply-To: <20180723122413.003644357@linuxfoundation.org>
4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kees Cook <keescook@chromium.org>
commit fae1fa0fc6cca8beee3ab8ed71d54f9a78fa3f64 upstream
As done with seccomp and no_new_privs, also show speculation flaw
mitigation state in /proc/$pid/status.
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Srivatsa S. Bhat <srivatsa@csail.mit.edu>
Reviewed-by: Matt Helsley (VMware) <matt.helsley@gmail.com>
Reviewed-by: Alexey Makhalov <amakhalov@vmware.com>
Reviewed-by: Bo Gan <ganb@vmware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/proc/array.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -79,6 +79,7 @@
#include <linux/delayacct.h>
#include <linux/seq_file.h>
#include <linux/pid_namespace.h>
+#include <linux/prctl.h>
#include <linux/ptrace.h>
#include <linux/tracehook.h>
#include <linux/string_helpers.h>
@@ -332,6 +333,28 @@ static inline void task_seccomp(struct s
#ifdef CONFIG_SECCOMP
seq_printf(m, "Seccomp:\t%d\n", p->seccomp.mode);
#endif
+ seq_printf(m, "\nSpeculation Store Bypass:\t");
+ switch (arch_prctl_spec_ctrl_get(p, PR_SPEC_STORE_BYPASS)) {
+ case -EINVAL:
+ seq_printf(m, "unknown");
+ break;
+ case PR_SPEC_NOT_AFFECTED:
+ seq_printf(m, "not vulnerable");
+ break;
+ case PR_SPEC_PRCTL | PR_SPEC_DISABLE:
+ seq_printf(m, "thread mitigated");
+ break;
+ case PR_SPEC_PRCTL | PR_SPEC_ENABLE:
+ seq_printf(m, "thread vulnerable");
+ break;
+ case PR_SPEC_DISABLE:
+ seq_printf(m, "globally mitigated");
+ break;
+ default:
+ seq_printf(m, "vulnerable");
+ break;
+ }
+ seq_putc(m, '\n');
}
static inline void task_context_switch_counts(struct seq_file *m,
^ permalink raw reply
* Re: [Qemu-devel] [PATCH] qstring: Fix integer overflow
From: Markus Armbruster @ 2018-07-23 12:47 UTC (permalink / raw)
To: liujunjie; +Cc: wangxinxin.wang, arei.gonglei, weidong.huang, qemu-devel
In-Reply-To: <20180720130928.6696-1-liujunjie23@huawei.com>
liujunjie <liujunjie23@huawei.com> writes:
> From: l00425170 <liujunjie23@huawei.com>
>
> The incoming parameters "start" and "end" is int type in
> qstring_from_substr(), but this function can be called by
> qstring_from_str, which is size_t type in strlen(str).
Yes, there's a conversion from size_t to int in
return qstring_from_substr(str, 0, strlen(str) - 1);
The conversion truncates when strlen(str) - 1 exceeds INT_MAX.
strlen(str) - 1 wraps around to SIZE_MAX when @str is empty.
> It may result in coredump when called g_malloc later.
> One scene to triger is to call hmp "into tlb", which may have
> too long length of string.
Really? How exactly can this happen? Please explain step by step.
Aside: @end is only used as @end + 1, and all callers pass some X - 1.
Both the addition and the subtraction can overflow. Changing the
function to take the index behind the last character instead of the
index of the last character would almost certainly simplify things. Not
this patch's problem.
>
> Signed-off-by: l00425170 <liujunjie23@huawei.com>
> ---
> include/qapi/qmp/qstring.h | 2 +-
> qobject/qstring.c | 2 +-
> 2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/include/qapi/qmp/qstring.h b/include/qapi/qmp/qstring.h
> index b3b3d44..3e83e3a 100644
> --- a/include/qapi/qmp/qstring.h
> +++ b/include/qapi/qmp/qstring.h
> @@ -24,7 +24,7 @@ struct QString {
>
> QString *qstring_new(void);
> QString *qstring_from_str(const char *str);
> -QString *qstring_from_substr(const char *str, int start, int end);
> +QString *qstring_from_substr(const char *str, size_t start, size_t end);
> size_t qstring_get_length(const QString *qstring);
> const char *qstring_get_str(const QString *qstring);
> const char *qstring_get_try_str(const QString *qstring);
> diff --git a/qobject/qstring.c b/qobject/qstring.c
> index afca54b..18b8eb8 100644
> --- a/qobject/qstring.c
> +++ b/qobject/qstring.c
> @@ -37,7 +37,7 @@ size_t qstring_get_length(const QString *qstring)
> *
> * Return string reference
> */
> -QString *qstring_from_substr(const char *str, int start, int end)
> +QString *qstring_from_substr(const char *str, size_t start, size_t end)
> {
> QString *qstring;
The patch makes sense, but the commit message makes claims that need to
be substantiated.
^ permalink raw reply
* [PATCH 4.4 104/107] ubi: Be more paranoid while seaching for the most recent Fastmap
From: Greg Kroah-Hartman @ 2018-07-23 12:42 UTC (permalink / raw)
To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Richard Weinberger
In-Reply-To: <20180723122413.003644357@linuxfoundation.org>
4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Richard Weinberger <richard@nod.at>
commit 74f2c6e9a47cf4e508198c8594626cc82906a13d upstream.
Since PEB erasure is asynchornous it can happen that there is
more than one Fastmap on the MTD. This is fine because the attach logic
will pick the Fastmap data structure with the highest sequence number.
On a not so well configured MTD stack spurious ECC errors are common.
Causes can be different, bad hardware, wrong operating modes, etc...
If the most current Fastmap renders bad due to ECC errors UBI might
pick an older Fastmap to attach from.
While this can only happen on an anyway broken setup it will show
completely different sympthoms and makes finding the root cause much
more difficult.
So, be debug friendly and fall back to scanning mode of we're facing
an ECC error while scanning for Fastmap.
Cc: <stable@vger.kernel.org>
Signed-off-by: Richard Weinberger <richard@nod.at>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mtd/ubi/attach.c | 28 ++++++++++++++++++++++++----
drivers/mtd/ubi/ubi.h | 3 +++
2 files changed, 27 insertions(+), 4 deletions(-)
--- a/drivers/mtd/ubi/attach.c
+++ b/drivers/mtd/ubi/attach.c
@@ -856,13 +856,15 @@ static bool vol_ignored(int vol_id)
* @ubi: UBI device description object
* @ai: attaching information
* @pnum: the physical eraseblock number
+ * @fast: true if we're scanning for a Fastmap
*
* This function reads UBI headers of PEB @pnum, checks them, and adds
* information about this PEB to the corresponding list or RB-tree in the
* "attaching info" structure. Returns zero if the physical eraseblock was
* successfully handled and a negative error code in case of failure.
*/
-static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum)
+static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai,
+ int pnum, bool fast)
{
long long ec;
int err, bitflips = 0, vol_id = -1, ec_err = 0;
@@ -980,6 +982,20 @@ static int scan_peb(struct ubi_device *u
*/
ai->maybe_bad_peb_count += 1;
case UBI_IO_BAD_HDR:
+ /*
+ * If we're facing a bad VID header we have to drop *all*
+ * Fastmap data structures we find. The most recent Fastmap
+ * could be bad and therefore there is a chance that we attach
+ * from an old one. On a fine MTD stack a PEB must not render
+ * bad all of a sudden, but the reality is different.
+ * So, let's be paranoid and help finding the root cause by
+ * falling back to scanning mode instead of attaching with a
+ * bad EBA table and cause data corruption which is hard to
+ * analyze.
+ */
+ if (fast)
+ ai->force_full_scan = 1;
+
if (ec_err)
/*
* Both headers are corrupted. There is a possibility
@@ -1293,7 +1309,7 @@ static int scan_all(struct ubi_device *u
cond_resched();
dbg_gen("process PEB %d", pnum);
- err = scan_peb(ubi, ai, pnum);
+ err = scan_peb(ubi, ai, pnum, false);
if (err < 0)
goto out_vidh;
}
@@ -1407,7 +1423,7 @@ static int scan_fast(struct ubi_device *
cond_resched();
dbg_gen("process PEB %d", pnum);
- err = scan_peb(ubi, scan_ai, pnum);
+ err = scan_peb(ubi, scan_ai, pnum, true);
if (err < 0)
goto out_vidh;
}
@@ -1415,7 +1431,11 @@ static int scan_fast(struct ubi_device *
ubi_free_vid_hdr(ubi, vidh);
kfree(ech);
- err = ubi_scan_fastmap(ubi, *ai, scan_ai);
+ if (scan_ai->force_full_scan)
+ err = UBI_NO_FASTMAP;
+ else
+ err = ubi_scan_fastmap(ubi, *ai, scan_ai);
+
if (err) {
/*
* Didn't attach via fastmap, do a full scan but reuse what
--- a/drivers/mtd/ubi/ubi.h
+++ b/drivers/mtd/ubi/ubi.h
@@ -711,6 +711,8 @@ struct ubi_ainf_volume {
* @vols_found: number of volumes found
* @highest_vol_id: highest volume ID
* @is_empty: flag indicating whether the MTD device is empty or not
+ * @force_full_scan: flag indicating whether we need to do a full scan and drop
+ all existing Fastmap data structures
* @min_ec: lowest erase counter value
* @max_ec: highest erase counter value
* @max_sqnum: highest sequence number value
@@ -738,6 +740,7 @@ struct ubi_attach_info {
int vols_found;
int highest_vol_id;
int is_empty;
+ int force_full_scan;
int min_ec;
int max_ec;
unsigned long long max_sqnum;
^ permalink raw reply
* [PATCH 4.4 107/107] ubi: fastmap: Erase outdated anchor PEBs during attach
From: Greg Kroah-Hartman @ 2018-07-23 12:42 UTC (permalink / raw)
To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Sascha Hauer, Richard Weinberger
In-Reply-To: <20180723122413.003644357@linuxfoundation.org>
4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sascha Hauer <s.hauer@pengutronix.de>
commit f78e5623f45bab2b726eec29dc5cefbbab2d0b1c upstream.
The fastmap update code might erase the current fastmap anchor PEB
in case it doesn't find any new free PEB. When a power cut happens
in this situation we must not have any outdated fastmap anchor PEB
on the device, because that would be used to attach during next
boot.
The easiest way to make that sure is to erase all outdated fastmap
anchor PEBs synchronously during attach.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Reviewed-by: Richard Weinberger <richard@nod.at>
Fixes: dbb7d2a88d2a ("UBI: Add fastmap core")
Cc: <stable@vger.kernel.org>
Signed-off-by: Richard Weinberger <richard@nod.at>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mtd/ubi/wl.c | 77 +++++++++++++++++++++++++++++++++++++--------------
1 file changed, 57 insertions(+), 20 deletions(-)
--- a/drivers/mtd/ubi/wl.c
+++ b/drivers/mtd/ubi/wl.c
@@ -1509,6 +1509,46 @@ static void shutdown_work(struct ubi_dev
}
/**
+ * erase_aeb - erase a PEB given in UBI attach info PEB
+ * @ubi: UBI device description object
+ * @aeb: UBI attach info PEB
+ * @sync: If true, erase synchronously. Otherwise schedule for erasure
+ */
+static int erase_aeb(struct ubi_device *ubi, struct ubi_ainf_peb *aeb, bool sync)
+{
+ struct ubi_wl_entry *e;
+ int err;
+
+ e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL);
+ if (!e)
+ return -ENOMEM;
+
+ e->pnum = aeb->pnum;
+ e->ec = aeb->ec;
+ ubi->lookuptbl[e->pnum] = e;
+
+ if (sync) {
+ err = sync_erase(ubi, e, false);
+ if (err)
+ goto out_free;
+
+ wl_tree_add(e, &ubi->free);
+ ubi->free_count++;
+ } else {
+ err = schedule_erase(ubi, e, aeb->vol_id, aeb->lnum, 0, false);
+ if (err)
+ goto out_free;
+ }
+
+ return 0;
+
+out_free:
+ wl_entry_destroy(ubi, e);
+
+ return err;
+}
+
+/**
* ubi_wl_init - initialize the WL sub-system using attaching information.
* @ubi: UBI device description object
* @ai: attaching information
@@ -1545,17 +1585,9 @@ int ubi_wl_init(struct ubi_device *ubi,
list_for_each_entry_safe(aeb, tmp, &ai->erase, u.list) {
cond_resched();
- e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL);
- if (!e)
- goto out_free;
-
- e->pnum = aeb->pnum;
- e->ec = aeb->ec;
- ubi->lookuptbl[e->pnum] = e;
- if (schedule_erase(ubi, e, aeb->vol_id, aeb->lnum, 0, false)) {
- wl_entry_destroy(ubi, e);
+ err = erase_aeb(ubi, aeb, false);
+ if (err)
goto out_free;
- }
found_pebs++;
}
@@ -1615,6 +1647,8 @@ int ubi_wl_init(struct ubi_device *ubi,
ubi_assert(!ubi->lookuptbl[e->pnum]);
ubi->lookuptbl[e->pnum] = e;
} else {
+ bool sync = false;
+
/*
* Usually old Fastmap PEBs are scheduled for erasure
* and we don't have to care about them but if we face
@@ -1624,18 +1658,21 @@ int ubi_wl_init(struct ubi_device *ubi,
if (ubi->lookuptbl[aeb->pnum])
continue;
- e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL);
- if (!e)
- goto out_free;
+ /*
+ * The fastmap update code might not find a free PEB for
+ * writing the fastmap anchor to and then reuses the
+ * current fastmap anchor PEB. When this PEB gets erased
+ * and a power cut happens before it is written again we
+ * must make sure that the fastmap attach code doesn't
+ * find any outdated fastmap anchors, hence we erase the
+ * outdated fastmap anchor PEBs synchronously here.
+ */
+ if (aeb->vol_id == UBI_FM_SB_VOLUME_ID)
+ sync = true;
- e->pnum = aeb->pnum;
- e->ec = aeb->ec;
- ubi_assert(!ubi->lookuptbl[e->pnum]);
- ubi->lookuptbl[e->pnum] = e;
- if (schedule_erase(ubi, e, aeb->vol_id, aeb->lnum, 0, false)) {
- wl_entry_destroy(ubi, e);
+ err = erase_aeb(ubi, aeb, sync);
+ if (err)
goto out_free;
- }
}
found_pebs++;
^ permalink raw reply
* [PATCH 4.4 106/107] ubi: Fix Fastmaps update_vol()
From: Greg Kroah-Hartman @ 2018-07-23 12:42 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Richard Weinberger, Boris Brezillon
In-Reply-To: <20180723122413.003644357@linuxfoundation.org>
4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Richard Weinberger <richard@nod.at>
commit f7d11b33d4e8cedf19367c09b891bbc705163976 upstream.
Usually Fastmap is free to consider every PEB in one of the pools
as newer than the existing PEB. Since PEBs in a pool are by definition
newer than everything else.
But update_vol() missed the case that a pool can contain more than
one candidate.
Cc: <stable@vger.kernel.org>
Fixes: dbb7d2a88d ("UBI: Add fastmap core")
Signed-off-by: Richard Weinberger <richard@nod.at>
Reviewed-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Signed-off-by: Richard Weinberger <richard@nod.at>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mtd/ubi/fastmap.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/mtd/ubi/fastmap.c
+++ b/drivers/mtd/ubi/fastmap.c
@@ -326,6 +326,7 @@ static int update_vol(struct ubi_device
aeb->pnum = new_aeb->pnum;
aeb->copy_flag = new_vh->copy_flag;
aeb->scrub = new_aeb->scrub;
+ aeb->sqnum = new_aeb->sqnum;
kmem_cache_free(ai->aeb_slab_cache, new_aeb);
/* new_aeb is older */
^ permalink raw reply
* [PATCH 4.4 105/107] ubi: Fix races around ubi_refill_pools()
From: Greg Kroah-Hartman @ 2018-07-23 12:42 UTC (permalink / raw)
To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Richard Weinberger
In-Reply-To: <20180723122413.003644357@linuxfoundation.org>
4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Richard Weinberger <richard@nod.at>
commit 2e8f08deabbc7eefe4c5838aaa6aa9a23a8acf2e upstream.
When writing a new Fastmap the first thing that happens
is refilling the pools in memory.
At this stage it is possible that new PEBs from the new pools
get already claimed and written with data.
If this happens before the new Fastmap data structure hits the
flash and we face power cut the freshly written PEB will not
scanned and unnoticed.
Solve the issue by locking the pools until Fastmap is written.
Cc: <stable@vger.kernel.org>
Fixes: dbb7d2a88d ("UBI: Add fastmap core")
Signed-off-by: Richard Weinberger <richard@nod.at>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mtd/ubi/eba.c | 4 ++--
drivers/mtd/ubi/fastmap-wl.c | 6 ++++--
drivers/mtd/ubi/fastmap.c | 14 ++++++++++----
drivers/mtd/ubi/wl.c | 20 ++++++++++++++------
4 files changed, 30 insertions(+), 14 deletions(-)
--- a/drivers/mtd/ubi/eba.c
+++ b/drivers/mtd/ubi/eba.c
@@ -1178,6 +1178,8 @@ int ubi_eba_copy_leb(struct ubi_device *
struct ubi_volume *vol;
uint32_t crc;
+ ubi_assert(rwsem_is_locked(&ubi->fm_eba_sem));
+
vol_id = be32_to_cpu(vid_hdr->vol_id);
lnum = be32_to_cpu(vid_hdr->lnum);
@@ -1346,9 +1348,7 @@ int ubi_eba_copy_leb(struct ubi_device *
}
ubi_assert(vol->eba_tbl[lnum] == from);
- down_read(&ubi->fm_eba_sem);
vol->eba_tbl[lnum] = to;
- up_read(&ubi->fm_eba_sem);
out_unlock_buf:
mutex_unlock(&ubi->buf_mutex);
--- a/drivers/mtd/ubi/fastmap-wl.c
+++ b/drivers/mtd/ubi/fastmap-wl.c
@@ -262,6 +262,8 @@ static struct ubi_wl_entry *get_peb_for_
struct ubi_fm_pool *pool = &ubi->fm_wl_pool;
int pnum;
+ ubi_assert(rwsem_is_locked(&ubi->fm_eba_sem));
+
if (pool->used == pool->size) {
/* We cannot update the fastmap here because this
* function is called in atomic context.
@@ -303,7 +305,7 @@ int ubi_ensure_anchor_pebs(struct ubi_de
wrk->anchor = 1;
wrk->func = &wear_leveling_worker;
- schedule_ubi_work(ubi, wrk);
+ __schedule_ubi_work(ubi, wrk);
return 0;
}
@@ -344,7 +346,7 @@ int ubi_wl_put_fm_peb(struct ubi_device
spin_unlock(&ubi->wl_lock);
vol_id = lnum ? UBI_FM_DATA_VOLUME_ID : UBI_FM_SB_VOLUME_ID;
- return schedule_erase(ubi, e, vol_id, lnum, torture);
+ return schedule_erase(ubi, e, vol_id, lnum, torture, true);
}
/**
--- a/drivers/mtd/ubi/fastmap.c
+++ b/drivers/mtd/ubi/fastmap.c
@@ -1514,22 +1514,30 @@ int ubi_update_fastmap(struct ubi_device
struct ubi_wl_entry *tmp_e;
down_write(&ubi->fm_protect);
+ down_write(&ubi->work_sem);
+ down_write(&ubi->fm_eba_sem);
ubi_refill_pools(ubi);
if (ubi->ro_mode || ubi->fm_disabled) {
+ up_write(&ubi->fm_eba_sem);
+ up_write(&ubi->work_sem);
up_write(&ubi->fm_protect);
return 0;
}
ret = ubi_ensure_anchor_pebs(ubi);
if (ret) {
+ up_write(&ubi->fm_eba_sem);
+ up_write(&ubi->work_sem);
up_write(&ubi->fm_protect);
return ret;
}
new_fm = kzalloc(sizeof(*new_fm), GFP_KERNEL);
if (!new_fm) {
+ up_write(&ubi->fm_eba_sem);
+ up_write(&ubi->work_sem);
up_write(&ubi->fm_protect);
return -ENOMEM;
}
@@ -1638,16 +1646,14 @@ int ubi_update_fastmap(struct ubi_device
new_fm->e[0] = tmp_e;
}
- down_write(&ubi->work_sem);
- down_write(&ubi->fm_eba_sem);
ret = ubi_write_fastmap(ubi, new_fm);
- up_write(&ubi->fm_eba_sem);
- up_write(&ubi->work_sem);
if (ret)
goto err;
out_unlock:
+ up_write(&ubi->fm_eba_sem);
+ up_write(&ubi->work_sem);
up_write(&ubi->fm_protect);
kfree(old_fm);
return ret;
--- a/drivers/mtd/ubi/wl.c
+++ b/drivers/mtd/ubi/wl.c
@@ -580,7 +580,7 @@ static int erase_worker(struct ubi_devic
* failure.
*/
static int schedule_erase(struct ubi_device *ubi, struct ubi_wl_entry *e,
- int vol_id, int lnum, int torture)
+ int vol_id, int lnum, int torture, bool nested)
{
struct ubi_work *wl_wrk;
@@ -599,7 +599,10 @@ static int schedule_erase(struct ubi_dev
wl_wrk->lnum = lnum;
wl_wrk->torture = torture;
- schedule_ubi_work(ubi, wl_wrk);
+ if (nested)
+ __schedule_ubi_work(ubi, wl_wrk);
+ else
+ schedule_ubi_work(ubi, wl_wrk);
return 0;
}
@@ -658,6 +661,7 @@ static int wear_leveling_worker(struct u
if (!vid_hdr)
return -ENOMEM;
+ down_read(&ubi->fm_eba_sem);
mutex_lock(&ubi->move_mutex);
spin_lock(&ubi->wl_lock);
ubi_assert(!ubi->move_from && !ubi->move_to);
@@ -884,6 +888,7 @@ static int wear_leveling_worker(struct u
dbg_wl("done");
mutex_unlock(&ubi->move_mutex);
+ up_read(&ubi->fm_eba_sem);
return 0;
/*
@@ -925,6 +930,7 @@ out_not_moved:
}
mutex_unlock(&ubi->move_mutex);
+ up_read(&ubi->fm_eba_sem);
return 0;
out_error:
@@ -946,6 +952,7 @@ out_error:
out_ro:
ubi_ro_mode(ubi);
mutex_unlock(&ubi->move_mutex);
+ up_read(&ubi->fm_eba_sem);
ubi_assert(err != 0);
return err < 0 ? err : -EIO;
@@ -953,6 +960,7 @@ out_cancel:
ubi->wl_scheduled = 0;
spin_unlock(&ubi->wl_lock);
mutex_unlock(&ubi->move_mutex);
+ up_read(&ubi->fm_eba_sem);
ubi_free_vid_hdr(ubi, vid_hdr);
return 0;
}
@@ -1075,7 +1083,7 @@ static int __erase_worker(struct ubi_dev
int err1;
/* Re-schedule the LEB for erasure */
- err1 = schedule_erase(ubi, e, vol_id, lnum, 0);
+ err1 = schedule_erase(ubi, e, vol_id, lnum, 0, false);
if (err1) {
wl_entry_destroy(ubi, e);
err = err1;
@@ -1256,7 +1264,7 @@ retry:
}
spin_unlock(&ubi->wl_lock);
- err = schedule_erase(ubi, e, vol_id, lnum, torture);
+ err = schedule_erase(ubi, e, vol_id, lnum, torture, false);
if (err) {
spin_lock(&ubi->wl_lock);
wl_tree_add(e, &ubi->used);
@@ -1544,7 +1552,7 @@ int ubi_wl_init(struct ubi_device *ubi,
e->pnum = aeb->pnum;
e->ec = aeb->ec;
ubi->lookuptbl[e->pnum] = e;
- if (schedule_erase(ubi, e, aeb->vol_id, aeb->lnum, 0)) {
+ if (schedule_erase(ubi, e, aeb->vol_id, aeb->lnum, 0, false)) {
wl_entry_destroy(ubi, e);
goto out_free;
}
@@ -1624,7 +1632,7 @@ int ubi_wl_init(struct ubi_device *ubi,
e->ec = aeb->ec;
ubi_assert(!ubi->lookuptbl[e->pnum]);
ubi->lookuptbl[e->pnum] = e;
- if (schedule_erase(ubi, e, aeb->vol_id, aeb->lnum, 0)) {
+ if (schedule_erase(ubi, e, aeb->vol_id, aeb->lnum, 0, false)) {
wl_entry_destroy(ubi, e);
goto out_free;
}
^ permalink raw reply
* Re: [PATCH v2] f2fs: split discard command in prior to block layer
From: Jaegeuk Kim @ 2018-07-23 12:47 UTC (permalink / raw)
To: Chao Yu; +Cc: linux-f2fs-devel, linux-kernel, Chao Yu
In-Reply-To: <30b14b7b-4036-d8a7-c477-0f578449e18d@kernel.org>
On 07/15, Chao Yu wrote:
> On 2018/7/15 11:13, Jaegeuk Kim wrote:
> > On 07/15, Chao Yu wrote:
> >> Hi Jaegeuk,
> >>
> >> On 2018/7/15 9:27, Jaegeuk Kim wrote:
> >>> On 07/08, Chao Yu wrote:
> >>>> From: Chao Yu <yuchao0@huawei.com>
> >>>>
> >>>> Some devices has small max_{hw,}discard_sectors, so that in
> >>>> __blkdev_issue_discard(), one big size discard bio can be split
> >>>> into multiple small size discard bios, result in heavy load in IO
> >>>> scheduler and device, which can hang other sync IO for long time.
> >>>>
> >>>> Now, f2fs is trying to control discard commands more elaboratively,
> >>>> in order to make less conflict in between discard IO and user IO
> >>>> to enhance application's performance, so in this patch, we will
> >>>> split discard bio in f2fs in prior to in block layer to reduce
> >>>> issuing multiple discard bios in a short time.
> >>>
> >>> Can we just change __submit_discard_cmd() to submit the large candidate
> >>> partially and adjust lstart in the original candidate?
> >>
> >> Yep, could you check __submit_discard_cmd() implementation below? Does that
> >> match the thoughts from you?
> >>
> >> Thanks,
> >>
> >>>
> >>>>
> >>>> Signed-off-by: Chao Yu <yuchao0@huawei.com>
> >>>> ---
> >>>> v2:
> >>>> - change to split discard command entry before submission.
> >>>> fs/f2fs/f2fs.h | 13 +++---
> >>>> fs/f2fs/segment.c | 117 +++++++++++++++++++++++++++++++++++++-----------------
> >>>> 2 files changed, 86 insertions(+), 44 deletions(-)
> >>>>
> >>>> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> >>>> index c48b655d5d8d..359526d88d3f 100644
> >>>> --- a/fs/f2fs/f2fs.h
> >>>> +++ b/fs/f2fs/f2fs.h
> >>>> @@ -178,7 +178,6 @@ enum {
> >>>>
> >>>> #define MAX_DISCARD_BLOCKS(sbi) BLKS_PER_SEC(sbi)
> >>>> #define DEF_MAX_DISCARD_REQUEST 8 /* issue 8 discards per round */
> >>>> -#define DEF_MAX_DISCARD_LEN 512 /* Max. 2MB per discard */
> >>>> #define DEF_MIN_DISCARD_ISSUE_TIME 50 /* 50 ms, if exists */
> >>>> #define DEF_MID_DISCARD_ISSUE_TIME 500 /* 500 ms, if device busy */
> >>>> #define DEF_MAX_DISCARD_ISSUE_TIME 60000 /* 60 s, if no candidates */
> >>>> @@ -709,22 +708,22 @@ static inline void set_extent_info(struct extent_info *ei, unsigned int fofs,
> >>>> }
> >>>>
> >>>> static inline bool __is_discard_mergeable(struct discard_info *back,
> >>>> - struct discard_info *front)
> >>>> + struct discard_info *front, unsigned int max_len)
> >>>> {
> >>>> return (back->lstart + back->len == front->lstart) &&
> >>>> - (back->len + front->len < DEF_MAX_DISCARD_LEN);
> >>>> + (back->len + front->len <= max_len);
> >>>> }
> >>>>
> >>>> static inline bool __is_discard_back_mergeable(struct discard_info *cur,
> >>>> - struct discard_info *back)
> >>>> + struct discard_info *back, unsigned int max_len)
> >>>> {
> >>>> - return __is_discard_mergeable(back, cur);
> >>>> + return __is_discard_mergeable(back, cur, max_len);
> >>>> }
> >>>>
> >>>> static inline bool __is_discard_front_mergeable(struct discard_info *cur,
> >>>> - struct discard_info *front)
> >>>> + struct discard_info *front, unsigned int max_len)
> >>>> {
> >>>> - return __is_discard_mergeable(cur, front);
> >>>> + return __is_discard_mergeable(cur, front, max_len);
> >>>> }
> >>>>
> >>>> static inline bool __is_extent_mergeable(struct extent_info *back,
> >>>> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> >>>> index f7f56dd091b4..cbf8f3f9a8e7 100644
> >>>> --- a/fs/f2fs/segment.c
> >>>> +++ b/fs/f2fs/segment.c
> >>>> @@ -966,17 +966,24 @@ static void __init_discard_policy(struct f2fs_sb_info *sbi,
> >>>> }
> >>>> }
> >>>>
> >>>> -
> >
> > ===================== BEGIN
> >
> >>>> +static void __update_discard_tree_range(struct f2fs_sb_info *sbi,
> >>>> + struct block_device *bdev, block_t lstart,
> >>>> + block_t start, block_t len);
> >>>> /* this function is copied from blkdev_issue_discard from block/blk-lib.c */
> >>>> static void __submit_discard_cmd(struct f2fs_sb_info *sbi,
> >>>> struct discard_policy *dpolicy,
> >>>> - struct discard_cmd *dc)
> >>>> + struct discard_cmd *dc,
> >>>> + unsigned int *issued)
> >>>> {
> >>>> + struct block_device *bdev = dc->bdev;
> >>>> + struct request_queue *q = bdev_get_queue(bdev);
> >>>> + unsigned int max_discard_blocks =
> >>>> + SECTOR_TO_BLOCK(q->limits.max_discard_sectors);
> >>>> struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
> >>>> struct list_head *wait_list = (dpolicy->type == DPOLICY_FSTRIM) ?
> >>>> &(dcc->fstrim_list) : &(dcc->wait_list);
> >>>> - struct bio *bio = NULL;
> >>>> int flag = dpolicy->sync ? REQ_SYNC : 0;
> >>>> + block_t lstart, start, len, total_len;
> >>>>
> >>>> if (dc->state != D_PREP)
> >>>> return;
> >>>> @@ -984,30 +991,63 @@ static void __submit_discard_cmd(struct f2fs_sb_info *sbi,
> >>>> if (is_sbi_flag_set(sbi, SBI_NEED_FSCK))
> >>>> return;
> >>>>
> >>>> - trace_f2fs_issue_discard(dc->bdev, dc->start, dc->len);
> >>>> -
> >>>> - dc->error = __blkdev_issue_discard(dc->bdev,
> >>>> - SECTOR_FROM_BLOCK(dc->start),
> >>>> - SECTOR_FROM_BLOCK(dc->len),
> >>>> - GFP_NOFS, 0, &bio);
> >>>> - if (!dc->error) {
> >>>> - /* should keep before submission to avoid D_DONE right away */
> >>>> - dc->state = D_SUBMIT;
> >>>> - atomic_inc(&dcc->issued_discard);
> >>>> - atomic_inc(&dcc->issing_discard);
> >>>> - if (bio) {
> >>>> - bio->bi_private = dc;
> >>>> - bio->bi_end_io = f2fs_submit_discard_endio;
> >>>> - bio->bi_opf |= flag;
> >>>> - submit_bio(bio);
> >>>> - list_move_tail(&dc->list, wait_list);
> >>>> - __check_sit_bitmap(sbi, dc->start, dc->start + dc->len);
> >>>> -
> >>>> - f2fs_update_iostat(sbi, FS_DISCARD, 1);
> >>>> + trace_f2fs_issue_discard(bdev, dc->start, dc->len);
> >>>> +
> >>>> + lstart = dc->lstart;
> >>>> + start = dc->start;
> >>>> + len = dc->len;
> >>>> + total_len = len;
> >>>> +
> >>>> + while (total_len && *issued < dpolicy->max_requests) {
> >>>> + struct bio *bio = NULL;
> >>>> +
> >>>> + if (len > max_discard_blocks)
> >>>> + len = max_discard_blocks;
> >>>> +
> >>>> + dc->error = __blkdev_issue_discard(bdev,
> >>>> + SECTOR_FROM_BLOCK(start),
> >>>> + SECTOR_FROM_BLOCK(len),
> >>>> + GFP_NOFS, 0, &bio);
> >>>> + if (!dc->error) {
> >>>> + /*
> >>>> + * should keep before submission to avoid D_DONE
> >>>> + * right away
> >>>> + */
> >>>> + dc->state = D_SUBMIT;
> >>>> + dc->len = len;
> >>>> + atomic_inc(&dcc->issued_discard);
> >>>> + atomic_inc(&dcc->issing_discard);
> >>>> + if (bio) {
> >>>> + bio->bi_private = dc;
> >>>> + bio->bi_end_io = f2fs_submit_discard_endio;
> >>>> + bio->bi_opf |= flag;
> >>>> + submit_bio(bio);
> >>>> + list_move_tail(&dc->list, wait_list);
> >>>> + __check_sit_bitmap(sbi, dc->start,
> >>>> + dc->start + dc->len);
> >>>> +
> >>>> + f2fs_update_iostat(sbi, FS_DISCARD, 1);
> >>>> + }
> >>>> + } else {
> >>>> + __remove_discard_cmd(sbi, dc);
> >
> > Keep the original one, since it's partially failed?
>
> During __submit_discard_cmd(), we are trying to split original dc into multiple
> dc, and once we failed to submit some of them, we will remove corresponding dc,
> the removal logic is the same as before, not being changed...
>
> If we want to keep failed dc and do retry, we'd better add another patch for
> that, right?
I thought removing failed portion of the dc.
>
> >
> >>>> + return;
> >>>> + }
> >>>> + lstart += len;
> >>>> + start += len;
> >>>> + total_len -= len;
> >>>> + len = total_len;
> >>>> + (*issued)++;
> >>>> +
> >>>> + if (len) {
> >>>> + __update_discard_tree_range(sbi, bdev, lstart,
> >>>> + start, len);
> >
> > Do we really need this? We already grabbed one candidate which was not merged
> > well.
>
> You mean submitting multiple bios based on one large size dc?
Yes.
>
> Previously, one bio references to one dc as below, in end_io, it will change
> dc->state which can be detected by its own waiter.
>
> bio->bi_private = dc;
> bio->bi_end_io = f2fs_submit_discard_endio;
> bio->bi_opf |= flag;
>
> If multiple bios reference to one dc, it will be more complicated to handle
> that. How do you think?
I was concerned about too many entries in the lists. How about adding a refcnt
to count how many bios were issued on the dc?
Thanks,
>
> Thanks,
>
> >
> >>>> + dc = (struct discard_cmd *)f2fs_lookup_rb_tree(
> >>>> + &dcc->root, NULL, lstart);
> >>>> + f2fs_bug_on(sbi, !dc);
> >>>> }
> >>>> - } else {
> >>>> - __remove_discard_cmd(sbi, dc);
> >>>> }
> >>>> +
> >>>> + return;
> >>>> }
> >
> > ======================= END
> >
> >
> >>>>
> >>>> static struct discard_cmd *__insert_discard_tree(struct f2fs_sb_info *sbi,
> >>>> @@ -1088,10 +1128,11 @@ static void __update_discard_tree_range(struct f2fs_sb_info *sbi,
> >>>> struct discard_cmd *dc;
> >>>> struct discard_info di = {0};
> >>>> struct rb_node **insert_p = NULL, *insert_parent = NULL;
> >>>> + struct request_queue *q = bdev_get_queue(bdev);
> >>>> + unsigned int max_discard_blocks =
> >>>> + SECTOR_TO_BLOCK(q->limits.max_discard_sectors);
> >>>> block_t end = lstart + len;
> >>>>
> >>>> - mutex_lock(&dcc->cmd_lock);
> >>>> -
> >>>> dc = (struct discard_cmd *)f2fs_lookup_rb_tree_ret(&dcc->root,
> >>>> NULL, lstart,
> >>>> (struct rb_entry **)&prev_dc,
> >>>> @@ -1131,7 +1172,8 @@ static void __update_discard_tree_range(struct f2fs_sb_info *sbi,
> >>>>
> >>>> if (prev_dc && prev_dc->state == D_PREP &&
> >>>> prev_dc->bdev == bdev &&
> >>>> - __is_discard_back_mergeable(&di, &prev_dc->di)) {
> >>>> + __is_discard_back_mergeable(&di, &prev_dc->di,
> >>>> + max_discard_blocks)) {
> >>>> prev_dc->di.len += di.len;
> >>>> dcc->undiscard_blks += di.len;
> >>>> __relocate_discard_cmd(dcc, prev_dc);
> >>>> @@ -1142,7 +1184,8 @@ static void __update_discard_tree_range(struct f2fs_sb_info *sbi,
> >>>>
> >>>> if (next_dc && next_dc->state == D_PREP &&
> >>>> next_dc->bdev == bdev &&
> >>>> - __is_discard_front_mergeable(&di, &next_dc->di)) {
> >>>> + __is_discard_front_mergeable(&di, &next_dc->di,
> >>>> + max_discard_blocks)) {
> >>>> next_dc->di.lstart = di.lstart;
> >>>> next_dc->di.len += di.len;
> >>>> next_dc->di.start = di.start;
> >>>> @@ -1165,8 +1208,6 @@ static void __update_discard_tree_range(struct f2fs_sb_info *sbi,
> >>>> node = rb_next(&prev_dc->rb_node);
> >>>> next_dc = rb_entry_safe(node, struct discard_cmd, rb_node);
> >>>> }
> >>>> -
> >>>> - mutex_unlock(&dcc->cmd_lock);
> >>>> }
> >>>>
> >>>> static int __queue_discard_cmd(struct f2fs_sb_info *sbi,
> >>>> @@ -1181,7 +1222,9 @@ static int __queue_discard_cmd(struct f2fs_sb_info *sbi,
> >>>>
> >>>> blkstart -= FDEV(devi).start_blk;
> >>>> }
> >>>> + mutex_lock(&SM_I(sbi)->dcc_info->cmd_lock);
> >>>> __update_discard_tree_range(sbi, bdev, lblkstart, blkstart, blklen);
> >>>> + mutex_unlock(&SM_I(sbi)->dcc_info->cmd_lock);
> >>>> return 0;
> >>>> }
> >>>>
> >>>> @@ -1220,9 +1263,9 @@ static unsigned int __issue_discard_cmd_orderly(struct f2fs_sb_info *sbi,
> >>>> }
> >>>>
> >>>> dcc->next_pos = dc->lstart + dc->len;
> >>>> - __submit_discard_cmd(sbi, dpolicy, dc);
> >>>> + __submit_discard_cmd(sbi, dpolicy, dc, &issued);
> >>>>
> >>>> - if (++issued >= dpolicy->max_requests)
> >>>> + if (issued >= dpolicy->max_requests)
> >>>> break;
> >>>> next:
> >>>> node = rb_next(&dc->rb_node);
> >>>> @@ -1277,9 +1320,9 @@ static int __issue_discard_cmd(struct f2fs_sb_info *sbi,
> >>>> break;
> >>>> }
> >>>>
> >>>> - __submit_discard_cmd(sbi, dpolicy, dc);
> >>>> + __submit_discard_cmd(sbi, dpolicy, dc, &issued);
> >>>>
> >>>> - if (++issued >= dpolicy->max_requests)
> >>>> + if (issued >= dpolicy->max_requests)
> >>>> break;
> >>>> }
> >>>> blk_finish_plug(&plug);
> >>>> @@ -2475,9 +2518,9 @@ static unsigned int __issue_discard_cmd_range(struct f2fs_sb_info *sbi,
> >>>> goto skip;
> >>>> }
> >>>>
> >>>> - __submit_discard_cmd(sbi, dpolicy, dc);
> >>>> + __submit_discard_cmd(sbi, dpolicy, dc, &issued);
> >>>>
> >>>> - if (++issued >= dpolicy->max_requests) {
> >>>> + if (issued >= dpolicy->max_requests) {
> >>>> start = dc->lstart + dc->len;
> >>>>
> >>>> blk_finish_plug(&plug);
> >>>> --
> >>>> 2.16.2.17.g38e79b1fd
^ permalink raw reply
* [PATCH 4.4 062/107] prctl: Add speculation control prctls
From: Greg Kroah-Hartman @ 2018-07-23 12:41 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Thomas Gleixner, Ingo Molnar,
Konrad Rzeszutek Wilk, David Woodhouse, Srivatsa S. Bhat,
Matt Helsley (VMware), Alexey Makhalov, Bo Gan
In-Reply-To: <20180723122413.003644357@linuxfoundation.org>
4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Gleixner <tglx@linutronix.de>
commit b617cfc858161140d69cc0b5cc211996b557a1c7 upstream
Add two new prctls to control aspects of speculation related vulnerabilites
and their mitigations to provide finer grained control over performance
impacting mitigations.
PR_GET_SPECULATION_CTRL returns the state of the speculation misfeature
which is selected with arg2 of prctl(2). The return value uses bit 0-2 with
the following meaning:
Bit Define Description
0 PR_SPEC_PRCTL Mitigation can be controlled per task by
PR_SET_SPECULATION_CTRL
1 PR_SPEC_ENABLE The speculation feature is enabled, mitigation is
disabled
2 PR_SPEC_DISABLE The speculation feature is disabled, mitigation is
enabled
If all bits are 0 the CPU is not affected by the speculation misfeature.
If PR_SPEC_PRCTL is set, then the per task control of the mitigation is
available. If not set, prctl(PR_SET_SPECULATION_CTRL) for the speculation
misfeature will fail.
PR_SET_SPECULATION_CTRL allows to control the speculation misfeature, which
is selected by arg2 of prctl(2) per task. arg3 is used to hand in the
control value, i.e. either PR_SPEC_ENABLE or PR_SPEC_DISABLE.
The common return values are:
EINVAL prctl is not implemented by the architecture or the unused prctl()
arguments are not 0
ENODEV arg2 is selecting a not supported speculation misfeature
PR_SET_SPECULATION_CTRL has these additional return values:
ERANGE arg3 is incorrect, i.e. it's not either PR_SPEC_ENABLE or PR_SPEC_DISABLE
ENXIO prctl control of the selected speculation misfeature is disabled
The first supported controlable speculation misfeature is
PR_SPEC_STORE_BYPASS. Add the define so this can be shared between
architectures.
Based on an initial patch from Tim Chen and mostly rewritten.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Srivatsa S. Bhat <srivatsa@csail.mit.edu>
Reviewed-by: Matt Helsley (VMware) <matt.helsley@gmail.com>
Reviewed-by: Alexey Makhalov <amakhalov@vmware.com>
Reviewed-by: Bo Gan <ganb@vmware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
Documentation/spec_ctrl.txt | 86 ++++++++++++++++++++++++++++++++++++++++++++
include/linux/nospec.h | 5 ++
include/uapi/linux/prctl.h | 11 +++++
kernel/sys.c | 20 ++++++++++
4 files changed, 122 insertions(+)
create mode 100644 Documentation/spec_ctrl.txt
--- /dev/null
+++ b/Documentation/spec_ctrl.txt
@@ -0,0 +1,86 @@
+===================
+Speculation Control
+===================
+
+Quite some CPUs have speculation related misfeatures which are in fact
+vulnerabilites causing data leaks in various forms even accross privilege
+domains.
+
+The kernel provides mitigation for such vulnerabilities in various
+forms. Some of these mitigations are compile time configurable and some on
+the kernel command line.
+
+There is also a class of mitigations which are very expensive, but they can
+be restricted to a certain set of processes or tasks in controlled
+environments. The mechanism to control these mitigations is via
+:manpage:`prctl(2)`.
+
+There are two prctl options which are related to this:
+
+ * PR_GET_SPECULATION_CTRL
+
+ * PR_SET_SPECULATION_CTRL
+
+PR_GET_SPECULATION_CTRL
+-----------------------
+
+PR_GET_SPECULATION_CTRL returns the state of the speculation misfeature
+which is selected with arg2 of prctl(2). The return value uses bits 0-2 with
+the following meaning:
+
+==== ================ ===================================================
+Bit Define Description
+==== ================ ===================================================
+0 PR_SPEC_PRCTL Mitigation can be controlled per task by
+ PR_SET_SPECULATION_CTRL
+1 PR_SPEC_ENABLE The speculation feature is enabled, mitigation is
+ disabled
+2 PR_SPEC_DISABLE The speculation feature is disabled, mitigation is
+ enabled
+==== ================ ===================================================
+
+If all bits are 0 the CPU is not affected by the speculation misfeature.
+
+If PR_SPEC_PRCTL is set, then the per task control of the mitigation is
+available. If not set, prctl(PR_SET_SPECULATION_CTRL) for the speculation
+misfeature will fail.
+
+PR_SET_SPECULATION_CTRL
+-----------------------
+PR_SET_SPECULATION_CTRL allows to control the speculation misfeature, which
+is selected by arg2 of :manpage:`prctl(2)` per task. arg3 is used to hand
+in the control value, i.e. either PR_SPEC_ENABLE or PR_SPEC_DISABLE.
+
+Common error codes
+------------------
+======= =================================================================
+Value Meaning
+======= =================================================================
+EINVAL The prctl is not implemented by the architecture or unused
+ prctl(2) arguments are not 0
+
+ENODEV arg2 is selecting a not supported speculation misfeature
+======= =================================================================
+
+PR_SET_SPECULATION_CTRL error codes
+-----------------------------------
+======= =================================================================
+Value Meaning
+======= =================================================================
+0 Success
+
+ERANGE arg3 is incorrect, i.e. it's neither PR_SPEC_ENABLE nor
+ PR_SPEC_DISABLE
+
+ENXIO Control of the selected speculation misfeature is not possible.
+ See PR_GET_SPECULATION_CTRL.
+======= =================================================================
+
+Speculation misfeature controls
+-------------------------------
+- PR_SPEC_STORE_BYPASS: Speculative Store Bypass
+
+ Invocations:
+ * prctl(PR_GET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, 0, 0, 0);
+ * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_ENABLE, 0, 0);
+ * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_DISABLE, 0, 0);
--- a/include/linux/nospec.h
+++ b/include/linux/nospec.h
@@ -55,4 +55,9 @@ static inline unsigned long array_index_
\
(typeof(_i)) (_i & _mask); \
})
+
+/* Speculation control prctl */
+int arch_prctl_spec_ctrl_get(unsigned long which);
+int arch_prctl_spec_ctrl_set(unsigned long which, unsigned long ctrl);
+
#endif /* _LINUX_NOSPEC_H */
--- a/include/uapi/linux/prctl.h
+++ b/include/uapi/linux/prctl.h
@@ -197,4 +197,15 @@ struct prctl_mm_map {
# define PR_CAP_AMBIENT_LOWER 3
# define PR_CAP_AMBIENT_CLEAR_ALL 4
+/* Per task speculation control */
+#define PR_GET_SPECULATION_CTRL 52
+#define PR_SET_SPECULATION_CTRL 53
+/* Speculation control variants */
+# define PR_SPEC_STORE_BYPASS 0
+/* Return and control values for PR_SET/GET_SPECULATION_CTRL */
+# define PR_SPEC_NOT_AFFECTED 0
+# define PR_SPEC_PRCTL (1UL << 0)
+# define PR_SPEC_ENABLE (1UL << 1)
+# define PR_SPEC_DISABLE (1UL << 2)
+
#endif /* _LINUX_PRCTL_H */
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -2075,6 +2075,16 @@ static int prctl_get_tid_address(struct
}
#endif
+int __weak arch_prctl_spec_ctrl_get(unsigned long which)
+{
+ return -EINVAL;
+}
+
+int __weak arch_prctl_spec_ctrl_set(unsigned long which, unsigned long ctrl)
+{
+ return -EINVAL;
+}
+
SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
unsigned long, arg4, unsigned long, arg5)
{
@@ -2269,6 +2279,16 @@ SYSCALL_DEFINE5(prctl, int, option, unsi
case PR_GET_FP_MODE:
error = GET_FP_MODE(me);
break;
+ case PR_GET_SPECULATION_CTRL:
+ if (arg3 || arg4 || arg5)
+ return -EINVAL;
+ error = arch_prctl_spec_ctrl_get(arg2);
+ break;
+ case PR_SET_SPECULATION_CTRL:
+ if (arg4 || arg5)
+ return -EINVAL;
+ error = arch_prctl_spec_ctrl_set(arg2, arg3);
+ break;
default:
error = -EINVAL;
break;
^ permalink raw reply
* [PATCH 4.4 071/107] prctl: Add force disable speculation
From: Greg Kroah-Hartman @ 2018-07-23 12:42 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Thomas Gleixner, David Woodhouse,
Srivatsa S. Bhat, Matt Helsley (VMware), Alexey Makhalov, Bo Gan
In-Reply-To: <20180723122413.003644357@linuxfoundation.org>
4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Gleixner <tglx@linutronix.de>
commit 356e4bfff2c5489e016fdb925adbf12a1e3950ee upstream
For certain use cases it is desired to enforce mitigations so they cannot
be undone afterwards. That's important for loader stubs which want to
prevent a child from disabling the mitigation again. Will also be used for
seccomp(). The extra state preserving of the prctl state for SSB is a
preparatory step for EBPF dymanic speculation control.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Srivatsa S. Bhat <srivatsa@csail.mit.edu>
Reviewed-by: Matt Helsley (VMware) <matt.helsley@gmail.com>
Reviewed-by: Alexey Makhalov <amakhalov@vmware.com>
Reviewed-by: Bo Gan <ganb@vmware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
Documentation/spec_ctrl.txt | 34 +++++++++++++++++++++-------------
arch/x86/kernel/cpu/bugs.c | 35 +++++++++++++++++++++++++----------
fs/proc/array.c | 3 +++
include/linux/sched.h | 9 +++++++++
include/uapi/linux/prctl.h | 1 +
5 files changed, 59 insertions(+), 23 deletions(-)
--- a/Documentation/spec_ctrl.txt
+++ b/Documentation/spec_ctrl.txt
@@ -25,19 +25,21 @@ PR_GET_SPECULATION_CTRL
-----------------------
PR_GET_SPECULATION_CTRL returns the state of the speculation misfeature
-which is selected with arg2 of prctl(2). The return value uses bits 0-2 with
+which is selected with arg2 of prctl(2). The return value uses bits 0-3 with
the following meaning:
-==== ================ ===================================================
-Bit Define Description
-==== ================ ===================================================
-0 PR_SPEC_PRCTL Mitigation can be controlled per task by
- PR_SET_SPECULATION_CTRL
-1 PR_SPEC_ENABLE The speculation feature is enabled, mitigation is
- disabled
-2 PR_SPEC_DISABLE The speculation feature is disabled, mitigation is
- enabled
-==== ================ ===================================================
+==== ===================== ===================================================
+Bit Define Description
+==== ===================== ===================================================
+0 PR_SPEC_PRCTL Mitigation can be controlled per task by
+ PR_SET_SPECULATION_CTRL
+1 PR_SPEC_ENABLE The speculation feature is enabled, mitigation is
+ disabled
+2 PR_SPEC_DISABLE The speculation feature is disabled, mitigation is
+ enabled
+3 PR_SPEC_FORCE_DISABLE Same as PR_SPEC_DISABLE, but cannot be undone. A
+ subsequent prctl(..., PR_SPEC_ENABLE) will fail.
+==== ===================== ===================================================
If all bits are 0 the CPU is not affected by the speculation misfeature.
@@ -47,9 +49,11 @@ misfeature will fail.
PR_SET_SPECULATION_CTRL
-----------------------
+
PR_SET_SPECULATION_CTRL allows to control the speculation misfeature, which
is selected by arg2 of :manpage:`prctl(2)` per task. arg3 is used to hand
-in the control value, i.e. either PR_SPEC_ENABLE or PR_SPEC_DISABLE.
+in the control value, i.e. either PR_SPEC_ENABLE or PR_SPEC_DISABLE or
+PR_SPEC_FORCE_DISABLE.
Common error codes
------------------
@@ -70,10 +74,13 @@ Value Meaning
0 Success
ERANGE arg3 is incorrect, i.e. it's neither PR_SPEC_ENABLE nor
- PR_SPEC_DISABLE
+ PR_SPEC_DISABLE nor PR_SPEC_FORCE_DISABLE
ENXIO Control of the selected speculation misfeature is not possible.
See PR_GET_SPECULATION_CTRL.
+
+EPERM Speculation was disabled with PR_SPEC_FORCE_DISABLE and caller
+ tried to enable it again.
======= =================================================================
Speculation misfeature controls
@@ -84,3 +91,4 @@ Speculation misfeature controls
* prctl(PR_GET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, 0, 0, 0);
* prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_ENABLE, 0, 0);
* prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_DISABLE, 0, 0);
+ * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_FORCE_DISABLE, 0, 0);
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -531,21 +531,37 @@ static void ssb_select_mitigation()
static int ssb_prctl_set(struct task_struct *task, unsigned long ctrl)
{
- bool rds = !!test_tsk_thread_flag(task, TIF_RDS);
+ bool update;
if (ssb_mode != SPEC_STORE_BYPASS_PRCTL)
return -ENXIO;
- if (ctrl == PR_SPEC_ENABLE)
- clear_tsk_thread_flag(task, TIF_RDS);
- else
- set_tsk_thread_flag(task, TIF_RDS);
+ switch (ctrl) {
+ case PR_SPEC_ENABLE:
+ /* If speculation is force disabled, enable is not allowed */
+ if (task_spec_ssb_force_disable(task))
+ return -EPERM;
+ task_clear_spec_ssb_disable(task);
+ update = test_and_clear_tsk_thread_flag(task, TIF_RDS);
+ break;
+ case PR_SPEC_DISABLE:
+ task_set_spec_ssb_disable(task);
+ update = !test_and_set_tsk_thread_flag(task, TIF_RDS);
+ break;
+ case PR_SPEC_FORCE_DISABLE:
+ task_set_spec_ssb_disable(task);
+ task_set_spec_ssb_force_disable(task);
+ update = !test_and_set_tsk_thread_flag(task, TIF_RDS);
+ break;
+ default:
+ return -ERANGE;
+ }
/*
* If being set on non-current task, delay setting the CPU
* mitigation until it is next scheduled.
*/
- if (task == current && rds != !!test_tsk_thread_flag(task, TIF_RDS))
+ if (task == current && update)
speculative_store_bypass_update();
return 0;
@@ -557,7 +573,9 @@ static int ssb_prctl_get(struct task_str
case SPEC_STORE_BYPASS_DISABLE:
return PR_SPEC_DISABLE;
case SPEC_STORE_BYPASS_PRCTL:
- if (test_tsk_thread_flag(task, TIF_RDS))
+ if (task_spec_ssb_force_disable(task))
+ return PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE;
+ if (task_spec_ssb_disable(task))
return PR_SPEC_PRCTL | PR_SPEC_DISABLE;
return PR_SPEC_PRCTL | PR_SPEC_ENABLE;
default:
@@ -570,9 +588,6 @@ static int ssb_prctl_get(struct task_str
int arch_prctl_spec_ctrl_set(struct task_struct *task, unsigned long which,
unsigned long ctrl)
{
- if (ctrl != PR_SPEC_ENABLE && ctrl != PR_SPEC_DISABLE)
- return -ERANGE;
-
switch (which) {
case PR_SPEC_STORE_BYPASS:
return ssb_prctl_set(task, ctrl);
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -341,6 +341,9 @@ static inline void task_seccomp(struct s
case PR_SPEC_NOT_AFFECTED:
seq_printf(m, "not vulnerable");
break;
+ case PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE:
+ seq_printf(m, "thread force mitigated");
+ break;
case PR_SPEC_PRCTL | PR_SPEC_DISABLE:
seq_printf(m, "thread mitigated");
break;
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -2167,6 +2167,8 @@ static inline void memalloc_noio_restore
#define PFA_NO_NEW_PRIVS 0 /* May not gain new privileges. */
#define PFA_SPREAD_PAGE 1 /* Spread page cache over cpuset */
#define PFA_SPREAD_SLAB 2 /* Spread some slab caches over cpuset */
+#define PFA_SPEC_SSB_DISABLE 4 /* Speculative Store Bypass disabled */
+#define PFA_SPEC_SSB_FORCE_DISABLE 5 /* Speculative Store Bypass force disabled*/
#define TASK_PFA_TEST(name, func) \
@@ -2190,6 +2192,13 @@ TASK_PFA_TEST(SPREAD_SLAB, spread_slab)
TASK_PFA_SET(SPREAD_SLAB, spread_slab)
TASK_PFA_CLEAR(SPREAD_SLAB, spread_slab)
+TASK_PFA_TEST(SPEC_SSB_DISABLE, spec_ssb_disable)
+TASK_PFA_SET(SPEC_SSB_DISABLE, spec_ssb_disable)
+TASK_PFA_CLEAR(SPEC_SSB_DISABLE, spec_ssb_disable)
+
+TASK_PFA_TEST(SPEC_SSB_FORCE_DISABLE, spec_ssb_force_disable)
+TASK_PFA_SET(SPEC_SSB_FORCE_DISABLE, spec_ssb_force_disable)
+
/*
* task->jobctl flags
*/
--- a/include/uapi/linux/prctl.h
+++ b/include/uapi/linux/prctl.h
@@ -207,5 +207,6 @@ struct prctl_mm_map {
# define PR_SPEC_PRCTL (1UL << 0)
# define PR_SPEC_ENABLE (1UL << 1)
# define PR_SPEC_DISABLE (1UL << 2)
+# define PR_SPEC_FORCE_DISABLE (1UL << 3)
#endif /* _LINUX_PRCTL_H */
^ permalink raw reply
* [PATCH 4.4 070/107] seccomp: Enable speculation flaw mitigations
From: Greg Kroah-Hartman @ 2018-07-23 12:42 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Kees Cook, Thomas Gleixner,
David Woodhouse, Srivatsa S. Bhat, Matt Helsley (VMware),
Alexey Makhalov, Bo Gan
In-Reply-To: <20180723122413.003644357@linuxfoundation.org>
4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kees Cook <keescook@chromium.org>
commit 5c3070890d06ff82eecb808d02d2ca39169533ef upstream
When speculation flaw mitigations are opt-in (via prctl), using seccomp
will automatically opt-in to these protections, since using seccomp
indicates at least some level of sandboxing is desired.
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Srivatsa S. Bhat <srivatsa@csail.mit.edu>
Reviewed-by: Matt Helsley (VMware) <matt.helsley@gmail.com>
Reviewed-by: Alexey Makhalov <amakhalov@vmware.com>
Reviewed-by: Bo Gan <ganb@vmware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/seccomp.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -16,6 +16,8 @@
#include <linux/atomic.h>
#include <linux/audit.h>
#include <linux/compat.h>
+#include <linux/nospec.h>
+#include <linux/prctl.h>
#include <linux/sched.h>
#include <linux/seccomp.h>
#include <linux/slab.h>
@@ -214,6 +216,19 @@ static inline bool seccomp_may_assign_mo
return true;
}
+/*
+ * If a given speculation mitigation is opt-in (prctl()-controlled),
+ * select it, by disabling speculation (enabling mitigation).
+ */
+static inline void spec_mitigate(struct task_struct *task,
+ unsigned long which)
+{
+ int state = arch_prctl_spec_ctrl_get(task, which);
+
+ if (state > 0 && (state & PR_SPEC_PRCTL))
+ arch_prctl_spec_ctrl_set(task, which, PR_SPEC_DISABLE);
+}
+
static inline void seccomp_assign_mode(struct task_struct *task,
unsigned long seccomp_mode)
{
@@ -225,6 +240,8 @@ static inline void seccomp_assign_mode(s
* filter) is set.
*/
smp_mb__before_atomic();
+ /* Assume seccomp processes want speculation flaw mitigation. */
+ spec_mitigate(task, PR_SPEC_STORE_BYPASS);
set_tsk_thread_flag(task, TIF_SECCOMP);
}
^ permalink raw reply
* [PATCH 4.4 068/107] nospec: Allow getting/setting on non-current task
From: Greg Kroah-Hartman @ 2018-07-23 12:42 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Kees Cook, Thomas Gleixner,
David Woodhouse, Srivatsa S. Bhat, Matt Helsley (VMware),
Alexey Makhalov, Bo Gan
In-Reply-To: <20180723122413.003644357@linuxfoundation.org>
4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kees Cook <keescook@chromium.org>
commit 7bbf1373e228840bb0295a2ca26d548ef37f448e upstream
Adjust arch_prctl_get/set_spec_ctrl() to operate on tasks other than
current.
This is needed both for /proc/$pid/status queries and for seccomp (since
thread-syncing can trigger seccomp in non-current threads).
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Srivatsa S. Bhat <srivatsa@csail.mit.edu>
Reviewed-by: Matt Helsley (VMware) <matt.helsley@gmail.com>
Reviewed-by: Alexey Makhalov <amakhalov@vmware.com>
Reviewed-by: Bo Gan <ganb@vmware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/x86/kernel/cpu/bugs.c | 27 ++++++++++++++++-----------
include/linux/nospec.h | 7 +++++--
kernel/sys.c | 9 +++++----
3 files changed, 26 insertions(+), 17 deletions(-)
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -529,31 +529,35 @@ static void ssb_select_mitigation()
#undef pr_fmt
-static int ssb_prctl_set(unsigned long ctrl)
+static int ssb_prctl_set(struct task_struct *task, unsigned long ctrl)
{
- bool rds = !!test_tsk_thread_flag(current, TIF_RDS);
+ bool rds = !!test_tsk_thread_flag(task, TIF_RDS);
if (ssb_mode != SPEC_STORE_BYPASS_PRCTL)
return -ENXIO;
if (ctrl == PR_SPEC_ENABLE)
- clear_tsk_thread_flag(current, TIF_RDS);
+ clear_tsk_thread_flag(task, TIF_RDS);
else
- set_tsk_thread_flag(current, TIF_RDS);
+ set_tsk_thread_flag(task, TIF_RDS);
- if (rds != !!test_tsk_thread_flag(current, TIF_RDS))
+ /*
+ * If being set on non-current task, delay setting the CPU
+ * mitigation until it is next scheduled.
+ */
+ if (task == current && rds != !!test_tsk_thread_flag(task, TIF_RDS))
speculative_store_bypass_update();
return 0;
}
-static int ssb_prctl_get(void)
+static int ssb_prctl_get(struct task_struct *task)
{
switch (ssb_mode) {
case SPEC_STORE_BYPASS_DISABLE:
return PR_SPEC_DISABLE;
case SPEC_STORE_BYPASS_PRCTL:
- if (test_tsk_thread_flag(current, TIF_RDS))
+ if (test_tsk_thread_flag(task, TIF_RDS))
return PR_SPEC_PRCTL | PR_SPEC_DISABLE;
return PR_SPEC_PRCTL | PR_SPEC_ENABLE;
default:
@@ -563,24 +567,25 @@ static int ssb_prctl_get(void)
}
}
-int arch_prctl_spec_ctrl_set(unsigned long which, unsigned long ctrl)
+int arch_prctl_spec_ctrl_set(struct task_struct *task, unsigned long which,
+ unsigned long ctrl)
{
if (ctrl != PR_SPEC_ENABLE && ctrl != PR_SPEC_DISABLE)
return -ERANGE;
switch (which) {
case PR_SPEC_STORE_BYPASS:
- return ssb_prctl_set(ctrl);
+ return ssb_prctl_set(task, ctrl);
default:
return -ENODEV;
}
}
-int arch_prctl_spec_ctrl_get(unsigned long which)
+int arch_prctl_spec_ctrl_get(struct task_struct *task, unsigned long which)
{
switch (which) {
case PR_SPEC_STORE_BYPASS:
- return ssb_prctl_get();
+ return ssb_prctl_get(task);
default:
return -ENODEV;
}
--- a/include/linux/nospec.h
+++ b/include/linux/nospec.h
@@ -7,6 +7,8 @@
#define _LINUX_NOSPEC_H
#include <asm/barrier.h>
+struct task_struct;
+
/**
* array_index_mask_nospec() - generate a ~0 mask when index < size, 0 otherwise
* @index: array element index
@@ -57,7 +59,8 @@ static inline unsigned long array_index_
})
/* Speculation control prctl */
-int arch_prctl_spec_ctrl_get(unsigned long which);
-int arch_prctl_spec_ctrl_set(unsigned long which, unsigned long ctrl);
+int arch_prctl_spec_ctrl_get(struct task_struct *task, unsigned long which);
+int arch_prctl_spec_ctrl_set(struct task_struct *task, unsigned long which,
+ unsigned long ctrl);
#endif /* _LINUX_NOSPEC_H */
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -2075,12 +2075,13 @@ static int prctl_get_tid_address(struct
}
#endif
-int __weak arch_prctl_spec_ctrl_get(unsigned long which)
+int __weak arch_prctl_spec_ctrl_get(struct task_struct *t, unsigned long which)
{
return -EINVAL;
}
-int __weak arch_prctl_spec_ctrl_set(unsigned long which, unsigned long ctrl)
+int __weak arch_prctl_spec_ctrl_set(struct task_struct *t, unsigned long which,
+ unsigned long ctrl)
{
return -EINVAL;
}
@@ -2282,12 +2283,12 @@ SYSCALL_DEFINE5(prctl, int, option, unsi
case PR_GET_SPECULATION_CTRL:
if (arg3 || arg4 || arg5)
return -EINVAL;
- error = arch_prctl_spec_ctrl_get(arg2);
+ error = arch_prctl_spec_ctrl_get(me, arg2);
break;
case PR_SET_SPECULATION_CTRL:
if (arg4 || arg5)
return -EINVAL;
- error = arch_prctl_spec_ctrl_set(arg2, arg3);
+ error = arch_prctl_spec_ctrl_set(me, arg2, arg3);
break;
default:
error = -EINVAL;
^ permalink raw reply
* [PATCH 4.4 067/107] x86/speculation: Add prctl for Speculative Store Bypass mitigation
From: Greg Kroah-Hartman @ 2018-07-23 12:42 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Thomas Gleixner,
Konrad Rzeszutek Wilk, David Woodhouse, Srivatsa S. Bhat,
Matt Helsley (VMware), Alexey Makhalov, Bo Gan
In-Reply-To: <20180723122413.003644357@linuxfoundation.org>
4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Gleixner <tglx@linutronix.de>
commit a73ec77ee17ec556fe7f165d00314cb7c047b1ac upstream
Add prctl based control for Speculative Store Bypass mitigation and make it
the default mitigation for Intel and AMD.
Andi Kleen provided the following rationale (slightly redacted):
There are multiple levels of impact of Speculative Store Bypass:
1) JITed sandbox.
It cannot invoke system calls, but can do PRIME+PROBE and may have call
interfaces to other code
2) Native code process.
No protection inside the process at this level.
3) Kernel.
4) Between processes.
The prctl tries to protect against case (1) doing attacks.
If the untrusted code can do random system calls then control is already
lost in a much worse way. So there needs to be system call protection in
some way (using a JIT not allowing them or seccomp). Or rather if the
process can subvert its environment somehow to do the prctl it can already
execute arbitrary code, which is much worse than SSB.
To put it differently, the point of the prctl is to not allow JITed code
to read data it shouldn't read from its JITed sandbox. If it already has
escaped its sandbox then it can already read everything it wants in its
address space, and do much worse.
The ability to control Speculative Store Bypass allows to enable the
protection selectively without affecting overall system performance.
Based on an initial patch from Tim Chen. Completely rewritten.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Srivatsa S. Bhat <srivatsa@csail.mit.edu>
Reviewed-by: Matt Helsley (VMware) <matt.helsley@gmail.com>
Reviewed-by: Alexey Makhalov <amakhalov@vmware.com>
Reviewed-by: Bo Gan <ganb@vmware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
Documentation/kernel-parameters.txt | 6 ++
arch/x86/include/asm/nospec-branch.h | 1
arch/x86/kernel/cpu/bugs.c | 83 ++++++++++++++++++++++++++++++-----
3 files changed, 79 insertions(+), 11 deletions(-)
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -3651,7 +3651,11 @@ bytes respectively. Such letter suffixes
off - Unconditionally enable Speculative Store Bypass
auto - Kernel detects whether the CPU model contains an
implementation of Speculative Store Bypass and
- picks the most appropriate mitigation
+ picks the most appropriate mitigation.
+ prctl - Control Speculative Store Bypass per thread
+ via prctl. Speculative Store Bypass is enabled
+ for a process by default. The state of the control
+ is inherited on fork.
Not specifying this option is equivalent to
spec_store_bypass_disable=auto.
--- a/arch/x86/include/asm/nospec-branch.h
+++ b/arch/x86/include/asm/nospec-branch.h
@@ -187,6 +187,7 @@ extern u64 x86_spec_ctrl_get_default(voi
enum ssb_mitigation {
SPEC_STORE_BYPASS_NONE,
SPEC_STORE_BYPASS_DISABLE,
+ SPEC_STORE_BYPASS_PRCTL,
};
extern char __indirect_thunk_start[];
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -11,6 +11,8 @@
#include <linux/utsname.h>
#include <linux/cpu.h>
#include <linux/module.h>
+#include <linux/nospec.h>
+#include <linux/prctl.h>
#include <asm/spec-ctrl.h>
#include <asm/cmdline.h>
@@ -411,20 +413,23 @@ enum ssb_mitigation_cmd {
SPEC_STORE_BYPASS_CMD_NONE,
SPEC_STORE_BYPASS_CMD_AUTO,
SPEC_STORE_BYPASS_CMD_ON,
+ SPEC_STORE_BYPASS_CMD_PRCTL,
};
static const char *ssb_strings[] = {
[SPEC_STORE_BYPASS_NONE] = "Vulnerable",
- [SPEC_STORE_BYPASS_DISABLE] = "Mitigation: Speculative Store Bypass disabled"
+ [SPEC_STORE_BYPASS_DISABLE] = "Mitigation: Speculative Store Bypass disabled",
+ [SPEC_STORE_BYPASS_PRCTL] = "Mitigation: Speculative Store Bypass disabled via prctl"
};
static const struct {
const char *option;
enum ssb_mitigation_cmd cmd;
} ssb_mitigation_options[] = {
- { "auto", SPEC_STORE_BYPASS_CMD_AUTO }, /* Platform decides */
- { "on", SPEC_STORE_BYPASS_CMD_ON }, /* Disable Speculative Store Bypass */
- { "off", SPEC_STORE_BYPASS_CMD_NONE }, /* Don't touch Speculative Store Bypass */
+ { "auto", SPEC_STORE_BYPASS_CMD_AUTO }, /* Platform decides */
+ { "on", SPEC_STORE_BYPASS_CMD_ON }, /* Disable Speculative Store Bypass */
+ { "off", SPEC_STORE_BYPASS_CMD_NONE }, /* Don't touch Speculative Store Bypass */
+ { "prctl", SPEC_STORE_BYPASS_CMD_PRCTL }, /* Disable Speculative Store Bypass via prctl */
};
static enum ssb_mitigation_cmd __init ssb_parse_cmdline(void)
@@ -474,14 +479,15 @@ static enum ssb_mitigation_cmd __init __
switch (cmd) {
case SPEC_STORE_BYPASS_CMD_AUTO:
- /*
- * AMD platforms by default don't need SSB mitigation.
- */
- if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
- break;
+ /* Choose prctl as the default mode */
+ mode = SPEC_STORE_BYPASS_PRCTL;
+ break;
case SPEC_STORE_BYPASS_CMD_ON:
mode = SPEC_STORE_BYPASS_DISABLE;
break;
+ case SPEC_STORE_BYPASS_CMD_PRCTL:
+ mode = SPEC_STORE_BYPASS_PRCTL;
+ break;
case SPEC_STORE_BYPASS_CMD_NONE:
break;
}
@@ -492,7 +498,7 @@ static enum ssb_mitigation_cmd __init __
* - X86_FEATURE_RDS - CPU is able to turn off speculative store bypass
* - X86_FEATURE_SPEC_STORE_BYPASS_DISABLE - engage the mitigation
*/
- if (mode != SPEC_STORE_BYPASS_NONE) {
+ if (mode == SPEC_STORE_BYPASS_DISABLE) {
setup_force_cpu_cap(X86_FEATURE_SPEC_STORE_BYPASS_DISABLE);
/*
* Intel uses the SPEC CTRL MSR Bit(2) for this, while AMD uses
@@ -523,6 +529,63 @@ static void ssb_select_mitigation()
#undef pr_fmt
+static int ssb_prctl_set(unsigned long ctrl)
+{
+ bool rds = !!test_tsk_thread_flag(current, TIF_RDS);
+
+ if (ssb_mode != SPEC_STORE_BYPASS_PRCTL)
+ return -ENXIO;
+
+ if (ctrl == PR_SPEC_ENABLE)
+ clear_tsk_thread_flag(current, TIF_RDS);
+ else
+ set_tsk_thread_flag(current, TIF_RDS);
+
+ if (rds != !!test_tsk_thread_flag(current, TIF_RDS))
+ speculative_store_bypass_update();
+
+ return 0;
+}
+
+static int ssb_prctl_get(void)
+{
+ switch (ssb_mode) {
+ case SPEC_STORE_BYPASS_DISABLE:
+ return PR_SPEC_DISABLE;
+ case SPEC_STORE_BYPASS_PRCTL:
+ if (test_tsk_thread_flag(current, TIF_RDS))
+ return PR_SPEC_PRCTL | PR_SPEC_DISABLE;
+ return PR_SPEC_PRCTL | PR_SPEC_ENABLE;
+ default:
+ if (boot_cpu_has_bug(X86_BUG_SPEC_STORE_BYPASS))
+ return PR_SPEC_ENABLE;
+ return PR_SPEC_NOT_AFFECTED;
+ }
+}
+
+int arch_prctl_spec_ctrl_set(unsigned long which, unsigned long ctrl)
+{
+ if (ctrl != PR_SPEC_ENABLE && ctrl != PR_SPEC_DISABLE)
+ return -ERANGE;
+
+ switch (which) {
+ case PR_SPEC_STORE_BYPASS:
+ return ssb_prctl_set(ctrl);
+ default:
+ return -ENODEV;
+ }
+}
+
+int arch_prctl_spec_ctrl_get(unsigned long which)
+{
+ switch (which) {
+ case PR_SPEC_STORE_BYPASS:
+ return ssb_prctl_get();
+ default:
+ return -ENODEV;
+ }
+}
+
void x86_spec_ctrl_setup_ap(void)
{
if (boot_cpu_has(X86_FEATURE_IBRS))
^ permalink raw reply
* Re: [PATCH/RFT 2/6] i2c: imx: use open drain for recovery GPIO
From: Lucas Stach @ 2018-07-23 12:47 UTC (permalink / raw)
To: Wolfram Sang, linux-i2c; +Cc: linux-renesas-soc, linux-kernel, kernel
In-Reply-To: <20180713210920.3648-3-wsa+renesas@sang-engineering.com>
Am Freitag, den 13.07.2018, 23:09 +0200 schrieb Wolfram Sang:
> I2C is open drain, so set up the GPIO accordingly.
>
> Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
I don't think this matters on any of the i.MX platforms, as the GPIO
pin configuration (including open-drain) is only taken from the DT
pinctrl, with the GPIO driver not being able to change any of those. On
the flipside this results in a near zero probability of regressions.
;)
As this is obviously right even if it doesn't have any effect on
current software:
Reviewed-by: Lucas Stach <l.stach@pengutronix.de>
> ---
> drivers/i2c/busses/i2c-imx.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
> index 0207e194f84b..3e23ee26c55c 100644
> --- a/drivers/i2c/busses/i2c-imx.c
> +++ b/drivers/i2c/busses/i2c-imx.c
> @@ -1010,7 +1010,7 @@ static int i2c_imx_init_recovery_info(struct imx_i2c_struct *i2c_imx,
> > i2c_imx->pinctrl_pins_gpio = pinctrl_lookup_state(i2c_imx->pinctrl,
> > "gpio");
> > rinfo->sda_gpiod = devm_gpiod_get(&pdev->dev, "sda", GPIOD_IN);
> > - rinfo->scl_gpiod = devm_gpiod_get(&pdev->dev, "scl", GPIOD_OUT_HIGH);
> > + rinfo->scl_gpiod = devm_gpiod_get(&pdev->dev, "scl", GPIOD_OUT_HIGH_OPEN_DRAIN);
>
> > if (PTR_ERR(rinfo->sda_gpiod) == -EPROBE_DEFER ||
> > PTR_ERR(rinfo->scl_gpiod) == -EPROBE_DEFER) {
^ permalink raw reply
* [PATCH 4.4 103/107] ubi: Rework Fastmap attach base code
From: Greg Kroah-Hartman @ 2018-07-23 12:42 UTC (permalink / raw)
To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Richard Weinberger
In-Reply-To: <20180723122413.003644357@linuxfoundation.org>
4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Richard Weinberger <richard@nod.at>
commit fdf10ed710c0aa177e8dfcd84e65e4e5e8e0956b upstream.
Introduce a new list to the UBI attach information
object to be able to deal better with old and corrupted
Fastmap eraseblocks.
Also move more Fastmap specific code into fastmap.c.
Signed-off-by: Richard Weinberger <richard@nod.at>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mtd/ubi/attach.c | 99 ++++++++++++++++++++++++++++++++--------------
drivers/mtd/ubi/fastmap.c | 36 +++++++++++++++-
drivers/mtd/ubi/ubi.h | 28 ++++++++++++-
drivers/mtd/ubi/wl.c | 41 +++++++++++++++----
4 files changed, 162 insertions(+), 42 deletions(-)
--- a/drivers/mtd/ubi/attach.c
+++ b/drivers/mtd/ubi/attach.c
@@ -175,6 +175,40 @@ static int add_corrupted(struct ubi_atta
}
/**
+ * add_fastmap - add a Fastmap related physical eraseblock.
+ * @ai: attaching information
+ * @pnum: physical eraseblock number the VID header came from
+ * @vid_hdr: the volume identifier header
+ * @ec: erase counter of the physical eraseblock
+ *
+ * This function allocates a 'struct ubi_ainf_peb' object for a Fastamp
+ * physical eraseblock @pnum and adds it to the 'fastmap' list.
+ * Such blocks can be Fastmap super and data blocks from both the most
+ * recent Fastmap we're attaching from or from old Fastmaps which will
+ * be erased.
+ */
+static int add_fastmap(struct ubi_attach_info *ai, int pnum,
+ struct ubi_vid_hdr *vid_hdr, int ec)
+{
+ struct ubi_ainf_peb *aeb;
+
+ aeb = kmem_cache_alloc(ai->aeb_slab_cache, GFP_KERNEL);
+ if (!aeb)
+ return -ENOMEM;
+
+ aeb->pnum = pnum;
+ aeb->vol_id = be32_to_cpu(vidh->vol_id);
+ aeb->sqnum = be64_to_cpu(vidh->sqnum);
+ aeb->ec = ec;
+ list_add(&aeb->u.list, &ai->fastmap);
+
+ dbg_bld("add to fastmap list: PEB %d, vol_id %d, sqnum: %llu", pnum,
+ aeb->vol_id, aeb->sqnum);
+
+ return 0;
+}
+
+/**
* validate_vid_hdr - check volume identifier header.
* @ubi: UBI device description object
* @vid_hdr: the volume identifier header to check
@@ -822,18 +856,15 @@ static bool vol_ignored(int vol_id)
* @ubi: UBI device description object
* @ai: attaching information
* @pnum: the physical eraseblock number
- * @vid: The volume ID of the found volume will be stored in this pointer
- * @sqnum: The sqnum of the found volume will be stored in this pointer
*
* This function reads UBI headers of PEB @pnum, checks them, and adds
* information about this PEB to the corresponding list or RB-tree in the
* "attaching info" structure. Returns zero if the physical eraseblock was
* successfully handled and a negative error code in case of failure.
*/
-static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai,
- int pnum, int *vid, unsigned long long *sqnum)
+static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum)
{
- long long uninitialized_var(ec);
+ long long ec;
int err, bitflips = 0, vol_id = -1, ec_err = 0;
dbg_bld("scan PEB %d", pnum);
@@ -1005,10 +1036,6 @@ static int scan_peb(struct ubi_device *u
}
vol_id = be32_to_cpu(vidh->vol_id);
- if (vid)
- *vid = vol_id;
- if (sqnum)
- *sqnum = be64_to_cpu(vidh->sqnum);
if (vol_id > UBI_MAX_VOLUMES && !vol_ignored(vol_id)) {
int lnum = be32_to_cpu(vidh->lnum);
@@ -1049,7 +1076,12 @@ static int scan_peb(struct ubi_device *u
if (ec_err)
ubi_warn(ubi, "valid VID header but corrupted EC header at PEB %d",
pnum);
- err = ubi_add_to_av(ubi, ai, pnum, ec, vidh, bitflips);
+
+ if (ubi_is_fm_vol(vol_id))
+ err = add_fastmap(ai, pnum, vidh, ec);
+ else
+ err = ubi_add_to_av(ubi, ai, pnum, ec, vidh, bitflips);
+
if (err)
return err;
@@ -1198,6 +1230,10 @@ static void destroy_ai(struct ubi_attach
list_del(&aeb->u.list);
kmem_cache_free(ai->aeb_slab_cache, aeb);
}
+ list_for_each_entry_safe(aeb, aeb_tmp, &ai->fastmap, u.list) {
+ list_del(&aeb->u.list);
+ kmem_cache_free(ai->aeb_slab_cache, aeb);
+ }
/* Destroy the volume RB-tree */
rb = ai->volumes.rb_node;
@@ -1257,7 +1293,7 @@ static int scan_all(struct ubi_device *u
cond_resched();
dbg_gen("process PEB %d", pnum);
- err = scan_peb(ubi, ai, pnum, NULL, NULL);
+ err = scan_peb(ubi, ai, pnum);
if (err < 0)
goto out_vidh;
}
@@ -1323,6 +1359,7 @@ static struct ubi_attach_info *alloc_ai(
INIT_LIST_HEAD(&ai->free);
INIT_LIST_HEAD(&ai->erase);
INIT_LIST_HEAD(&ai->alien);
+ INIT_LIST_HEAD(&ai->fastmap);
ai->volumes = RB_ROOT;
ai->aeb_slab_cache = kmem_cache_create("ubi_aeb_slab_cache",
sizeof(struct ubi_ainf_peb),
@@ -1349,52 +1386,54 @@ static struct ubi_attach_info *alloc_ai(
*/
static int scan_fast(struct ubi_device *ubi, struct ubi_attach_info **ai)
{
- int err, pnum, fm_anchor = -1;
- unsigned long long max_sqnum = 0;
+ int err, pnum;
+ struct ubi_attach_info *scan_ai;
err = -ENOMEM;
+ scan_ai = alloc_ai();
+ if (!scan_ai)
+ goto out;
+
ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL);
if (!ech)
- goto out;
+ goto out_ai;
vidh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL);
if (!vidh)
goto out_ech;
for (pnum = 0; pnum < UBI_FM_MAX_START; pnum++) {
- int vol_id = -1;
- unsigned long long sqnum = -1;
cond_resched();
dbg_gen("process PEB %d", pnum);
- err = scan_peb(ubi, *ai, pnum, &vol_id, &sqnum);
+ err = scan_peb(ubi, scan_ai, pnum);
if (err < 0)
goto out_vidh;
-
- if (vol_id == UBI_FM_SB_VOLUME_ID && sqnum > max_sqnum) {
- max_sqnum = sqnum;
- fm_anchor = pnum;
- }
}
ubi_free_vid_hdr(ubi, vidh);
kfree(ech);
- if (fm_anchor < 0)
- return UBI_NO_FASTMAP;
-
- destroy_ai(*ai);
- *ai = alloc_ai();
- if (!*ai)
- return -ENOMEM;
+ err = ubi_scan_fastmap(ubi, *ai, scan_ai);
+ if (err) {
+ /*
+ * Didn't attach via fastmap, do a full scan but reuse what
+ * we've aready scanned.
+ */
+ destroy_ai(*ai);
+ *ai = scan_ai;
+ } else
+ destroy_ai(scan_ai);
- return ubi_scan_fastmap(ubi, *ai, fm_anchor);
+ return err;
out_vidh:
ubi_free_vid_hdr(ubi, vidh);
out_ech:
kfree(ech);
+out_ai:
+ destroy_ai(scan_ai);
out:
return err;
}
--- a/drivers/mtd/ubi/fastmap.c
+++ b/drivers/mtd/ubi/fastmap.c
@@ -851,27 +851,57 @@ fail:
}
/**
+ * find_fm_anchor - find the most recent Fastmap superblock (anchor)
+ * @ai: UBI attach info to be filled
+ */
+static int find_fm_anchor(struct ubi_attach_info *ai)
+{
+ int ret = -1;
+ struct ubi_ainf_peb *aeb;
+ unsigned long long max_sqnum = 0;
+
+ list_for_each_entry(aeb, &ai->fastmap, u.list) {
+ if (aeb->vol_id == UBI_FM_SB_VOLUME_ID && aeb->sqnum > max_sqnum) {
+ max_sqnum = aeb->sqnum;
+ ret = aeb->pnum;
+ }
+ }
+
+ return ret;
+}
+
+/**
* ubi_scan_fastmap - scan the fastmap.
* @ubi: UBI device object
* @ai: UBI attach info to be filled
- * @fm_anchor: The fastmap starts at this PEB
+ * @scan_ai: UBI attach info from the first 64 PEBs,
+ * used to find the most recent Fastmap data structure
*
* Returns 0 on success, UBI_NO_FASTMAP if no fastmap was found,
* UBI_BAD_FASTMAP if one was found but is not usable.
* < 0 indicates an internal error.
*/
int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai,
- int fm_anchor)
+ struct ubi_attach_info *scan_ai)
{
struct ubi_fm_sb *fmsb, *fmsb2;
struct ubi_vid_hdr *vh;
struct ubi_ec_hdr *ech;
struct ubi_fastmap_layout *fm;
- int i, used_blocks, pnum, ret = 0;
+ struct ubi_ainf_peb *tmp_aeb, *aeb;
+ int i, used_blocks, pnum, fm_anchor, ret = 0;
size_t fm_size;
__be32 crc, tmp_crc;
unsigned long long sqnum = 0;
+ fm_anchor = find_fm_anchor(scan_ai);
+ if (fm_anchor < 0)
+ return UBI_NO_FASTMAP;
+
+ /* Move all (possible) fastmap blocks into our new attach structure. */
+ list_for_each_entry_safe(aeb, tmp_aeb, &scan_ai->fastmap, u.list)
+ list_move_tail(&aeb->u.list, &ai->fastmap);
+
down_write(&ubi->fm_protect);
memset(ubi->fm_buf, 0, ubi->fm_size);
--- a/drivers/mtd/ubi/ubi.h
+++ b/drivers/mtd/ubi/ubi.h
@@ -699,6 +699,8 @@ struct ubi_ainf_volume {
* @erase: list of physical eraseblocks which have to be erased
* @alien: list of physical eraseblocks which should not be used by UBI (e.g.,
* those belonging to "preserve"-compatible internal volumes)
+ * @fastmap: list of physical eraseblocks which relate to fastmap (e.g.,
+ * eraseblocks of the current and not yet erased old fastmap blocks)
* @corr_peb_count: count of PEBs in the @corr list
* @empty_peb_count: count of PEBs which are presumably empty (contain only
* 0xFF bytes)
@@ -727,6 +729,7 @@ struct ubi_attach_info {
struct list_head free;
struct list_head erase;
struct list_head alien;
+ struct list_head fastmap;
int corr_peb_count;
int empty_peb_count;
int alien_peb_count;
@@ -907,7 +910,7 @@ int ubi_compare_lebs(struct ubi_device *
size_t ubi_calc_fm_size(struct ubi_device *ubi);
int ubi_update_fastmap(struct ubi_device *ubi);
int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai,
- int fm_anchor);
+ struct ubi_attach_info *scan_ai);
#else
static inline int ubi_update_fastmap(struct ubi_device *ubi) { return 0; }
#endif
@@ -1116,4 +1119,27 @@ static inline bool ubi_is_fm_vol(int vol
return false;
}
+/**
+ * ubi_find_fm_block - check whether a PEB is part of the current Fastmap.
+ * @ubi: UBI device description object
+ * @pnum: physical eraseblock to look for
+ *
+ * This function returns a wear leveling object if @pnum relates to the current
+ * fastmap, @NULL otherwise.
+ */
+static inline struct ubi_wl_entry *ubi_find_fm_block(const struct ubi_device *ubi,
+ int pnum)
+{
+ int i;
+
+ if (ubi->fm) {
+ for (i = 0; i < ubi->fm->used_blocks; i++) {
+ if (ubi->fm->e[i]->pnum == pnum)
+ return ubi->fm->e[i];
+ }
+ }
+
+ return NULL;
+}
+
#endif /* !__UBI_UBI_H__ */
--- a/drivers/mtd/ubi/wl.c
+++ b/drivers/mtd/ubi/wl.c
@@ -1598,19 +1598,44 @@ int ubi_wl_init(struct ubi_device *ubi,
}
}
- dbg_wl("found %i PEBs", found_pebs);
+ list_for_each_entry(aeb, &ai->fastmap, u.list) {
+ cond_resched();
+
+ e = ubi_find_fm_block(ubi, aeb->pnum);
+
+ if (e) {
+ ubi_assert(!ubi->lookuptbl[e->pnum]);
+ ubi->lookuptbl[e->pnum] = e;
+ } else {
+ /*
+ * Usually old Fastmap PEBs are scheduled for erasure
+ * and we don't have to care about them but if we face
+ * an power cut before scheduling them we need to
+ * take care of them here.
+ */
+ if (ubi->lookuptbl[aeb->pnum])
+ continue;
- if (ubi->fm) {
- ubi_assert(ubi->good_peb_count ==
- found_pebs + ubi->fm->used_blocks);
+ e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL);
+ if (!e)
+ goto out_free;
- for (i = 0; i < ubi->fm->used_blocks; i++) {
- e = ubi->fm->e[i];
+ e->pnum = aeb->pnum;
+ e->ec = aeb->ec;
+ ubi_assert(!ubi->lookuptbl[e->pnum]);
ubi->lookuptbl[e->pnum] = e;
+ if (schedule_erase(ubi, e, aeb->vol_id, aeb->lnum, 0)) {
+ wl_entry_destroy(ubi, e);
+ goto out_free;
+ }
}
+
+ found_pebs++;
}
- else
- ubi_assert(ubi->good_peb_count == found_pebs);
+
+ dbg_wl("found %i PEBs", found_pebs);
+
+ ubi_assert(ubi->good_peb_count == found_pebs);
reserved_pebs = WL_RESERVED_PEBS;
ubi_fastmap_init(ubi, &reserved_pebs);
^ permalink raw reply
* [PATCH net-next] selftests: forwarding: gre_multipath: Drop IPv6 tests
From: David Ahern @ 2018-07-23 12:47 UTC (permalink / raw)
In-Reply-To: <cf0e380baf6a6aa5cf384017e8d69fec79750cfe.1532341813.git.petrm@mellanox.com>
On 7/23/18 4:33 AM, Petr Machata wrote:
> Support for device-only IPv6 multipath next hops was dropped in
> commit 33bd5ac54dc4 ("net/ipv6: Revert attempt to simplify route replace
> and append") and as of commit b5d2d75e079a ("net/ipv6: Do not allow
> device only routes via the multipath API"), attempts to add a next hop
> like that yield an explicit diagnostic.
>
> Correspondingly, drop the IPv6 parts of GRE multipath test that are
> supposed to test that code.
>
> Signed-off-by: Petr Machata <petrm at mellanox.com>
> ---
> .../selftests/net/forwarding/gre_multipath.sh | 113 ++-------------------
> 1 file changed, 6 insertions(+), 107 deletions(-)
Reviewed-by: David Ahern <dsahern at gmail.com>
Thanks for following up.
--
To unsubscribe from this list: send the line "unsubscribe linux-kselftest" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH net-next] selftests: forwarding: gre_multipath: Drop IPv6 tests
From: dsahern @ 2018-07-23 12:47 UTC (permalink / raw)
In-Reply-To: <cf0e380baf6a6aa5cf384017e8d69fec79750cfe.1532341813.git.petrm@mellanox.com>
On 7/23/18 4:33 AM, Petr Machata wrote:
> Support for device-only IPv6 multipath next hops was dropped in
> commit 33bd5ac54dc4 ("net/ipv6: Revert attempt to simplify route replace
> and append") and as of commit b5d2d75e079a ("net/ipv6: Do not allow
> device only routes via the multipath API"), attempts to add a next hop
> like that yield an explicit diagnostic.
>
> Correspondingly, drop the IPv6 parts of GRE multipath test that are
> supposed to test that code.
>
> Signed-off-by: Petr Machata <petrm at mellanox.com>
> ---
> .../selftests/net/forwarding/gre_multipath.sh | 113 ++-------------------
> 1 file changed, 6 insertions(+), 107 deletions(-)
Reviewed-by: David Ahern <dsahern at gmail.com>
Thanks for following up.
--
To unsubscribe from this list: send the line "unsubscribe linux-kselftest" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH 4.4 102/107] ubi: Introduce vol_ignored()
From: Greg Kroah-Hartman @ 2018-07-23 12:42 UTC (permalink / raw)
To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Richard Weinberger
In-Reply-To: <20180723122413.003644357@linuxfoundation.org>
4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Richard Weinberger <richard@nod.at>
commit 243a4f8126fcf7facb04b324dbb7c85d10b11ce9 upstream.
This makes the logic more easy to follow.
Signed-off-by: Richard Weinberger <richard@nod.at>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mtd/ubi/attach.c | 24 ++++++++++++++++++------
drivers/mtd/ubi/ubi.h | 15 +++++++++++++++
2 files changed, 33 insertions(+), 6 deletions(-)
--- a/drivers/mtd/ubi/attach.c
+++ b/drivers/mtd/ubi/attach.c
@@ -803,6 +803,20 @@ out_unlock:
return err;
}
+static bool vol_ignored(int vol_id)
+{
+ switch (vol_id) {
+ case UBI_LAYOUT_VOLUME_ID:
+ return true;
+ }
+
+#ifdef CONFIG_MTD_UBI_FASTMAP
+ return ubi_is_fm_vol(vol_id);
+#else
+ return false;
+#endif
+}
+
/**
* scan_peb - scan and process UBI headers of a PEB.
* @ubi: UBI device description object
@@ -995,17 +1009,15 @@ static int scan_peb(struct ubi_device *u
*vid = vol_id;
if (sqnum)
*sqnum = be64_to_cpu(vidh->sqnum);
- if (vol_id > UBI_MAX_VOLUMES && vol_id != UBI_LAYOUT_VOLUME_ID) {
+ if (vol_id > UBI_MAX_VOLUMES && !vol_ignored(vol_id)) {
int lnum = be32_to_cpu(vidh->lnum);
/* Unsupported internal volume */
switch (vidh->compat) {
case UBI_COMPAT_DELETE:
- if (vol_id != UBI_FM_SB_VOLUME_ID
- && vol_id != UBI_FM_DATA_VOLUME_ID) {
- ubi_msg(ubi, "\"delete\" compatible internal volume %d:%d found, will remove it",
- vol_id, lnum);
- }
+ ubi_msg(ubi, "\"delete\" compatible internal volume %d:%d found, will remove it",
+ vol_id, lnum);
+
err = add_to_list(ai, pnum, vol_id, lnum,
ec, 1, &ai->erase);
if (err)
--- a/drivers/mtd/ubi/ubi.h
+++ b/drivers/mtd/ubi/ubi.h
@@ -1101,4 +1101,19 @@ static inline int idx2vol_id(const struc
return idx;
}
+/**
+ * ubi_is_fm_vol - check whether a volume ID is a Fastmap volume.
+ * @vol_id: volume ID
+ */
+static inline bool ubi_is_fm_vol(int vol_id)
+{
+ switch (vol_id) {
+ case UBI_FM_SB_VOLUME_ID:
+ case UBI_FM_DATA_VOLUME_ID:
+ return true;
+ }
+
+ return false;
+}
+
#endif /* !__UBI_UBI_H__ */
^ permalink raw reply
* [PATCH 4.4 066/107] x86/process: Allow runtime control of Speculative Store Bypass
From: Greg Kroah-Hartman @ 2018-07-23 12:42 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Thomas Gleixner, Ingo Molnar,
Konrad Rzeszutek Wilk, David Woodhouse, Srivatsa S. Bhat,
Matt Helsley (VMware), Alexey Makhalov, Bo Gan
In-Reply-To: <20180723122413.003644357@linuxfoundation.org>
4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Gleixner <tglx@linutronix.de>
commit 885f82bfbc6fefb6664ea27965c3ab9ac4194b8c upstream
The Speculative Store Bypass vulnerability can be mitigated with the
Reduced Data Speculation (RDS) feature. To allow finer grained control of
this eventually expensive mitigation a per task mitigation control is
required.
Add a new TIF_RDS flag and put it into the group of TIF flags which are
evaluated for mismatch in switch_to(). If these bits differ in the previous
and the next task, then the slow path function __switch_to_xtra() is
invoked. Implement the TIF_RDS dependent mitigation control in the slow
path.
If the prctl for controlling Speculative Store Bypass is disabled or no
task uses the prctl then there is no overhead in the switch_to() fast
path.
Update the KVM related speculation control functions to take TID_RDS into
account as well.
Based on a patch from Tim Chen. Completely rewritten.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Srivatsa S. Bhat <srivatsa@csail.mit.edu>
Reviewed-by: Matt Helsley (VMware) <matt.helsley@gmail.com>
Reviewed-by: Alexey Makhalov <amakhalov@vmware.com>
Reviewed-by: Bo Gan <ganb@vmware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/x86/include/asm/msr-index.h | 3 ++-
arch/x86/include/asm/spec-ctrl.h | 17 +++++++++++++++++
arch/x86/include/asm/thread_info.h | 6 ++++--
arch/x86/kernel/cpu/bugs.c | 26 +++++++++++++++++++++-----
arch/x86/kernel/process.c | 22 ++++++++++++++++++++++
5 files changed, 66 insertions(+), 8 deletions(-)
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -35,7 +35,8 @@
#define MSR_IA32_SPEC_CTRL 0x00000048 /* Speculation Control */
#define SPEC_CTRL_IBRS (1 << 0) /* Indirect Branch Restricted Speculation */
#define SPEC_CTRL_STIBP (1 << 1) /* Single Thread Indirect Branch Predictors */
-#define SPEC_CTRL_RDS (1 << 2) /* Reduced Data Speculation */
+#define SPEC_CTRL_RDS_SHIFT 2 /* Reduced Data Speculation bit */
+#define SPEC_CTRL_RDS (1 << SPEC_CTRL_RDS_SHIFT) /* Reduced Data Speculation */
#define MSR_IA32_PRED_CMD 0x00000049 /* Prediction Command */
#define PRED_CMD_IBPB (1 << 0) /* Indirect Branch Prediction Barrier */
--- a/arch/x86/include/asm/spec-ctrl.h
+++ b/arch/x86/include/asm/spec-ctrl.h
@@ -2,6 +2,7 @@
#ifndef _ASM_X86_SPECCTRL_H_
#define _ASM_X86_SPECCTRL_H_
+#include <linux/thread_info.h>
#include <asm/nospec-branch.h>
/*
@@ -18,4 +19,20 @@ extern void x86_spec_ctrl_restore_host(u
extern u64 x86_amd_ls_cfg_base;
extern u64 x86_amd_ls_cfg_rds_mask;
+/* The Intel SPEC CTRL MSR base value cache */
+extern u64 x86_spec_ctrl_base;
+
+static inline u64 rds_tif_to_spec_ctrl(u64 tifn)
+{
+ BUILD_BUG_ON(TIF_RDS < SPEC_CTRL_RDS_SHIFT);
+ return (tifn & _TIF_RDS) >> (TIF_RDS - SPEC_CTRL_RDS_SHIFT);
+}
+
+static inline u64 rds_tif_to_amd_ls_cfg(u64 tifn)
+{
+ return (tifn & _TIF_RDS) ? x86_amd_ls_cfg_rds_mask : 0ULL;
+}
+
+extern void speculative_store_bypass_update(void);
+
#endif
--- a/arch/x86/include/asm/thread_info.h
+++ b/arch/x86/include/asm/thread_info.h
@@ -92,6 +92,7 @@ struct thread_info {
#define TIF_SIGPENDING 2 /* signal pending */
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
#define TIF_SINGLESTEP 4 /* reenable singlestep on user return*/
+#define TIF_RDS 5 /* Reduced data speculation */
#define TIF_SYSCALL_EMU 6 /* syscall emulation active */
#define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */
#define TIF_SECCOMP 8 /* secure computing */
@@ -114,8 +115,9 @@ struct thread_info {
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
-#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
+#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
+#define _TIF_RDS (1 << TIF_RDS)
#define _TIF_SYSCALL_EMU (1 << TIF_SYSCALL_EMU)
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
#define _TIF_SECCOMP (1 << TIF_SECCOMP)
@@ -147,7 +149,7 @@ struct thread_info {
/* flags to check in __switch_to() */
#define _TIF_WORK_CTXSW \
- (_TIF_IO_BITMAP|_TIF_NOTSC|_TIF_BLOCKSTEP)
+ (_TIF_IO_BITMAP|_TIF_NOTSC|_TIF_BLOCKSTEP|_TIF_RDS)
#define _TIF_WORK_CTXSW_PREV (_TIF_WORK_CTXSW|_TIF_USER_RETURN_NOTIFY)
#define _TIF_WORK_CTXSW_NEXT (_TIF_WORK_CTXSW)
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -32,7 +32,7 @@ static void __init ssb_select_mitigation
* Our boot-time value of the SPEC_CTRL MSR. We read it once so that any
* writes to SPEC_CTRL contain whatever reserved bits have been set.
*/
-static u64 x86_spec_ctrl_base;
+u64 x86_spec_ctrl_base;
/*
* The vendor and possibly platform specific bits which can be modified in
@@ -139,25 +139,41 @@ EXPORT_SYMBOL_GPL(x86_spec_ctrl_set);
u64 x86_spec_ctrl_get_default(void)
{
- return x86_spec_ctrl_base;
+ u64 msrval = x86_spec_ctrl_base;
+
+ if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)
+ msrval |= rds_tif_to_spec_ctrl(current_thread_info()->flags);
+ return msrval;
}
EXPORT_SYMBOL_GPL(x86_spec_ctrl_get_default);
void x86_spec_ctrl_set_guest(u64 guest_spec_ctrl)
{
+ u64 host = x86_spec_ctrl_base;
+
if (!boot_cpu_has(X86_FEATURE_IBRS))
return;
- if (x86_spec_ctrl_base != guest_spec_ctrl)
+
+ if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)
+ host |= rds_tif_to_spec_ctrl(current_thread_info()->flags);
+
+ if (host != guest_spec_ctrl)
wrmsrl(MSR_IA32_SPEC_CTRL, guest_spec_ctrl);
}
EXPORT_SYMBOL_GPL(x86_spec_ctrl_set_guest);
void x86_spec_ctrl_restore_host(u64 guest_spec_ctrl)
{
+ u64 host = x86_spec_ctrl_base;
+
if (!boot_cpu_has(X86_FEATURE_IBRS))
return;
- if (x86_spec_ctrl_base != guest_spec_ctrl)
- wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base);
+
+ if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)
+ host |= rds_tif_to_spec_ctrl(current_thread_info()->flags);
+
+ if (host != guest_spec_ctrl)
+ wrmsrl(MSR_IA32_SPEC_CTRL, host);
}
EXPORT_SYMBOL_GPL(x86_spec_ctrl_restore_host);
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -31,6 +31,7 @@
#include <asm/tlbflush.h>
#include <asm/mce.h>
#include <asm/vm86.h>
+#include <asm/spec-ctrl.h>
/*
* per-CPU TSS segments. Threads are completely 'soft' on Linux,
@@ -198,6 +199,24 @@ static inline void switch_to_bitmap(stru
}
}
+static __always_inline void __speculative_store_bypass_update(unsigned long tifn)
+{
+ u64 msr;
+
+ if (static_cpu_has(X86_FEATURE_AMD_RDS)) {
+ msr = x86_amd_ls_cfg_base | rds_tif_to_amd_ls_cfg(tifn);
+ wrmsrl(MSR_AMD64_LS_CFG, msr);
+ } else {
+ msr = x86_spec_ctrl_base | rds_tif_to_spec_ctrl(tifn);
+ wrmsrl(MSR_IA32_SPEC_CTRL, msr);
+ }
+}
+
+void speculative_store_bypass_update(void)
+{
+ __speculative_store_bypass_update(current_thread_info()->flags);
+}
+
void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
struct tss_struct *tss)
{
@@ -226,6 +245,9 @@ void __switch_to_xtra(struct task_struct
if ((tifp ^ tifn) & _TIF_NOTSC)
cr4_toggle_bits(X86_CR4_TSD);
+
+ if ((tifp ^ tifn) & _TIF_RDS)
+ __speculative_store_bypass_update(tifn);
}
/*
^ permalink raw reply
* [PATCH 4.4 101/107] clk: tegra: Fix PLL_U post divider and initial rate on Tegra30
From: Greg Kroah-Hartman @ 2018-07-23 12:42 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Lucas Stach, Thierry Reding,
Jon Hunter
In-Reply-To: <20180723122413.003644357@linuxfoundation.org>
4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lucas Stach <dev@lynxeye.de>
commit 797097301860c64b63346d068ba4fe4992bd5021 upstream.
The post divider value in the frequency table is wrong as it would lead
to the PLL producing an output rate of 960 MHz instead of the desired
480 MHz. This wasn't a problem as nothing used the table to actually
initialize the PLL rate, but the bootloader configuration was used
unaltered.
If the bootloader does not set up the PLL it will fail to come when used
under Linux. To fix this don't rely on the bootloader, but set the
correct rate in the clock driver.
Signed-off-by: Lucas Stach <dev@lynxeye.de>
Signed-off-by: Thierry Reding <treding@nvidia.com>
[jonathanh@nvidia.com: Back-ported to stable v4.4.y]
Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/clk/tegra/clk-tegra30.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
--- a/drivers/clk/tegra/clk-tegra30.c
+++ b/drivers/clk/tegra/clk-tegra30.c
@@ -333,11 +333,11 @@ static struct pdiv_map pllu_p[] = {
};
static struct tegra_clk_pll_freq_table pll_u_freq_table[] = {
- { 12000000, 480000000, 960, 12, 0, 12},
- { 13000000, 480000000, 960, 13, 0, 12},
- { 16800000, 480000000, 400, 7, 0, 5},
- { 19200000, 480000000, 200, 4, 0, 3},
- { 26000000, 480000000, 960, 26, 0, 12},
+ { 12000000, 480000000, 960, 12, 2, 12 },
+ { 13000000, 480000000, 960, 13, 2, 12 },
+ { 16800000, 480000000, 400, 7, 2, 5 },
+ { 19200000, 480000000, 200, 4, 2, 3 },
+ { 26000000, 480000000, 960, 26, 2, 12 },
{ 0, 0, 0, 0, 0, 0 },
};
@@ -1372,6 +1372,7 @@ static struct tegra_clk_init_table init_
{TEGRA30_CLK_GR2D, TEGRA30_CLK_PLL_C, 300000000, 0},
{TEGRA30_CLK_GR3D, TEGRA30_CLK_PLL_C, 300000000, 0},
{TEGRA30_CLK_GR3D2, TEGRA30_CLK_PLL_C, 300000000, 0},
+ { TEGRA30_CLK_PLL_U, TEGRA30_CLK_CLK_MAX, 480000000, 0 },
{TEGRA30_CLK_CLK_MAX, TEGRA30_CLK_CLK_MAX, 0, 0}, /* This MUST be the last entry. */
};
^ permalink raw reply
* [PATCH 4.4 100/107] block: do not use interruptible wait anywhere
From: Greg Kroah-Hartman @ 2018-07-23 12:42 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Bart Van Assche, Alan Jenkins,
Jens Axboe, Sudip Mukherjee
In-Reply-To: <20180723122413.003644357@linuxfoundation.org>
4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alan Jenkins <alan.christopher.jenkins@gmail.com>
commit 1dc3039bc87ae7d19a990c3ee71cfd8a9068f428 upstream.
When blk_queue_enter() waits for a queue to unfreeze, or unset the
PREEMPT_ONLY flag, do not allow it to be interrupted by a signal.
The PREEMPT_ONLY flag was introduced later in commit 3a0a529971ec
("block, scsi: Make SCSI quiesce and resume work reliably"). Note the SCSI
device is resumed asynchronously, i.e. after un-freezing userspace tasks.
So that commit exposed the bug as a regression in v4.15. A mysterious
SIGBUS (or -EIO) sometimes happened during the time the device was being
resumed. Most frequently, there was no kernel log message, and we saw Xorg
or Xwayland killed by SIGBUS.[1]
[1] E.g. https://bugzilla.redhat.com/show_bug.cgi?id=1553979
Without this fix, I get an IO error in this test:
# dd if=/dev/sda of=/dev/null iflag=direct & \
while killall -SIGUSR1 dd; do sleep 0.1; done & \
echo mem > /sys/power/state ; \
sleep 5; killall dd # stop after 5 seconds
The interruptible wait was added to blk_queue_enter in
commit 3ef28e83ab15 ("block: generic request_queue reference counting").
Before then, the interruptible wait was only in blk-mq, but I don't think
it could ever have been correct.
Reviewed-by: Bart Van Assche <bart.vanassche@wdc.com>
Cc: stable@vger.kernel.org
Signed-off-by: Alan Jenkins <alan.christopher.jenkins@gmail.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
block/blk-core.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -651,21 +651,17 @@ EXPORT_SYMBOL(blk_alloc_queue);
int blk_queue_enter(struct request_queue *q, gfp_t gfp)
{
while (true) {
- int ret;
-
if (percpu_ref_tryget_live(&q->q_usage_counter))
return 0;
if (!gfpflags_allow_blocking(gfp))
return -EBUSY;
- ret = wait_event_interruptible(q->mq_freeze_wq,
- !atomic_read(&q->mq_freeze_depth) ||
- blk_queue_dying(q));
+ wait_event(q->mq_freeze_wq,
+ !atomic_read(&q->mq_freeze_depth) ||
+ blk_queue_dying(q));
if (blk_queue_dying(q))
return -ENODEV;
- if (ret)
- return ret;
}
}
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.