KEYS: put keyring if install_session_keyring_to_cred() fails
Subsystems (2)
Sasha Levin
maintainerPATCH 1/65 KEYS: put keyring if install_session_keyring_to_cred() fails
From: Eric Biggers <[email protected]>
[ Upstream commit d636bd9f12a66ea3775c9fabbf3f8e118253467a ]
In join_session_keyring(), if install_session_keyring_to_cred() were to fail, we would leak the keyring reference, just like in the bug fixed by commit 23567fd052a9 ("KEYS: Fix keyring ref leak in join_session_keyring()"). Fortunately this cannot happen currently, but we really should be more careful. Do this by adding and using a new error label at which the keyring reference is dropped.
--- security/keys/process_keys.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
security/keys/process_keys.c +4 -3
@@ -808,15 +808,14 @@ long join_session_keyring(const char *name) ret =PTR_ERR (keyring); goto error2; }else if (keyring == new->session_keyring) { -key_put (keyring); ret =0 ; - goto error2; + goto error3; }/* we've got a keyring - now to install it */ ret =install_session_keyring_to_cred (new, keyring);if (ret <0 ) - goto error2; + goto error3;commit_creds (new);mutex_unlock (&key_session_mutex);
@@ -826,6 +825,8 @@ long join_session_keyring(const char *name) okay:return ret; +error3: +key_put (keyring); error2:mutex_unlock (&key_session_mutex); error:
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 2/65 ipv6: suppress sparse warnings in IP6_ECN_set_ce()
From: Johannes Berg <[email protected]>
[ Upstream commit c15c0ab12fd62f2b19181d05c62d24bc9fa55a42 ]
Pass the correct type __wsum to csum_sub() and csum_add(). This doesn't really change anything since __wsum really *is* __be32, but removes the address space warnings from sparse.
--- include/net/inet_ecn.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
include/net/inet_ecn.h +2 -1
@@ -128,7 +128,8 @@ static inline int IP6_ECN_set_ce(struct sk_buff *skb, struct ipv6hdr *iph) to = from |htonl (INET_ECN_CE <<20 ); *(__be32 *)iph = to;if (skb->ip_summed ==CHECKSUM_COMPLETE ) - skb->csum =csum_add (csum_sub (skb->csum, from), to); + skb->csum =csum_add (csum_sub (skb->csum, (__force __wsum )from), + (__force __wsum )to);return 1 ; }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 3/65 net: drop write-only stack variable
In reply to Sasha LevinFrom: David Herrmann <[email protected]>
[ Upstream commit 3575dbf2cbbc8e598f17ec441aed526dbea0e1bd ]
Remove a write-only stack variable from unix_attach_fds(). This is a left-over from the security fix in:
commit 712f4aad406bb1ed67f3f98d04c044191f0ff593
Author: willy tarreau <[email protected]>
Date: Sun Jan 10 07:54:56 2016 +0100
unix: properly account for FDs passed over unix sockets
--- net/unix/af_unix.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
net/unix/af_unix.c +1 -4
@@ -1531,7 +1531,6 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) {int i;unsigned char max_level =0 ; -int unix_sock_count =0 ;if (too_many_unix_fds (current))return -ETOOMANYREFS ;
@@ -1539,11 +1538,9 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)for (i = scm->fp->count -1 ; i >=0 ; i--) {struct sock *sk =unix_get_socket (scm->fp->fp[i]); -if (sk) { - unix_sock_count++; +if (sk) max_level =max (max_level,unix_sk (sk)->recursion_level); - } }if (unlikely (max_level >MAX_RECURSION_LEVEL ))return -ETOOMANYREFS ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 4/65 ser_gigaset: use container_of() instead of detour
In reply to Sasha LevinFrom: Paul Bolle <[email protected]>
[ Upstream commit 8d2c3ab4445640957d136caa3629857d63544a2a ]
The purpose of gigaset_device_release() is to kfree() the struct ser_cardstate that contains our struct device. This is done via a bit of a detour. First we make our struct device's driver_data point to the container of our struct ser_cardstate (which is a struct cardstate). In gigaset_device_release() we then retrieve that driver_data again. And after that we finally kfree() the struct ser_cardstate that was saved in the struct cardstate.
All of this can be achieved much easier by using container_of() to get from our struct device to its container, struct ser_cardstate. Do so.
Note that at the time the detour was implemented commit b8b2c7d845d5 ("base/platform: assert that dev_pm_domain callbacks are called unconditionally") had just entered the tree. That commit disconnected our platform_device and our platform_driver. These were reconnected again in v4.5-rc2 through commit 25cad69f21f5 ("base/platform: Fix platform drivers with no probe callback"). And one of the consequences of that fix was that it broke the detour via driver_data. That's because it made __device_release_driver() stop being a NOP for our struct device and actually do stuff again. One of the things it now does, is setting our driver_data to NULL. That, in turn, makes it impossible for gigaset_device_release() to get to our struct cardstate. Which has the net effect of leaking a struct ser_cardstate at every call of this driver's tty close() operation. So using container_of() has the additional benefit of actually working.
--- drivers/isdn/gigaset/ser-gigaset.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-)
drivers/isdn/gigaset/ser-gigaset.c +1 -8
@@ -373,13 +373,7 @@ static void gigaset_freecshw(struct cardstate *cs)static void gigaset_device_release (struct device *dev) { -struct cardstate *cs =dev_get_drvdata (dev); - -if (!cs) -return ; -dev_set_drvdata (dev,NULL ); -kfree (cs->hw.ser); - cs->hw.ser =NULL ; + kfree(container_of(dev, struct ser_cardstate, dev.dev)); }/*
@@ -408,7 +402,6 @@ static int gigaset_initcshw(struct cardstate *cs) cs->hw.ser =NULL ;return rc; } -dev_set_drvdata (&cs->hw.ser->dev.dev, cs);tasklet_init (&cs->write_tasklet, gigaset_modem_fill, (unsigned long ) cs);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 5/65 tracing: Skip more functions when doing stack tracing of events
In reply to Sasha LevinFrom: "Steven Rostedt (Red Hat)" <[email protected]>
[ Upstream commit be54f69c26193de31053190761e521903b89d098 ]
# echo 1 > options/stacktrace
# echo 1 > events/sched/sched_switch/enable
# cat trace
<idle>-0 [002] d..2 1982.525169: <stack trace>
=> save_stack_trace
=> __ftrace_trace_stack
=> trace_buffer_unlock_commit_regs
=> event_trigger_unlock_commit
=> trace_event_buffer_commit
=> trace_event_raw_event_sched_switch
=> __schedule
=> schedule
=> schedule_preempt_disabled
=> cpu_startup_entry
=> start_secondaryThe above shows that we are seeing 6 functions before ever making it to the caller of the sched_switch event.
# echo stacktrace > events/sched/sched_switch/trigger
# cat trace
<idle>-0 [002] d..3 2146.335208: <stack trace>
=> trace_event_buffer_commit
=> trace_event_raw_event_sched_switch
=> __schedule
=> schedule
=> schedule_preempt_disabled
=> cpu_startup_entry
=> start_secondaryThe stacktrace trigger isn't as bad, because it adds its own skip to the stacktracing, but still has two events extra.
One issue is that if the stacktrace passes its own "regs" then there should be no addition to the skip, as the regs will not include the functions being called. This was an issue that was fixed by commit 7717c6be6999 ("tracing:
Fix stacktrace skip depth in trace_buffer_unlock_commit_regs()" as adding the skip number for kprobes made the probes not have any stack at all.
But since this is only an issue when regs is being used, a skip should be added if regs is NULL. Now we have:
# echo 1 > options/stacktrace
# echo 1 > events/sched/sched_switch/enable
# cat trace
<idle>-0 [000] d..2 1297.676333: <stack trace>
=> __schedule
=> schedule
=> schedule_preempt_disabled
=> cpu_startup_entry
=> rest_init
=> start_kernel
=> x86_64_start_reservations
=> x86_64_start_kernel # echo stacktrace > events/sched/sched_switch/trigger
# cat trace
<idle>-0 [002] d..3 1370.759745: <stack trace>
=> __schedule
=> schedule
=> schedule_preempt_disabled
=> cpu_startup_entry
=> start_secondaryAnd kprobes are not touched.
--- kernel/trace/trace.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-)
kernel/trace/trace.c +18 -1
@@ -1757,7 +1757,17 @@ void trace_buffer_unlock_commit_regs(struct trace_array *tr, {__buffer_unlock_commit (buffer, event); -ftrace_trace_stack (tr, buffer, flags,0 , pc, regs); +/* +* If regs is not set, then skip the following callers: +* trace_buffer_unlock_commit_regs +* event_trigger_unlock_commit +* trace_event_buffer_commit +* trace_event_raw_event_sched_switch +* Note, we can still get here via blktrace, wakeup tracer +* and mmiotrace, but that's ok if they lose a function or +* two. They are that meaningful. +*/ +ftrace_trace_stack (tr, buffer, flags, regs ?0 :4 , pc, regs);ftrace_trace_userstack (buffer, flags, pc); }EXPORT_SYMBOL_GPL (trace_buffer_unlock_commit_regs);
@@ -1815,6 +1825,13 @@ static void __ftrace_trace_stack(struct ring_buffer *buffer, trace.nr_entries =0 ; trace.skip = skip; +/* +* Add two, for this function and the call to save_stack_trace() +* If regs is set, then these functions will not be in the way. +*/ +if (!regs) + trace.skip +=2 ; +/* * Since events can happen in NMIs there's no safe way to * use the per cpu ftrace_stacks. We reserve it and if an interrupt
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 6/65 ARM: dts: apq8064: add ahci ports-implemented mask
In reply to Sasha LevinFrom: Srinivas Kandagatla <[email protected]>
[ Upstream commit bb4add2ce991e4ec891b5a0287fd1ab77b631979 ]
This patch adds new ports-implemented mask, which is required to get achi working on the mainline. Without this patch value read from PORTS_IMPL register which is zero would not enable any ports for software to use.
--- arch/arm/boot/dts/qcom-apq8064.dtsi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/arm/boot/dts/qcom-apq8064.dtsi +2 -1
@@ -577,7 +577,7 @@ }; sata0: sata@29000000 { - compatible = "generic-ahci"; + compatible = "qcom,apq8064-ahci", "generic-ahci"; status = "disabled"; reg = <0x29000000 0x180>; interrupts = <GIC_SPI 209 IRQ_TYPE_NONE>;
@@ -599,6 +599,7 @@ phys = <&sata_phy0>; phy-names = "sata-phy"; + ports-implemented = <0x1>; }; /* Temporary fixed regulator */
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 7/65 x86/mm/pat: Prevent hang during boot when mapping pages
In reply to Sasha LevinFrom: Matt Fleming <[email protected]>
[ Upstream commit e535ec0899d1fe52ec3a84c9bc03457ac67ad6f7 ]
There's a mixture of signed 32-bit and unsigned 32-bit and 64-bit data types used for keeping track of how many pages have been mapped.
This leads to hangs during boot when mapping large numbers of pages (multiple terabytes, as reported by Waiman) because those values are interpreted as being negative.
commit 742563777e8d ("x86/mm/pat: Avoid truncation when converting cpa->numpages to address") fixed one of those bugs, but there is another lurking in __change_page_attr_set_clr().
Additionally, the return value type for the populate_*() functions can return negative values when a large number of pages have been mapped, triggering the error paths even though no error occurred.
Consistently use 64-bit types on 64-bit platforms when counting pages. Even in the signed case this gives us room for regions 8PiB (pebibytes) in size whilst still allowing the usual negative value error checking idiom.
--- arch/x86/mm/pageattr.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-)
arch/x86/mm/pageattr.c +11 -10
@@ -955,11 +955,11 @@ static void populate_pte(struct cpa_data *cpa, } } -static int populate_pmd (struct cpa_data *cpa, -unsigned long start,unsigned long end, -unsigned num_pages,pud_t *pud,pgprot_t pgprot) +static long populate_pmd (struct cpa_data *cpa, +unsigned long start,unsigned long end, +unsigned num_pages,pud_t *pud,pgprot_t pgprot) { -unsigned int cur_pages =0 ; +long cur_pages =0 ;pmd_t *pmd;pgprot_t pmd_pgprot;
@@ -1029,12 +1029,12 @@ static int populate_pmd(struct cpa_data *cpa,return num_pages; } -static int populate_pud (struct cpa_data *cpa,unsigned long start,pgd_t *pgd, -pgprot_t pgprot) +static long populate_pud (struct cpa_data *cpa,unsigned long start,pgd_t *pgd, +pgprot_t pgprot) {pud_t *pud;unsigned long end; -int cur_pages =0 ; +long cur_pages =0 ;pgprot_t pud_pgprot; end = start + (cpa->numpages <<PAGE_SHIFT );
@@ -1090,7 +1090,7 @@ static int populate_pud(struct cpa_data *cpa, unsigned long start, pgd_t *pgd,/* Map trailing leftover */ if (start < end) { -int tmp; +long tmp; pud =pud_offset (pgd, start);if (pud_none (*pud))
@@ -1116,7 +1116,7 @@ static int populate_pgd(struct cpa_data *cpa, unsigned long addr)pgprot_t pgprot =__pgprot (_KERNPG_TABLE);pud_t *pud =NULL ;/* shut up gcc */ pgd_t *pgd_entry; -int ret; +long ret; pgd_entry = cpa->pgd +pgd_index (addr);
@@ -1351,7 +1351,8 @@ static int cpa_process_alias(struct cpa_data *cpa)static int __change_page_attr_set_clr (struct cpa_data *cpa,int checkalias) { -int ret, numpages = cpa->numpages; +unsigned long numpages = cpa->numpages; +int ret;while (numpages) {/*
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 8/65 btrfs: cleaner_kthread() doesn't need explicit freeze
In reply to Sasha LevinFrom: Jiri Kosina <[email protected]>
[ Upstream commit 838fe1887765f4cc679febea60d87d2a06bd300e ]
cleaner_kthread() is not marked freezable, and therefore calling try_to_freeze() in its context is a pointless no-op.
In addition to that, as has been clearly demonstrated by 80ad623edd2d ("Revert "btrfs: clear PF_NOFREEZE in cleaner_kthread()"), it's perfectly valid / legal for cleaner_kthread() to stay scheduled out in an arbitrary place during suspend (in that particular example that was waiting for reading of extent pages), so there is no need to leave any traces of freezer in this kthread.
--- fs/btrfs/disk-io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/btrfs/disk-io.c +1 -1
@@ -1820,7 +1820,7 @@ static int cleaner_kthread(void *arg)*/ btrfs_delete_unused_bgs (root->fs_info); sleep: -if (!try_to_freeze () && !again) { +if (!again) {set_current_state (TASK_INTERRUPTIBLE );if (!kthread_should_stop ())schedule ();
Signature · 1 line
2.17.1
Re: [PATCH AUTOSEL 4.4 08/65] btrfs: cleaner_kthread() doesn't need explicit freeze
Quoted 14 lines · Sasha Levin
From: Jiri Kosina <[email protected]>
[ Upstream commit
838fe1887765f4cc679febea60d87d2a06bd300e]
cleaner_kthread()is not marked freezable, and therefore callingtry_to_freeze()in its context is a pointless no-op.In addition to that, as has been clearly demonstrated by
80ad623edd2d("Revert "btrfs: clearPF_NOFREEZEincleaner_kthread()"), it's perfectly valid / legal forcleaner_kthread()to stay scheduled out in an arbitrary place during suspend (in that particular example that was waiting for reading of extent pages), so there is no need to leave any traces of freezer in this kthread.
Quoted 5 lines
Fixes 80ad623edd2d ("Revert "btrfs: clear PF_NOFREEZE in cleaner_kthread()")Fixes 696249132158 ("btrfs: clear PF_NOFREEZE in cleaner_kthread()")Signed-off-by Jiri Kosina <[email protected]>Signed-off-by David Sterba <[email protected]>Signed-off-by Sasha Levin <[email protected]>
IIRC it was some preparatory work for livepatching. I did a quick check if this is safe for 4.4 and would say yes, but the patch does not fix anything so IMO this does not need to go to stable.
Sasha Levin
maintainerRe: [PATCH AUTOSEL 4.4 08/65] btrfs: cleaner_kthread() doesn't need explicit freeze
Quoted 21 lines · David Sterba
Quoted 14 lines · Sasha Levin
From: Jiri Kosina <[email protected]>
[ Upstream commit
838fe1887765f4cc679febea60d87d2a06bd300e]
cleaner_kthread()is not marked freezable, and therefore callingtry_to_freeze()in its context is a pointless no-op.In addition to that, as has been clearly demonstrated by
80ad623edd2d("Revert "btrfs: clearPF_NOFREEZEincleaner_kthread()"), it's perfectly valid / legal forcleaner_kthread()to stay scheduled out in an arbitrary place during suspend (in that particular example that was waiting for reading of extent pages), so there is no need to leave any traces of freezer in this kthread.Quoted 5 lines
Fixes 80ad623edd2d ("Revert "btrfs: clear PF_NOFREEZE in cleaner_kthread()")Fixes 696249132158 ("btrfs: clear PF_NOFREEZE in cleaner_kthread()")Signed-off-by Jiri Kosina <[email protected]>Signed-off-by David Sterba <[email protected]>Signed-off-by Sasha Levin <[email protected]>
Quoted 3 lines
IIRC it was some preparatory work for livepatching. I did a quick check if this is safe for 4.4 and would say yes, but the patch does not fix anything so IMO this does not need to go to stable.
Doesn't that also affect hibernation and such?
--
Thanks,
Sasha
Re: [PATCH AUTOSEL 4.4 08/65] btrfs: cleaner_kthread() doesn't need explicit freeze
Quoted 17 lines · Sasha Levin
Quoted 17 lines
Quoted 16 lines
cleaner_kthread()is not marked freezable, and therefore callingtry_to_freeze()in its context is a pointless no-op.In addition to that, as has been clearly demonstrated by
80ad623edd2d("Revert "btrfs: clearPF_NOFREEZEincleaner_kthread()"), it's perfectly valid / legal forcleaner_kthread()to stay scheduled out in an arbitrary place during suspend (in that particular example that was waiting for reading of extent pages), so there is no need to leave any traces of freezer in this kthread.Fixes 80ad623edd2d ("Revert "btrfs: clear PF_NOFREEZE inFixes cleaner_kthread()")Fixes 696249132158 ("btrfs: clear PF_NOFREEZE in cleaner_kthread()")Signed-off-by Jiri Kosina <[email protected]>Signed-off-by David Sterba <[email protected]>Signed-off-by Sasha Levin <[email protected]>
Quoted 5 lines
Quoted 3 lines
IIRC it was some preparatory work for livepatching. I did a quick check if this is safe for 4.4 and would say yes, but the patch does not fix anything so IMO this does not need to go to stable.
Doesn't that also affect hibernation and such?
This patch just removes pointless try_to_freeze(), that's guaranteed not to do anything and return immediately, as the btrfs kthread is not freezable.
So I don't think it's needed in stable; the semantics is equivalent before and after.
Thanks,
Signature · 2 lines
Jiri Kosina SUSE Labs
Sasha Levin
maintainerRe: [PATCH AUTOSEL 4.4 08/65] btrfs: cleaner_kthread() doesn't need explicit freeze
Quoted 23 lines · Jiri Kosina
Quoted 21 lines · Sasha Levin
Quoted 20 lines
Quoted 10 lines
cleaner_kthread()is not marked freezable, and therefore callingtry_to_freeze()in its context is a pointless no-op.In addition to that, as has been clearly demonstrated by
80ad623edd2d("Revert "btrfs: clearPF_NOFREEZEincleaner_kthread()"), it's perfectly valid / legal forcleaner_kthread()to stay scheduled out in an arbitrary place during suspend (in that particular example that was waiting for reading of extent pages), so there is no need to leave any traces of freezer in this kthread.Quoted 6 lines
Fixes 80ad623edd2d ("Revert "btrfs: clear PF_NOFREEZE inFixes cleaner_kthread()")Fixes 696249132158 ("btrfs: clear PF_NOFREEZE in cleaner_kthread()")Signed-off-by Jiri Kosina <[email protected]>Signed-off-by David Sterba <[email protected]>Signed-off-by Sasha Levin <[email protected]>IIRC it was some preparatory work for livepatching. I did a quick check if this is safe for 4.4 and would say yes, but the patch does not fix anything so IMO this does not need to go to stable.
Quoted 7 lines
Quoted 1 line
Doesn't that also affect hibernation and such?
This patch just removes pointless
try_to_freeze(), that's guaranteed not to do anything and return immediately, as the btrfs kthread is not freezable.
So I don't think it's needed in stable; the semantics is equivalent before and after.
Gotcha. I'll drop it. Thank you!
--
Thanks,
Sasha
Sasha Levin
maintainerPATCH 9/65 radix-tree: fix radix_tree_iter_retry() for tagged iterators.
In reply to Sasha LevinFrom: Andrey Ryabinin <[email protected]>
[ Upstream commit 3cb9185c67304b2a7ea9be73e7d13df6fb2793a1 ]
radix_tree_iter_retry() resets slot to NULL, but it doesn't reset tags. Then NULL slot and non-zero iter.tags passed to radix_tree_next_slot() leading to crash:
RIP: radix_tree_next_slot include/linux/radix-tree.h:473
find_get_pages_tag+0x334/0x930 mm/filemap.c:1452
....
Call Trace:
pagevec_lookup_tag+0x3a/0x80 mm/swap.c:960
mpage_prepare_extent_to_map+0x321/0xa90 fs/ext4/inode.c:2516
ext4_writepages+0x10be/0x2b20 fs/ext4/inode.c:2736
do_writepages+0x97/0x100 mm/page-writeback.c:2364
__filemap_fdatawrite_range+0x248/0x2e0 mm/filemap.c:300
filemap_write_and_wait_range+0x121/0x1b0 mm/filemap.c:490
ext4_sync_file+0x34d/0xdb0 fs/ext4/fsync.c:115
vfs_fsync_range+0x10a/0x250 fs/sync.c:195
vfs_fsync fs/sync.c:209
do_fsync+0x42/0x70 fs/sync.c:219
SYSC_fdatasync fs/sync.c:232
SyS_fdatasync+0x19/0x20 fs/sync.c:230
entry_SYSCALL_64_fastpath+0x23/0xc1 arch/x86/entry/entry_64.S:207We must reset iterator's tags to bail out from radix_tree_next_slot() and go to the slow-path in radix_tree_next_chunk().
--- include/linux/radix-tree.h | 1 + 1 file changed, 1 insertion(+)
include/linux/radix-tree.h +1 -0
@@ -382,6 +382,7 @@ static inline __must_checkvoid **radix_tree_iter_retry (struct radix_tree_iter *iter) { iter->next_index = iter->index; + iter->tags =0 ;return NULL ; }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 10/65 af_iucv: Move sockaddr length checks to before accessing sa_family in bind and connect handlers
In reply to Sasha LevinFrom: Mateusz Jurczyk <[email protected]>
[ Upstream commit e3c42b61ff813921ba58cfc0019e3fd63f651190 ]
Verify that the caller-provided sockaddr structure is large enough to contain the sa_family field, before accessing it in bind() and connect() handlers of the AF_IUCV socket. Since neither syscall enforces a minimum size of the corresponding memory region, very short sockaddrs (zero or one byte long) result in operating on uninitialized memory while referencing .sa_family.
--- net/iucv/af_iucv.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
net/iucv/af_iucv.c +3 -5
@@ -705,10 +705,8 @@ static int iucv_sock_bind(struct socket *sock, struct sockaddr *addr,char uid[9 ];/* Verify the input sockaddr */ -if (!addr || addr->sa_family !=AF_IUCV ) -return -EINVAL ; - -if (addr_len <sizeof (struct sockaddr_iucv )) +if (addr_len <sizeof (struct sockaddr_iucv ) || + addr->sa_family !=AF_IUCV )return -EINVAL ;lock_sock (sk);
@@ -852,7 +850,7 @@ static int iucv_sock_connect(struct socket *sock, struct sockaddr *addr,struct iucv_sock *iucv =iucv_sk (sk);int err; -if (addr->sa_family !=AF_IUCV || alen <sizeof (struct sockaddr_iucv )) +if (alen <sizeof (struct sockaddr_iucv ) || addr->sa_family !=AF_IUCV )return -EINVAL ;if (sk->sk_state !=IUCV_OPEN && sk->sk_state !=IUCV_BOUND )
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 11/65 net/mlx4_en: Resolve dividing by zero in 32-bit system
In reply to Sasha LevinFrom: Eugenia Emantayev <[email protected]>
[ Upstream commit 4850cf4581578216468b7b3c3d06cc5abb0a697d ]
When doing roundup_pow_of_two for large enough number with bit 31, an overflow will occur and a value equal to 1 will be returned. In this case 1 will be subtracted from the return value and division by zero will be reached.
--- drivers/net/ethernet/mellanox/mlx4/en_clock.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx4/en_clock.c +4 -1
@@ -251,8 +251,11 @@ static u32 freq_to_shift(u16 freq) {u32 freq_khz = freq *1000 ;u64 max_val_cycles = freq_khz *1000 *MLX4_EN_WRAP_AROUND_SEC ; +u64 tmp_rounded = +roundup_pow_of_two (max_val_cycles) > max_val_cycles ? +roundup_pow_of_two (max_val_cycles) -1 :UINT_MAX ;u64 max_val_cycles_rounded =is_power_of_2 (max_val_cycles +1 ) ? - max_val_cycles :roundup_pow_of_two (max_val_cycles) -1 ; + max_val_cycles : tmp_rounded;/* calculate max possible multiplier in order to fit in 64bit */ u64 max_mul =div_u64 (0xffffffffffffffffULL , max_val_cycles_rounded);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 12/65 ipv6: orphan skbs in reassembly unit
In reply to Sasha LevinFrom: Eric Dumazet <[email protected]>
[ Upstream commit 48cac18ecf1de82f76259a54402c3adb7839ad01 ]
Andrey reported a use-after-free in IPv6 stack.
Issue here is that we free the socket while it still has skb in TX path and in some queues.
It happens here because IPv6 reassembly unit messes skb->truesize, breaking skb_set_owner_w() badly.
We fixed a similar issue for IPV4 in commit 8282f27449bf ("inet: frag:
Always orphan skbs inside ip_defrag()")
==================================================================
BUG: KASAN: use-after-free in sock_wfree+0x118/0x120 Read of size 8 at addr ffff880062da0060 by task a.out/4140
page:ffffea00018b6800 count:1 mapcount:0 mapping: (null)
index:0x0 compound_mapcount: 0
flags: 0x100000000008100(slab|head)
raw: 0100000000008100 0000000000000000 0000000000000000 0000000180130013 raw: dead000000000100 dead000000000200 ffff88006741f140 0000000000000000 page dumped because: kasan: bad access detected CPU: 0 PID: 4140 Comm: a.out Not tainted 4.10.0-rc3+ #59 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:15 dump_stack+0x292/0x398 lib/dump_stack.c:51 describe_address mm/kasan/report.c:262 kasan_report_error+0x121/0x560 mm/kasan/report.c:370 kasan_report mm/kasan/report.c:392 __asan_report_load8_noabort+0x3e/0x40 mm/kasan/report.c:413 sock_flag ./arch/x86/include/asm/bitops.h:324 sock_wfree+0x118/0x120 net/core/sock.c:1631 skb_release_head_state+0xfc/0x250 net/core/skbuff.c:655 skb_release_all+0x15/0x60 net/core/skbuff.c:668 __kfree_skb+0x15/0x20 net/core/skbuff.c:684 kfree_skb+0x16e/0x4e0 net/core/skbuff.c:705 inet_frag_destroy+0x121/0x290 net/ipv4/inet_fragment.c:304 inet_frag_put ./include/net/inet_frag.h:133 nf_ct_frag6_gather+0x1125/0x38b0 net/ipv6/netfilter/nf_conntrack_reasm.c:617 ipv6_defrag+0x21b/0x350 net/ipv6/netfilter/nf_defrag_ipv6_hooks.c:68 nf_hook_entry_hookfn ./include/linux/netfilter.h:102 nf_hook_slow+0xc3/0x290 net/netfilter/core.c:310 nf_hook ./include/linux/netfilter.h:212 __ip6_local_out+0x52c/0xaf0 net/ipv6/output_core.c:160 ip6_local_out+0x2d/0x170 net/ipv6/output_core.c:170 ip6_send_skb+0xa1/0x340 net/ipv6/ip6_output.c:1722 ip6_push_pending_frames+0xb3/0xe0 net/ipv6/ip6_output.c:1742 rawv6_push_pending_frames net/ipv6/raw.c:613 rawv6_sendmsg+0x2cff/0x4130 net/ipv6/raw.c:927 inet_sendmsg+0x164/0x5b0 net/ipv4/af_inet.c:744 sock_sendmsg_nosec net/socket.c:635 sock_sendmsg+0xca/0x110 net/socket.c:645 sock_write_iter+0x326/0x620 net/socket.c:848 new_sync_write fs/read_write.c:499 __vfs_write+0x483/0x760 fs/read_write.c:512 vfs_write+0x187/0x530 fs/read_write.c:560 SYSC_write fs/read_write.c:607 SyS_write+0xfb/0x230 fs/read_write.c:599 entry_SYSCALL_64_fastpath+0x1f/0xc2 arch/x86/entry/entry_64.S:203 RIP: 0033:0x7ff26e6f5b79 RSP: 002b:00007ff268e0ed98 EFLAGS: 00000206 ORIG_RAX: 0000000000000001 RAX: ffffffffffffffda RBX: 00007ff268e0f9c0 RCX: 00007ff26e6f5b79 RDX: 0000000000000010 RSI: 0000000020f50fe1 RDI: 0000000000000003 RBP: 00007ff26ebc1220 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000206 R12: 0000000000000000 R13: 00007ff268e0f9c0 R14: 00007ff26efec040 R15: 0000000000000003 The buggy address belongs to the object at ffff880062da0000 which belongs to the cache RAWv6 of size 1504
The buggy address ffff880062da0060 is located 96 bytes inside
of 1504-byte region [ffff880062da0000, ffff880062da05e0)
Freed by task 4113:
save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:57
save_stack+0x43/0xd0 mm/kasan/kasan.c:502
set_track mm/kasan/kasan.c:514
kasan_slab_free+0x73/0xc0 mm/kasan/kasan.c:578
slab_free_hook mm/slub.c:1352
slab_free_freelist_hook mm/slub.c:1374
slab_free mm/slub.c:2951
kmem_cache_free+0xb2/0x2c0 mm/slub.c:2973
sk_prot_free net/core/sock.c:1377
__sk_destruct+0x49c/0x6e0 net/core/sock.c:1452
sk_destruct+0x47/0x80 net/core/sock.c:1460
__sk_free+0x57/0x230 net/core/sock.c:1468
sk_free+0x23/0x30 net/core/sock.c:1479
sock_put ./include/net/sock.h:1638
sk_common_release+0x31e/0x4e0 net/core/sock.c:2782
rawv6_close+0x54/0x80 net/ipv6/raw.c:1214
inet_release+0xed/0x1c0 net/ipv4/af_inet.c:425
inet6_release+0x50/0x70 net/ipv6/af_inet6.c:431
sock_release+0x8d/0x1e0 net/socket.c:599
sock_close+0x16/0x20 net/socket.c:1063
__fput+0x332/0x7f0 fs/file_table.c:208
____fput+0x15/0x20 fs/file_table.c:244
task_work_run+0x19b/0x270 kernel/task_work.c:116
exit_task_work ./include/linux/task_work.h:21
do_exit+0x186b/0x2800 kernel/exit.c:839
do_group_exit+0x149/0x420 kernel/exit.c:943
SYSC_exit_group kernel/exit.c:954
SyS_exit_group+0x1d/0x20 kernel/exit.c:952
entry_SYSCALL_64_fastpath+0x1f/0xc2 arch/x86/entry/entry_64.S:203
Allocated by task 4115:
save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:57
save_stack+0x43/0xd0 mm/kasan/kasan.c:502
set_track mm/kasan/kasan.c:514
kasan_kmalloc+0xad/0xe0 mm/kasan/kasan.c:605
kasan_slab_alloc+0x12/0x20 mm/kasan/kasan.c:544
slab_post_alloc_hook mm/slab.h:432
slab_alloc_node mm/slub.c:2708
slab_alloc mm/slub.c:2716
kmem_cache_alloc+0x1af/0x250 mm/slub.c:2721
sk_prot_alloc+0x65/0x2a0 net/core/sock.c:1334
sk_alloc+0x105/0x1010 net/core/sock.c:1396
inet6_create+0x44d/0x1150 net/ipv6/af_inet6.c:183
__sock_create+0x4f6/0x880 net/socket.c:1199
sock_create net/socket.c:1239
SYSC_socket net/socket.c:1269
SyS_socket+0xf9/0x230 net/socket.c:1249
entry_SYSCALL_64_fastpath+0x1f/0xc2 arch/x86/entry/entry_64.S:203
Memory state around the buggy address:
ffff880062d9ff00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
ffff880062d9ff80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>ffff880062da0000: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff880062da0080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff880062da0100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================--- net/ipv6/netfilter/nf_conntrack_reasm.c | 1 + 1 file changed, 1 insertion(+)
net/ipv6/netfilter/nf_conntrack_reasm.c +1 -0
@@ -601,6 +601,7 @@ struct sk_buff *nf_ct_frag6_gather(struct net *net, struct sk_buff *skb, u32 use hdr =ipv6_hdr (clone); fhdr = (struct frag_hdr *)skb_transport_header (clone); +skb_orphan (skb); fq =fq_find (net, fhdr->identification, user, &hdr->saddr, &hdr->daddr, skb->dev ? skb->dev->ifindex :0 ,ip6_frag_ecn (hdr));if (fq ==NULL ) {
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 13/65 um: Avoid longjmp/setjmp symbol clashes with libpthread.a
In reply to Sasha LevinFrom: Florian Fainelli <[email protected]>
[ Upstream commit f44f1e7da7c8e3f4575d5d61c4df978496903fcc ]
Building a statically linked UML kernel on a Centos 6.9 host resulted in the following linking failure (GCC 4.4, glibc-2.12):
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64/libpthread.a(libpthread.o):
In function `siglongjmp':
(.text+0x8490): multiple definition of `longjmp' arch/x86/um/built-in.o:/local/users/fainelli/openwrt/trunk/build_dir/target-x86_64_musl/linux-uml/linux-4.4.69/arch/x86/um/setjmp_64.S:44:
first defined here
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64/libpthread.a(libpthread.o):
In function `sem_open':
(.text+0x77cd): warning: the use of `mktemp' is dangerous, better use
`mkstemp'
collect2: ld returned 1 exit status
make[4]: *** [vmlinux] Error 1
Adopt a solution similar to the one done for vmap where we define longjmp/setjmp to be kernel_longjmp/setjmp. In the process, make sure we do rename the functions in arch/x86/um/setjmp_*.S accordingly.
--- arch/um/Makefile | 4 ++++ arch/x86/um/setjmp_32.S | 16 ++++++++-------- arch/x86/um/setjmp_64.S | 16 ++++++++-------- 3 files changed, 20 insertions(+), 16 deletions(-)
arch/um/Makefile +4 -0
@@ -59,10 +59,14 @@ KBUILD_CPPFLAGS += -I$(srctree)/$(HOST_DIR)/um # Same things for in6addr_loopback and mktime - found in libc. For these two we # only get link-time error, luckily. # +# -Dlongjmp=kernel_longjmp prevents anything from referencing the libpthread.a +# embedded copy of longjmp, same thing for setjmp. +# # These apply to USER_CFLAGS to. KBUILD_CFLAGS += $(CFLAGS) $(CFLAGS-y) -D__arch_um__ \ $(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap \ + -Dlongjmp=kernel_longjmp -Dsetjmp=kernel_setjmp \ -Din6addr_loopback=kernel_in6addr_loopback \ -Din6addr_any=kernel_in6addr_any -Dstrrchr=kernel_strrchr
arch/x86/um/setjmp_32.S +8 -8
@@ -16,9 +16,9 @@ .text .align 4 - .globl setjmp - .type setjmp, @function -setjmp: + .globl kernel_setjmp + .type kernel_setjmp, @function +kernel_setjmp: #ifdef _REGPARM movl %eax,%edx #else
@@ -35,13 +35,13 @@ setjmp: movl %ecx,20(%edx) # Return address ret - .size setjmp,.-setjmp + .size kernel_setjmp,.-kernel_setjmp .text .align 4 - .globl longjmp - .type longjmp, @function -longjmp: + .globl kernel_longjmp + .type kernel_longjmp, @function +kernel_longjmp: #ifdef _REGPARM xchgl %eax,%edx #else
@@ -55,4 +55,4 @@ longjmp: movl 16(%edx),%edi jmp *20(%edx) - .size longjmp,.-longjmp + .size kernel_longjmp,.-kernel_longjmp
arch/x86/um/setjmp_64.S +8 -8
@@ -18,9 +18,9 @@ .text .align 4 - .globl setjmp - .type setjmp, @function -setjmp: + .globl kernel_setjmp + .type kernel_setjmp, @function +kernel_setjmp: pop %rsi # Return address, and adjust the stack xorl %eax,%eax # Return value movq %rbx,(%rdi)
@@ -34,13 +34,13 @@ setjmp: movq %rsi,56(%rdi) # Return address ret - .size setjmp,.-setjmp + .size kernel_setjmp,.-kernel_setjmp .text .align 4 - .globl longjmp - .type longjmp, @function -longjmp: + .globl kernel_longjmp + .type kernel_longjmp, @function +kernel_longjmp: movl %esi,%eax # Return value (int) movq (%rdi),%rbx movq 8(%rdi),%rsp
@@ -51,4 +51,4 @@ longjmp: movq 48(%rdi),%r15 jmp *56(%rdi) - .size longjmp,.-longjmp + .size kernel_longjmp,.-kernel_longjmp
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 14/65 sched/cgroup: Fix cgroup entity load tracking tear-down
In reply to Sasha LevinFrom: Peter Zijlstra <[email protected]>
[ Upstream commit 6fe1f348b3dd1f700f9630562b7d38afd6949568 ]
When a cgroup's CPU runqueue is destroyed, it should remove its remaining load accounting from its parent cgroup.
The current site for doing so it unsuited because its far too late and unordered against other cgroup removal (->css_free() will be, but we're also in an RCU callback).
Put it in the ->css_offline() callback, which is the start of cgroup destruction, right after the group has been made unavailable to userspace. The ->css_offline() callbacks are called in hierarchical order after the following v4.4 commit:
aa226ff4a1ce ("cgroup: make sure a parent css isn't offlined before its children")
--- kernel/sched/core.c | 4 +--- kernel/sched/fair.c | 37 +++++++++++++++++++++---------------- kernel/sched/sched.h | 2 +- 3 files changed, 23 insertions(+), 20 deletions(-)
kernel/sched/core.c +1 -3
@@ -7817,11 +7817,9 @@ void sched_destroy_group(struct task_group *tg)void sched_offline_group (struct task_group *tg) {unsigned long flags; -int i;/* end participation in shares distribution */ -for_each_possible_cpu (i) -unregister_fair_sched_group (tg, i); +unregister_fair_sched_group (tg);spin_lock_irqsave (&task_group_lock, flags);list_del_rcu (&tg->list);
kernel/sched/fair.c +21 -16
@@ -8154,11 +8154,8 @@ void free_fair_sched_group(struct task_group *tg)for_each_possible_cpu (i) {if (tg->cfs_rq)kfree (tg->cfs_rq[i]); -if (tg->se) { -if (tg->se[i]) -remove_entity_load_avg (tg->se[i]); +if (tg->se)kfree (tg->se[i]); - } }kfree (tg->cfs_rq);
@@ -8206,21 +8203,29 @@ int alloc_fair_sched_group(struct task_group *tg, struct task_group *parent)return 0 ; } -void unregister_fair_sched_group (struct task_group *tg,int cpu) +void unregister_fair_sched_group (struct task_group *tg) { -struct rq *rq =cpu_rq (cpu);unsigned long flags; +struct rq *rq; +int cpu; -/* -* Only empty task groups can be destroyed; so we can speculatively -* check on_list without danger of it being re-added. -*/ -if (!tg->cfs_rq[cpu]->on_list) -return ; +for_each_possible_cpu (cpu) { +if (tg->se[cpu]) +remove_entity_load_avg (tg->se[cpu]); -raw_spin_lock_irqsave (&rq->lock, flags); -list_del_leaf_cfs_rq (tg->cfs_rq[cpu]); -raw_spin_unlock_irqrestore (&rq->lock, flags); +/* +* Only empty task groups can be destroyed; so we can speculatively +* check on_list without danger of it being re-added. +*/ +if (!tg->cfs_rq[cpu]->on_list) +continue ; + + rq =cpu_rq (cpu); + +raw_spin_lock_irqsave (&rq->lock, flags); +list_del_leaf_cfs_rq (tg->cfs_rq[cpu]); +raw_spin_unlock_irqrestore (&rq->lock, flags); + } } void init_tg_cfs_entry(struct task_group *tg, struct cfs_rq *cfs_rq,
@@ -8302,7 +8307,7 @@ int alloc_fair_sched_group(struct task_group *tg, struct task_group *parent) return 1; } -void unregister_fair_sched_group (struct task_group *tg,int cpu) { } +void unregister_fair_sched_group (struct task_group *tg) { }#endif /* CONFIG_FAIR_GROUP_SCHED */
kernel/sched/sched.h +1 -1
@@ -308,7 +308,7 @@ extern int tg_nop(struct task_group *tg, void *data);extern void free_fair_sched_group (struct task_group *tg);extern int alloc_fair_sched_group (struct task_group *tg,struct task_group *parent); -extern void unregister_fair_sched_group (struct task_group *tg,int cpu); +extern void unregister_fair_sched_group (struct task_group *tg);extern void init_tg_cfs_entry (struct task_group *tg,struct cfs_rq *cfs_rq,struct sched_entity *se,int cpu,struct sched_entity *parent);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 15/65 btrfs: don't create or leak aliased root while cleaning up orphans
In reply to Sasha LevinFrom: Jeff Mahoney <[email protected]>
[ Upstream commit 35bbb97fc898aeb874cb7c8b746f091caa359994 ]
commit 909c3a22da3 (Btrfs: fix loading of orphan roots leading to BUG_ON) avoids the BUG_ON but can add an aliased root to the dead_roots list or leak the root.
Since we've already been loading roots into the radix tree, we should use it before looking the root up on disk.
--- fs/btrfs/disk-io.c | 4 ++-- fs/btrfs/disk-io.h | 2 ++ fs/btrfs/root-tree.c | 27 ++++++++++++++++++--------- 3 files changed, 22 insertions(+), 11 deletions(-)
fs/btrfs/disk-io.c +2 -2
@@ -1608,8 +1608,8 @@ int btrfs_init_fs_root(struct btrfs_root *root)return ret; } -static struct btrfs_root *btrfs_lookup_fs_root (struct btrfs_fs_info *fs_info, -u64 root_id) +struct btrfs_root *btrfs_lookup_fs_root (struct btrfs_fs_info *fs_info, +u64 root_id) {struct btrfs_root *root;
fs/btrfs/disk-io.h +2 -0
@@ -68,6 +68,8 @@ struct extent_buffer *btrfs_find_tree_block(struct btrfs_fs_info *fs_info,struct btrfs_root *btrfs_read_fs_root (struct btrfs_root *tree_root,struct btrfs_key *location);int btrfs_init_fs_root (struct btrfs_root *root); +struct btrfs_root *btrfs_lookup_fs_root (struct btrfs_fs_info *fs_info, +u64 root_id);int btrfs_insert_fs_root (struct btrfs_fs_info *fs_info,struct btrfs_root *root);void btrfs_free_fs_roots (struct btrfs_fs_info *fs_info);
fs/btrfs/root-tree.c +18 -9
@@ -272,6 +272,23 @@ int btrfs_find_orphan_roots(struct btrfs_root *tree_root) root_key.objectid = key.offset; key.offset++; +/* +* The root might have been inserted already, as before we look +* for orphan roots, log replay might have happened, which +* triggers a transaction commit and qgroup accounting, which +* in turn reads and inserts fs roots while doing backref +* walking. +*/ + root =btrfs_lookup_fs_root (tree_root->fs_info, + root_key.objectid); +if (root) { +WARN_ON (!test_bit (BTRFS_ROOT_ORPHAN_ITEM_INSERTED , + &root->state)); +if (btrfs_root_refs (&root->root_item) ==0 ) +btrfs_add_dead_root (root); +continue ; + } + root =btrfs_read_fs_root (tree_root, &root_key); err =PTR_ERR_OR_ZERO (root);if (err && err != -ENOENT ) {
@@ -310,16 +327,8 @@ int btrfs_find_orphan_roots(struct btrfs_root *tree_root)set_bit (BTRFS_ROOT_ORPHAN_ITEM_INSERTED , &root->state); err =btrfs_insert_fs_root (root->fs_info, root); -/* -* The root might have been inserted already, as before we look -* for orphan roots, log replay might have happened, which -* triggers a transaction commit and qgroup accounting, which -* in turn reads and inserts fs roots while doing backref -* walking. -*/ -if (err == -EEXIST ) - err =0 ;if (err) { +BUG_ON (err == -EEXIST );btrfs_free_fs_root (root);break ; }
Signature · 1 line
2.17.1
Re: [PATCH AUTOSEL 4.4 15/65] btrfs: don't create or leak aliased root while cleaning up orphans
Quoted 4 lines · Sasha Levin
From: Jeff Mahoney <[email protected]>
[ Upstream commit
35bbb97fc898aeb874cb7c8b746f091caa359994]
Quoted 8 lines
commit
909c3a22da3(Btrfs: fix loading of orphan roots leading toBUG_ON) avoids theBUG_ONbut can add an aliased root to thedead_rootslist or leak the root.Since we've already been loading roots into the radix tree, we should use it before looking the root up on disk.
Cc <[email protected]> # 4.5
Ack for 4.4 stable.
Sasha Levin
maintainerPATCH 16/65 thermal: allow spear-thermal driver to be a module
In reply to Sasha LevinFrom: Arnd Bergmann <[email protected]>
[ Upstream commit 4d2f1794c07aae55b8f25f4d8aebcafc0d3e501d ]
When the thermal subsystem is a loadable module, the spear driver fails to build:
drivers/thermal/built-in.o: In function `spear_thermal_exit':
spear_thermal.c:(.text+0xf8): undefined reference to thermal_zone_device_unregister' drivers/thermal/built-in.o: In function spear_thermal_probe':
spear_thermal.c:(.text+0x230): undefined reference to `thermal_zone_device_register'
This changes the symbol to a tristate, so Kconfig can track the dependency correctly.
--- drivers/thermal/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/thermal/Kconfig +1 -1
@@ -195,7 +195,7 @@ config IMX_THERMAL passive trip is crossed. config SPEAR_THERMAL - bool "SPEAr thermal sensor driver" + tristate "SPEAr thermal sensor driver" depends on PLAT_SPEAR || COMPILE_TEST depends on OF help
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 17/65 thermal: allow u8500-thermal driver to be a module
In reply to Sasha LevinFrom: Arnd Bergmann <[email protected]>
[ Upstream commit 26716ce124fce88f288f07738ef685d5dfe5c13f ]
When the thermal subsystem is a loadable module, the u8500 driver fails to build:
drivers/thermal/built-in.o: In function `db8500_thermal_probe':
db8500_thermal.c:(.text+0x96c): undefined reference to thermal_zone_device_register' drivers/thermal/built-in.o: In function db8500_thermal_work':
db8500_thermal.c:(.text+0xab4): undefined reference to `thermal_zone_device_update'
This changes the symbol to a tristate, so Kconfig can track the dependency correctly.
--- drivers/mfd/db8500-prcmu.c | 3 +++ drivers/thermal/Kconfig | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-)
drivers/mfd/db8500-prcmu.c +3 -0
@@ -2048,6 +2048,7 @@ int db8500_prcmu_config_hotmon(u8 low, u8 high)return 0 ; } +EXPORT_SYMBOL_GPL (db8500_prcmu_config_hotmon);static int config_hot_period (u16 val) {
@@ -2074,11 +2075,13 @@ int db8500_prcmu_start_temp_sense(u16 cycles32k)return config_hot_period (cycles32k); } +EXPORT_SYMBOL_GPL (db8500_prcmu_start_temp_sense);int db8500_prcmu_stop_temp_sense (void ) {return config_hot_period (0xFFFF ); } +EXPORT_SYMBOL_GPL (db8500_prcmu_stop_temp_sense);static int prcmu_a9wdog (u8 cmd,u8 d0,u8 d1,u8 d2,u8 d3) {
drivers/thermal/Kconfig +2 -2
@@ -237,8 +237,8 @@ config DOVE_THERMAL framework. config DB8500_THERMAL - bool "DB8500 thermal management" - depends on ARCH_U8500 + tristate "DB8500 thermal management" + depends on MFD_DB8500_PRCMU default y help Adds DB8500 thermal management implementation according to the thermal
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 18/65 tpm: fix: return rc when devm_add_action() fails
In reply to Sasha LevinFrom: Jarkko Sakkinen <[email protected]>
[ Upstream commit 4f3b193dee4423d8c89c9a3e8e05f9197ea459a4 ]
Call put_device() and return error code if devm_add_action() fails.
--- drivers/char/tpm/tpm-chip.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/char/tpm/tpm-chip.c +5 -1
@@ -230,7 +230,11 @@ struct tpm_chip *tpmm_chip_alloc(struct device *dev, chip->cdev.owner = dev->driver->owner; chip->cdev.kobj.parent = &chip->dev.kobj; -devm_add_action (dev, (void (*)(void *)) put_device, &chip->dev); + rc =devm_add_action (dev, (void (*)(void *)) put_device, &chip->dev); +if (rc) { +put_device (&chip->dev); +return ERR_PTR (rc); + }return chip; }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 19/65 x86/PCI: Mark Broadwell-EP Home Agent 1 as having non-compliant BARs
In reply to Sasha LevinFrom: Prarit Bhargava <[email protected]>
[ Upstream commit da77b67195de1c65bef4908fa29967c4d0af2da2 ]
Commit b894157145e4 ("x86/PCI: Mark Broadwell-EP Home Agent & PCU as having non-compliant BARs") marked Home Agent 0 & PCU has having non-compliant BARs. Home Agent 1 also has non-compliant BARs.
Mark Home Agent 1 as having non-compliant BARs so the PCI core doesn't touch them.
The problem with these devices is documented in the Xeon v4 specification update:
BDF2 PCI BARs in the Home Agent Will Return Non-Zero Values
During Enumeration
Problem: During system initialization the Operating System may access
the standard PCI BARs (Base Address Registers). Due to this erratum, accesses to the Home Agent BAR registers (Bus 1; Device 18; Function 0,4; Offsets (0x14-0x24) will return non-zero values.
Implication: The operating system may issue a warning. Intel has not
observed any functional failures due to this erratum.
--- arch/x86/pci/fixup.c | 7 +++++++ 1 file changed, 7 insertions(+)
arch/x86/pci/fixup.c +7 -0
@@ -541,9 +541,16 @@ static void twinhead_reserve_killing_zone(struct pci_dev *dev) }DECLARE_PCI_FIXUP_HEADER (PCI_VENDOR_ID_INTEL ,0x27B9 , twinhead_reserve_killing_zone); +/* +* Broadwell EP Home Agent BARs erroneously return non-zero values when read. +* +* See http://www.intel.com/content/www/us/en/processors/xeon/xeon-e5-v4-spec-update.html +* entry BDF2. +*/ static void pci_bdwep_bar (struct pci_dev *dev) { dev->non_compliant_bars =1 ; } +DECLARE_PCI_FIXUP_EARLY (PCI_VENDOR_ID_INTEL ,0x6f60 , pci_bdwep_bar);DECLARE_PCI_FIXUP_EARLY (PCI_VENDOR_ID_INTEL ,0x6fa0 , pci_bdwep_bar);DECLARE_PCI_FIXUP_EARLY (PCI_VENDOR_ID_INTEL ,0x6fc0 , pci_bdwep_bar);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 20/65 aacraid: Start adapter after updating number of MSIX vectors
In reply to Sasha LevinFrom: Raghava Aditya Renukunta <[email protected]>
[ Upstream commit 116d77fea02e2a5aded7d29ba4c692774cb339f1 ]
The adapter has to be started after updating the number of MSIX Vectors
--- drivers/scsi/aacraid/linit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/aacraid/linit.c +1 -1
@@ -1416,8 +1416,8 @@ static int aac_acquire_resources(struct aac_dev *dev)/* After EEH recovery or suspend resume, max_msix count * may change, therfore updating in init as well. */ -aac_adapter_start (dev); dev->init->Sa_MSIXVectors =cpu_to_le32 (dev->max_msix); +aac_adapter_start (dev); }return 0 ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 21/65 perf/core: Don't leak event in the syscall error path
In reply to Sasha LevinFrom: Alexander Shishkin <[email protected]>
[ Upstream commit 201c2f85bd0bc13b712d9c0b3d11251b182e06ae ]
In the error path, event_file not being NULL is used to determine whether the event itself still needs to be free'd, so fix it up to avoid leaking.
--- kernel/events/core.c | 1 + 1 file changed, 1 insertion(+)
kernel/events/core.c +1 -0
@@ -8530,6 +8530,7 @@ SYSCALL_DEFINE5(perf_event_open, f_flags);if (IS_ERR (event_file)) { err =PTR_ERR (event_file); + event_file =NULL ; goto err_context; }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 22/65 usbvision: revert commit 588afcc1
In reply to Sasha LevinFrom: Vladis Dronov <[email protected]>
[ Upstream commit d5468d7afaa9c9e961e150f0455a14a9f4872a98 ]
Commit 588afcc1c0e4 ("[media] usbvision fix overflow of interfaces array")' should be reverted, because:
* "!dev->actconfig->interface[ifnum]" won't catch a case where the value is not NULL but some garbage. This way the system may crash later with GPF.
* "(ifnum >= USB_MAXINTERFACES)" does not cover all the error conditions. "ifnum" should be compared to "dev->actconfig-> desc.bNumInterfaces", i.e. compared to the number of "struct usb_interface" kzalloc()-ed, not to USB_MAXINTERFACES.
* There is a "struct usb_device" leak in this error path, as there is usb_get_dev(), but no usb_put_dev() on this path.
* There is a bug of the same type several lines below with number of endpoints. The code is accessing hard-coded second endpoint ("interface->endpoint[1].desc") which may not exist. It would be great to handle this in the same patch too.
* All the concerns above are resolved by already-accepted commit fa52bd50 ("[media] usbvision: fix crash on detecting device with invalid configuration")
* Mailing list message:
http://www.spinics.net/lists/linux-media/msg94832.html
--- drivers/media/usb/usbvision/usbvision-video.c | 7 ------- 1 file changed, 7 deletions(-)
drivers/media/usb/usbvision/usbvision-video.c +0 -7
@@ -1461,13 +1461,6 @@ static int usbvision_probe(struct usb_interface *intf,printk (KERN_INFO "%s: %s found\n" , __func__, usbvision_device_data[model].model_string); -/* -* this is a security check. -* an exploit using an incorrect bInterfaceNumber is known -*/ -if (ifnum >=USB_MAXINTERFACES || !dev->actconfig->interface[ifnum]) -return -ENODEV ; -if (usbvision_device_data[model].interface >=0 ) interface = &dev->actconfig->interface[usbvision_device_data[model].interface]->altsetting[0 ];else if (ifnum < dev->actconfig->desc.bNumInterfaces)
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 23/65 MIPS: Fix FCSR Cause bit handling for correct SIGFPE issue
In reply to Sasha LevinFrom: "Maciej W. Rozycki" <[email protected]>
[ Upstream commit 5a1aca4469fdccd5b74ba0b4e490173b2b447895 ]
Sanitize FCSR Cause bit handling, following a trail of past attempts:
* commit 4249548454f7 ("MIPS: ptrace: Fix FP context restoration FCSR regression"),
* commit 443c44032a54 ("MIPS: Always clear FCSR cause bits after emulation"),
* commit 64bedffe4968 ("MIPS: Clear [MSA]FPE CSR.Cause after notify_die()"),
* commit b1442d39fac2 ("MIPS: Prevent user from setting FCSR cause bits"),
* commit b54d2901517d ("Properly handle branch delay slots in connection with signals.").
Specifically do not mask these bits out in ptrace(2) processing and send a SIGFPE signal instead whenever a matching pair of an FCSR Cause and Enable bit is seen as execution of an affected context is about to resume. Only then clear Cause bits, and even then do not clear any bits that are set but masked with the respective Enable bits. Adjust Cause bit clearing throughout code likewise, except within the FPU emulator proper where they are set according to IEEE 754 exceptions raised as the operation emulated executed. Do so so that any IEEE 754 exceptions subject to their default handling are recorded like with operations executed by FPU hardware.
Patchwork: https://patchwork.linux-mips.org/patch/14460/
--- arch/mips/include/asm/fpu_emulator.h | 13 +++++ arch/mips/include/asm/switch_to.h | 18 +++++++ arch/mips/kernel/mips-r2-to-r6-emul.c | 10 ++-- arch/mips/kernel/ptrace.c | 7 ++- arch/mips/kernel/traps.c | 72 +++++++++++++++------------ 5 files changed, 78 insertions(+), 42 deletions(-)
arch/mips/include/asm/fpu_emulator.h +13 -0
@@ -66,6 +66,8 @@ extern int do_dsemulret(struct pt_regs *xcp);extern int fpu_emulator_cop1Handler (struct pt_regs *xcp,struct mips_fpu_struct *ctx,int has_fpu,void *__user *fault_addr); +void force_fcr31_sig (unsigned long fcr31,void __user *fault_addr, +struct task_struct *tsk);int process_fpemu_return (int sig,void __user *fault_addr,unsigned long fcr31); int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
@@ -92,4 +94,15 @@ static inline void fpu_emulator_init_fpu(void) set_fpr64(&t->thread.fpu.fpr[i], 0, SIGNALLING_NAN); } +/* +* Mask the FCSR Cause bits according to the Enable bits, observing +* that Unimplemented is always enabled. +*/ +static inline unsigned long mask_fcr31_x (unsigned long fcr31) +{ +return fcr31 & (FPU_CSR_UNI_X | + ((fcr31 &FPU_CSR_ALL_E ) << + (ffs (FPU_CSR_ALL_X ) -ffs (FPU_CSR_ALL_E )))); +} +#endif /* _ASM_FPU_EMULATOR_H */
arch/mips/include/asm/switch_to.h +18 -0
@@ -75,6 +75,22 @@ do { if (cpu_has_rw_llb) { \ } \ }while (0 ) +/* +* Check FCSR for any unmasked exceptions pending set with `ptrace', +* clear them and send a signal. + */ +#define __sanitize_fcr31 (next) \ +do { \ + unsigned long fcr31 = mask_fcr31_x(next->thread.fpu.fcr31); \ + void __user *pc; \ + \ + if (unlikely(fcr31)) { \ + pc = (void __user *)task_pt_regs(next)->cp0_epc; \ + next->thread.fpu.fcr31 &= ~fcr31; \ + force_fcr31_sig(fcr31, pc, next); \ + } \ +} while (0) +/* * For newly created kernel threads switch_to() will return to * ret_from_kernel_thread, newly created user threads to ret_from_fork.
@@ -85,6 +101,8 @@ do { if (cpu_has_rw_llb) { \ do { \ __mips_mt_fpaff_switch_to(prev); \ lose_fpu_inatomic(1, prev); \ + if (tsk_used_math(next)) \ + __sanitize_fcr31(next); \ if (cpu_has_dsp) { \ __save_dsp(prev); \ __restore_dsp(next); \
arch/mips/kernel/mips-r2-to-r6-emul.c +5 -5
@@ -900,7 +900,7 @@ static inline int mipsr2_find_op_func(struct pt_regs *regs, u32 inst,* mipsr2_decoder: Decode and emulate a MIPS R2 instruction * @regs: Process register set * @inst: Instruction to decode and emulate -* @fcr31: Floating Point Control and Status Register returned +* @fcr31: Floating Point Control and Status Register Cause bits returned */ int mipsr2_decoder (struct pt_regs *regs,u32 inst,unsigned long *fcr31) {
@@ -1183,13 +1183,13 @@ int mipsr2_decoder(struct pt_regs *regs, u32 inst, unsigned long *fcr31) err =fpu_emulator_cop1Handler (regs, ¤t->thread.fpu,0 , &fault_addr); - *fcr31 = current->thread.fpu.fcr31;/* -* We can't allow the emulated instruction to leave any of -* the cause bits set in $fcr31. +* We can't allow the emulated instruction to leave any +* enabled Cause bits set in $fcr31. */ - current->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X ; + *fcr31 = res =mask_fcr31_x (current->thread.fpu.fcr31); + current->thread.fpu.fcr31 &= ~res;/* * this is a tricky issue - lose_fpu() uses LL/SC atomics
arch/mips/kernel/ptrace.c +3 -4
@@ -79,16 +79,15 @@ void ptrace_disable(struct task_struct *child) }/* -* Poke at FCSR according to its mask. Don't set the cause bits as -* this is currently not handled correctly in FP context restoration -* and will cause an oops if a corresponding enable bit is set. +* Poke at FCSR according to its mask. Set the Cause bits even +* if a corresponding Enable bit is set. This will be noticed at +* the time the thread is switched to and SIGFPE thrown accordingly. */ static void ptrace_setfcr31 (struct task_struct *child,u32 value) {u32 fcr31;u32 mask; - value &= ~FPU_CSR_ALL_X ; fcr31 = child->thread.fpu.fcr31; mask = boot_cpu_data.fpu_msk31; child->thread.fpu.fcr31 = (value & ~mask) | (fcr31 & mask);
arch/mips/kernel/traps.c +39 -33
118 lines not on this page · raw message
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 24/65 ASoC: ak4613: Enable cache usage to fix crashes on resume
In reply to Sasha LevinFrom: Geert Uytterhoeven <[email protected]>
[ Upstream commit dcd2d1f78664fdc75eadaaf65257834e24383d01 ]
During system resume:
kernel BUG at drivers/base/regmap/regcache.c:347!
...
PC is at regcache_sync+0x1c/0x128
LR is at ak4613_resume+0x28/0x34The ak4613 driver is using a regmap cache sync to restore the configuration of the chip on resume but does not actually define a register cache which means that the resume is never going to work and we trigger asserts in regmap. Fix this by enabling caching.
Based on commit d3030d11961a8c10 ("ASoC: ak4642: Enable cache usage to fix crashes on resume") by Mark Brown <[email protected]>.
--- sound/soc/codecs/ak4613.c | 1 + 1 file changed, 1 insertion(+)
sound/soc/codecs/ak4613.c +1 -0
@@ -143,6 +143,7 @@ static const struct regmap_config ak4613_regmap_cfg = { .max_register = 0x16, .reg_defaults = ak4613_reg, .num_reg_defaults = ARRAY_SIZE(ak4613_reg), + .cache_type = REGCACHE_RBTREE, };static const struct of_device_id ak4613_of_match[] = {
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 25/65 ASoC: wm8940: Enable cache usage to fix crashes on resume
In reply to Sasha LevinFrom: Geert Uytterhoeven <[email protected]>
[ Upstream commit 50c7a0ef2d97e56c7ce2f1ea5fe1d8e25aadc1bb ]
The wm8940 driver is using a regmap cache sync to restore the configuration of the chip when switching from OFF to STANDBY, but does not actually define a register cache which means that the restore is never going to work and we trigger asserts in regmap. Fix this by enabling caching.
Based on commit d3030d11961a8c10 ("ASoC: ak4642: Enable cache usage to fix crashes on resume") by Mark Brown <[email protected]>.
--- sound/soc/codecs/wm8940.c | 1 + 1 file changed, 1 insertion(+)
sound/soc/codecs/wm8940.c +1 -0
@@ -743,6 +743,7 @@ static const struct regmap_config wm8940_regmap = { .max_register = WM8940_MONOMIX, .reg_defaults = wm8940_reg_defaults, .num_reg_defaults = ARRAY_SIZE(wm8940_reg_defaults), + .cache_type = REGCACHE_RBTREE, .readable_reg = wm8940_readable_register, .volatile_reg = wm8940_volatile_register,
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 26/65 CIFS: handle guest access errors to Windows shares
In reply to Sasha LevinFrom: Mark Syms <[email protected]>
[ Upstream commit 40920c2bb119fd49ba03e2f97a172171781be442 ]
Commit 1a967d6c9b39c226be1b45f13acd4d8a5ab3dc44 ("correctly to anonymous authentication for the NTLM(v2) authentication") introduces a regression in handling errors related to attempting a guest connection to a Windows share which requires authentication. This should result in a permission denied error but actually causes the kernel module to enter a never-ending loop trying to follow a DFS referal which doesn't exist.
The base cause of this is the failure now occurs later in the process during tree connect and not at the session setup setup and all errors in tree connect are interpreted as needing to follow the DFS paths which isn't in this case correct. So, check the returned error against EACCES and fail if this is returned error.
Feedback from Aurelien:
PS> net user guest /activate:no
PS> mkdir C:\guestshare
PS> icacls C:\guestshare /grant 'Everyone:(OI)(CI)F'
PS> new-smbshare -name guestshare -path C:\guestshare -fullaccess Everyone
I've tested v3.10, v4.4, master, master+your patch using default options (empty or no user "NU") and user=abc (U).
NT_LOGON_FAILURE in session setup: LF
This is what you seem to have in 3.10.
NT_ACCESS_DENIED in tree connect to the share: AD This is what you get before your infinite loop.
| NU U
--------------------------------
3.10 | LF LF
4.4 | LF LF
master | AD LF
master+patch | AD LF
No infinite DFS loop :(
All these issues result in mount failing very fast with permission denied.
I guess it could be from either the Windows version or the share/folder ACL. A deeper analysis of the packets might reveal more.
In any case I did not notice any issues for on a basic DFS setup with the patch so I don't think it introduced any regressions, which is probably all that matters. It still bothers me a little I couldn't hit the bug.
I've included kernel output w/ debugging output and network capture of my tests if anyone want to have a look at it. (master+patch = ml-guestfix).
--- fs/cifs/connect.c | 3 +++ 1 file changed, 3 insertions(+)
fs/cifs/connect.c +3 -0
@@ -3674,6 +3674,9 @@ cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info)if (IS_ERR (tcon)) { rc =PTR_ERR (tcon); tcon =NULL ; +if (rc == -EACCES ) + goto mount_fail_check; + goto remote_path_check; }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 27/65 arm64: Fix potential race with hardware DBM in ptep_set_access_flags()
In reply to Sasha LevinFrom: Catalin Marinas <[email protected]>
[ Upstream commit 6d332747fa5f0a6843b56b5b129168ba909336d1 ]
In a system with DBM (dirty bit management) capable agents there is a possible race between a CPU executing ptep_set_access_flags() (maybe non-DBM capable) and a hardware update of the dirty state (clearing of PTE_RDONLY). The scenario:
a) the pte is writable (PTE_WRITE set), clean (PTE_RDONLY set) and old (PTE_AF clear)
b) ptep_set_access_flags() is called as a result of a read access and it needs to set the pte to writable, clean and young (PTE_AF set)
c) a DBM-capable agent, as a result of a different write access, is marking the entry as young (setting PTE_AF) and dirty (clearing PTE_RDONLY)
The current ptep_set_access_flags() implementation would set the PTE_RDONLY bit in the resulting value overriding the DBM update and losing the dirty state.
This patch fixes such race by setting PTE_RDONLY to the most permissive (lowest value) of the current entry and the new one.
--- arch/arm64/mm/fault.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)
arch/arm64/mm/fault.c +8 -7
@@ -107,26 +107,27 @@ int ptep_set_access_flags(struct vm_area_struct *vma,/* only preserve the access flags and write permission */ pte_val (entry) &=PTE_AF |PTE_WRITE |PTE_DIRTY ; -/* -* PTE_RDONLY is cleared by default in the asm below, so set it in -* back if necessary (read-only or clean PTE). -*/ +/* set PTE_RDONLY if actual read-only or clean PTE */ if (!pte_write (entry) || !pte_sw_dirty (entry))pte_val (entry) |=PTE_RDONLY ;/* * Setting the flags must be done atomically to avoid racing with the -* hardware update of the access/dirty state. +* hardware update of the access/dirty state. The PTE_RDONLY bit must +* be set to the most permissive (lowest value) of *ptep and entry +* (calculated as: a & b == ~(~a | ~b)). */ +pte_val (entry) ^=PTE_RDONLY ; asmvolatile ("// ptep_set_access_flags\n" " prfm pstl1strm, %2\n" "1: ldxr %0, %2\n" -" and %0, %0, %3 // clear PTE_RDONLY\n" +" eor %0, %0, %3 // negate PTE_RDONLY in *ptep\n" " orr %0, %0, %4 // set flags\n" +" eor %0, %0, %3 // negate final PTE_RDONLY\n" " stxr %w1, %0, %2\n" " cbnz %w1, 1b\n" :"=&r" (old_pteval),"=&r" (tmp),"+Q" (pte_val (*ptep)) - :"L" (~PTE_RDONLY ),"r" (pte_val (entry))); + :"L" (PTE_RDONLY ),"r" (pte_val (entry)));flush_tlb_fix_spurious_fault (vma, address);return 1 ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 28/65 xfrm: Clear sk_dst_cache when applying per-socket policy.
In reply to Sasha LevinFrom: Jonathan Basseri <[email protected]>
[ Upstream commit 2b06cdf3e688b98fcc9945873b5d42792bd4eee0 ]
If a socket has a valid dst cache, then xfrm_lookup_route will get skipped. However, the cache is not invalidated when applying policy to a socket (i.e. IPV6_XFRM_POLICY). The result is that new policies are sometimes ignored on those sockets. (Note: This was broken for IPv4 and IPv6 at different times.)
This can be demonstrated like so,
1. Create UDP socket.
2. connect() the socket.
3. Apply an outbound XFRM policy to the socket. (setsockopt)
4. send() data on the socket.
Packets will continue to be sent in the clear instead of matching an xfrm or returning a no-match error (EAGAIN). This affects calls to send() and not sendto().
Invalidating the sk_dst_cache is necessary to correctly apply xfrm policies. Since we do this in xfrm_user_policy(), the sk_lock was already acquired in either do_ip_setsockopt() or do_ipv6_setsockopt(), and we may call __sk_dst_reset().
Performance impact should be negligible, since this code is only called when changing xfrm policy, and only affects the socket in question.
Tested: https://android-review.googlesource.com/517555
Tested: https://android-review.googlesource.com/418659
--- net/xfrm/xfrm_state.c | 1 + 1 file changed, 1 insertion(+)
net/xfrm/xfrm_state.c +1 -0
@@ -1884,6 +1884,7 @@ int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlenif (err >=0 ) {xfrm_sk_policy_insert (sk, err, pol);xfrm_pol_put (pol); +__sk_dst_reset (sk); err =0 ; }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 29/65 scsi: Add STARGET_CREATED_REMOVE state to scsi_target_state
In reply to Sasha LevinFrom: "Ewan D. Milne" <[email protected]>
[ Upstream commit f9279c968c257ee39b0d7bd2571a4d231a67bcc1 ]
The addition of the STARGET_REMOVE state had the side effect of introducing a race condition that can cause a crash.
scsi_target_reap_ref_release() checks the starget->state to see if it still in STARGET_CREATED, and if so, skips calling transport_remove_device() and device_del(), because the starget->state is only set to STARGET_RUNNING after scsi_target_add() has called device_add() and transport_add_device().
However, if an rport loss occurs while a target is being scanned, it can happen that scsi_remove_target() will be called while the starget is still in the STARGET_CREATED state. In this case, the starget->state will be set to STARGET_REMOVE, and as a result, scsi_target_reap_ref_release() will take the wrong path. The end result is a panic:
[ 1255.356653] Oops: 0000 [#1] SMP [ 1255.360154] Modules linked in: x86_pkg_temp_thermal kvm_intel kvm irqbypass crc32c_intel ghash_clmulni_i [ 1255.393234] CPU: 5 PID: 149 Comm: kworker/u96:4 Tainted: G W 4.11.0+ #8 [ 1255.401879] Hardware name: Dell Inc. PowerEdge R320/08VT7V, BIOS 2.0.22 11/19/2013 [ 1255.410327] Workqueue: scsi_wq_6 fc_scsi_scan_rport [scsi_transport_fc] [ 1255.417720] task: ffff88060ca8c8c0 task.stack: ffffc900048a8000 [ 1255.424331] RIP: 0010:kernfs_find_ns+0x13/0xc0 [ 1255.429287] RSP: 0018:ffffc900048abbf0 EFLAGS: 00010246 [ 1255.435123] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000 [ 1255.443083] RDX: 0000000000000000 RSI: ffffffff8188d659 RDI: 0000000000000000 [ 1255.451043] RBP: ffffc900048abc10 R08: 0000000000000000 R09: 0000012433fe0025 [ 1255.459005] R10: 0000000025e5a4b5 R11: 0000000025e5a4b5 R12: ffffffff8188d659 [ 1255.466972] R13: 0000000000000000 R14: ffff8805f55e5088 R15: 0000000000000000 [ 1255.474931] FS: 0000000000000000(0000) GS:ffff880616b40000(0000) knlGS:0000000000000000 [ 1255.483959] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 1255.490370] CR2: 0000000000000068 CR3: 0000000001c09000 CR4: 00000000000406e0 [ 1255.498332] Call Trace: [ 1255.501058] kernfs_find_and_get_ns+0x31/0x60 [ 1255.505916] sysfs_unmerge_group+0x1d/0x60 [ 1255.510498] dpm_sysfs_remove+0x22/0x60 [ 1255.514783] device_del+0xf4/0x2e0 [ 1255.518577] ? device_remove_file+0x19/0x20 [ 1255.523241] attribute_container_class_device_del+0x1a/0x20 [ 1255.529457] transport_remove_classdev+0x4e/0x60 [ 1255.534607] ? transport_add_class_device+0x40/0x40 [ 1255.540046] attribute_container_device_trigger+0xb0/0xc0 [ 1255.546069] transport_remove_device+0x15/0x20 [ 1255.551025] scsi_target_reap_ref_release+0x25/0x40 [ 1255.556467] scsi_target_reap+0x2e/0x40 [ 1255.560744] __scsi_scan_target+0xaa/0x5b0 [ 1255.565312] scsi_scan_target+0xec/0x100 [ 1255.569689] fc_scsi_scan_rport+0xb1/0xc0 [scsi_transport_fc] [ 1255.576099] process_one_work+0x14b/0x390 [ 1255.580569] worker_thread+0x4b/0x390 [ 1255.584651] kthread+0x109/0x140 [ 1255.588251] ? rescuer_thread+0x330/0x330 [ 1255.592730] ? kthread_park+0x60/0x60 [ 1255.596815] ret_from_fork+0x29/0x40 [ 1255.600801] Code: 24 08 48 83 42 40 01 5b 41 5c 5d c3 66 66 66 2e 0f 1f 84 00 00 00 00 00 66 66 66 66 90 [ 1255.621876] RIP: kernfs_find_ns+0x13/0xc0 RSP: ffffc900048abbf0 [ 1255.628479] CR2: 0000000000000068 [ 1255.632756] ---[ end trace 34a69ba0477d036f ]---
Fix this by adding another scsi_target state STARGET_CREATED_REMOVE to distinguish this case.
--- drivers/scsi/scsi_scan.c | 5 +++-- drivers/scsi/scsi_sysfs.c | 8 ++++++-- include/scsi/scsi_device.h | 1 + 3 files changed, 10 insertions(+), 4 deletions(-)
drivers/scsi/scsi_scan.c +3 -2
@@ -381,11 +381,12 @@ static void scsi_target_reap_ref_release(struct kref *kref) = container_of(kref, struct scsi_target, reap_ref);/* -* if we get here and the target is still in the CREATED state that +* if we get here and the target is still in a CREATED state that * means it was allocated but never made visible (because a scan * turned up no LUNs), so don't call device_del() on it. */ -if (starget->state !=STARGET_CREATED ) { +if ((starget->state !=STARGET_CREATED ) && + (starget->state !=STARGET_CREATED_REMOVE )) {transport_remove_device (&starget->dev);device_del (&starget->dev); }
drivers/scsi/scsi_sysfs.c +6 -2
@@ -1212,11 +1212,15 @@ void scsi_remove_target(struct device *dev)spin_lock_irqsave (shost->host_lock, flags);list_for_each_entry (starget, &shost->__targets, siblings) {if (starget->state ==STARGET_DEL || - starget->state ==STARGET_REMOVE ) + starget->state ==STARGET_REMOVE || + starget->state ==STARGET_CREATED_REMOVE )continue ;if (starget->dev.parent == dev || &starget->dev == dev) {kref_get (&starget->reap_ref); - starget->state =STARGET_REMOVE ; +if (starget->state ==STARGET_CREATED ) + starget->state =STARGET_CREATED_REMOVE ; +else + starget->state =STARGET_REMOVE ;spin_unlock_irqrestore (shost->host_lock, flags);__scsi_remove_target (starget);scsi_target_reap (starget);
include/scsi/scsi_device.h +1 -0
@@ -240,6 +240,7 @@ enum scsi_target_state {STARGET_CREATED =1 ,STARGET_RUNNING ,STARGET_REMOVE , +STARGET_CREATED_REMOVE , STARGET_DEL, };
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 30/65 sparc/pci: Refactor dev_archdata initialization into pci_init_dev_archdata
In reply to Sasha LevinFrom: Sowmini Varadhan <[email protected]>
[ Upstream commit 9a78d4fc28904785ffe4c2d361e25b251b479704 ]
The function pcibios_add_device() added by commit d0c31e020057 ("sparc/PCI: Fix for panic while enabling SR-IOV") initializes the dev_archdata by doing a memcpy from the PF. This has the problem that it erroneously copies the OF device without explicitly refcounting it.
As David Miller pointed out: "Generally speaking we don't really support hot-plug for OF probed devices, but if we did all of the device tree pointers have to be refcounted properly."
To fix this error, and also avoid code duplication, this patch creates a new helper function, pci_init_dev_archdata(), that initializes the fields in dev_archdata, and can be invoked by callers after they have taken the needed refcounts
--- arch/sparc/kernel/pci.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-)
arch/sparc/kernel/pci.c +21 -8
@@ -245,6 +245,18 @@ static void pci_parse_of_addrs(struct platform_device *op, } } +static void pci_init_dev_archdata (struct dev_archdata *sd,void *iommu, +void *stc,void *host_controller, +struct platform_device *op, +int numa_node) +{ + sd->iommu = iommu; + sd->stc = stc; + sd->host_controller = host_controller; + sd->op = op; + sd->numa_node = numa_node; +} +static struct pci_dev *of_create_pci_dev (struct pci_pbm_info *pbm,struct device_node *node,struct pci_bus *bus,int devfn)
@@ -259,13 +271,10 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,if (!dev)return NULL ; + op =of_find_device_by_node (node); sd = &dev->dev.archdata; - sd->iommu = pbm->iommu; - sd->stc = &pbm->stc; - sd->host_controller = pbm; - sd->op = op =of_find_device_by_node (node); - sd->numa_node = pbm->numa_node; - +pci_init_dev_archdata (sd, pbm->iommu, &pbm->stc, pbm, op, + pbm->numa_node); sd = &op->dev.archdata; sd->iommu = pbm->iommu; sd->stc = &pbm->stc;
@@ -1003,9 +1012,13 @@ int pcibios_add_device(struct pci_dev *dev)* Copy dev_archdata from PF to VF */ if (dev->is_virtfn) { +struct dev_archdata *psd; + pdev = dev->physfn; -memcpy (&dev->dev.archdata, &pdev->dev.archdata, -sizeof (struct dev_archdata )); + psd = &pdev->dev.archdata; +pci_init_dev_archdata (&dev->dev.archdata, psd->iommu, + psd->stc, psd->host_controller,NULL , + psd->numa_node); }return 0 ; }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 31/65 sch_red: update backlog as well
In reply to Sasha LevinFrom: WANG Cong <[email protected]>
[ Upstream commit d7f4f332f082c4d4ba53582f902ed6b44fd6f45e ]
--- net/sched/sch_red.c | 4 ++++ 1 file changed, 4 insertions(+)
net/sched/sch_red.c +4 -0
@@ -97,6 +97,7 @@ static int red_enqueue(struct sk_buff *skb, struct Qdisc *sch) ret =qdisc_enqueue (skb, child);if (likely (ret ==NET_XMIT_SUCCESS )) { +qdisc_qstats_backlog_inc (sch, skb); sch->q.qlen++; }else if (net_xmit_drop_count (ret)) { q->stats.pdrop++;
@@ -118,6 +119,7 @@ static struct sk_buff *red_dequeue(struct Qdisc *sch) skb = child->dequeue (child);if (skb) {qdisc_bstats_update (sch, skb); +qdisc_qstats_backlog_dec (sch, skb); sch->q.qlen--; }else {if (!red_is_idling (&q->vars))
@@ -143,6 +145,7 @@ static unsigned int red_drop(struct Qdisc *sch)if (child->ops->drop && (len = child->ops->drop (child)) >0 ) { q->stats.other++;qdisc_qstats_drop (sch); + sch->qstats.backlog -= len; sch->q.qlen--;return len; }
@@ -158,6 +161,7 @@ static void red_reset(struct Qdisc *sch)struct red_sched_data *q =qdisc_priv (sch);qdisc_reset (q->qdisc); + sch->qstats.backlog =0 ; sch->q.qlen =0 ;red_restart (&q->vars); }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 32/65 usb-storage: fix bogus hardware error messages for ATA pass-thru devices
In reply to Sasha LevinFrom: Alan Stern <[email protected]>
[ Upstream commit a4fd4a724d6c30ad671046d83be2e9be2f11d275 ]
Ever since commit a621bac3044e ("scsi_lib: correctly retry failed zero length REQ_TYPE_FS commands"), people have been getting bogus error messages for USB disk drives using ATA pass-thru. For example:
[ 1344.880193] sd 6:0:0:0: [sdb] Attached SCSI disk [ 1345.069152] sd 6:0:0:0: [sdb] tag#0 FAILED Result: hostbyte=DID_ERROR driverbyte=DRIVER_SENSE [ 1345.069159] sd 6:0:0:0: [sdb] tag#0 Sense Key : Hardware Error [current] [descriptor] [ 1345.069162] sd 6:0:0:0: [sdb] tag#0 Add. Sense: No additional sense information [ 1345.069168] sd 6:0:0:0: [sdb] tag#0 CDB: ATA command pass through(16) 85 06 20 00 00 00 00 00 00 00 00 00 00 00 e5 00 [ 1345.172252] sd 6:0:0:0: [sdb] tag#0 FAILED Result: hostbyte=DID_ERROR driverbyte=DRIVER_SENSE [ 1345.172258] sd 6:0:0:0: [sdb] tag#0 Sense Key : Hardware Error [current] [descriptor] [ 1345.172261] sd 6:0:0:0: [sdb] tag#0 Add. Sense: No additional sense information [ 1345.172266] sd 6:0:0:0: [sdb] tag#0 CDB: ATA command pass through(12)/Blank a1 06 20 da 00 00 4f c2 00 b0 00 00
These messages can be quite annoying, because programs like udisks2 provoke them every 10 minutes or so. Other programs can also have this effect, such as those in smartmontools.
I don't fully understand how that commit induced the SCSI core to log these error messages, but the underlying cause for them is code added to usb-storage by commit f1a0743bc0e7 ("USB: storage: When a device returns no sense data, call it a Hardware Error"). At the time it was necessary to do this, in order to prevent an infinite retry loop with some not-so-great mass storage devices.
However, the ATA pass-thru protocol uses SCSI sense data to return command status values, and some devices always report Check Condition status for ATA pass-thru commands to ensure that the host retrieves the sense data, even if the command succeeded. This violates the USB mass-storage protocol (Check Condition status is supposed to mean the command failed), but we can't help that.
This patch attempts to mitigate the problem of these bogus error reports by changing usb-storage. The HARDWARE ERROR sense key will be inserted only for commands that aren't ATA pass-thru.
Thanks to Ewan Milne for pointing out that this mechanism was present in usb-storage. 8 years after writing it, I had completely forgotten its existence.
Ref: https://bugzilla.redhat.com/show_bug.cgi?id=1351305
--- drivers/usb/storage/transport.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
drivers/usb/storage/transport.c +13 -1
@@ -808,12 +808,24 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)if (result ==USB_STOR_TRANSPORT_GOOD ) { srb->result =SAM_STAT_GOOD ; srb->sense_buffer[0 ] =0x0 ; + } + +/* +* ATA-passthru commands use sense data to report +* the command completion status, and often devices +* return Check Condition status when nothing is +* wrong. +*/ +else if (srb->cmnd[0 ] ==ATA_16 || + srb->cmnd[0 ] ==ATA_12 ) { +/* leave the data alone */ + }/* If there was a problem, report an unspecified * hardware error to prevent the higher layers from * entering an infinite retry loop. */ - }else { +else { srb->result =DID_ERROR <<16 ;if ((sshdr.response_code &0x72 ) ==0x72 ) srb->sense_buffer[1 ] =HARDWARE_ERROR ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 33/65 bpf: generally move prog destruction to RCU deferral
In reply to Sasha LevinFrom: Daniel Borkmann <[email protected]>
[ Upstream commit 1aacde3d22c42281236155c1ef6d7a5aa32a826b ]
Jann Horn reported following analysis that could potentially result in a very hard to trigger (if not impossible) UAF race, to quote his event timeline:
- Set up a process with threads T1, T2 and T3
- Let T1 set up a socket filter F1 that invokes another filter F2 through a BPF map [tail call]
- Let T1 trigger the socket filter via a unix domain socket write, don't wait for completion
- Let T2 call PERF_EVENT_IOC_SET_BPF with F2, don't wait for completion
- Now T2 should be behind bpf_prog_get(), but before bpf_prog_put()
- Let T3 close the file descriptor for F2, dropping the reference count of F2 to 2
- At this point, T1 should have looked up F2 from the map, but not finished executing it
- Let T3 remove F2 from the BPF map, dropping the reference count of F2 to 1
- Now T2 should call bpf_prog_put() (wrong BPF program type), dropping the reference count of F2 to 0 and scheduling bpf_prog_free_deferred() via schedule_work()
- At this point, the BPF program could be freed
- BPF execution is still running in a freed BPF program
While at PERF_EVENT_IOC_SET_BPF time it's only guaranteed that the perf event fd we're doing the syscall on doesn't disappear from underneath us for whole syscall time, it may not be the case for the bpf fd used as an argument only after we did the put. It needs to be a valid fd pointing to a BPF program at the time of the call to make the bpf_prog_get() and while T2 gets preempted, F2 must have dropped reference to 1 on the other CPU. The fput() from the close() in T3 should also add additionally delay to the reference drop via exit_task_work() when bpf_prog_release() gets called as well as scheduling bpf_prog_free_deferred().
That said, it makes nevertheless sense to move the BPF prog destruction generally after RCU grace period to guarantee that such scenario above, but also others as recently fixed in ceb56070359b ("bpf, perf: delay release of BPF prog after grace period") with regards to tail calls won't happen. Integrating bpf_prog_free_deferred() directly into the RCU callback is not allowed since the invocation might happen from either softirq or process context, so we're not permitted to block. Reviewing all bpf_prog_put() invocations from eBPF side (note, cBPF -> eBPF progs don't use this for their destruction) with call_rcu() look good to me.
Since we don't know whether at the time of attaching the program, we're already part of a tail call map, we need to use RCU variant. However, due to this, there won't be severely more stress on the RCU callback queue:
situations with above bpf_prog_get() and bpf_prog_put() combo in practice normally won't lead to releases, but even if they would, enough effort/ cycles have to be put into loading a BPF program into the kernel already.
--- include/linux/bpf.h | 5 ----- kernel/bpf/arraymap.c | 4 +--- kernel/bpf/syscall.c | 13 +++---------- kernel/events/core.c | 2 +- 4 files changed, 5 insertions(+), 19 deletions(-)
include/linux/bpf.h +0 -5
@@ -177,7 +177,6 @@ void bpf_register_map_type(struct bpf_map_type_list *tl);struct bpf_prog *bpf_prog_get (u32 ufd);struct bpf_prog *bpf_prog_inc (struct bpf_prog *prog);void bpf_prog_put (struct bpf_prog *prog); -void bpf_prog_put_rcu (struct bpf_prog *prog);struct bpf_map *bpf_map_get_with_uref (u32 ufd);struct bpf_map *__bpf_map_get (struct fd f);
@@ -208,10 +207,6 @@ static inline struct bpf_prog *bpf_prog_get(u32 ufd)static inline void bpf_prog_put (struct bpf_prog *prog) { } - -static inline void bpf_prog_put_rcu (struct bpf_prog *prog) -{ -}#endif /* CONFIG_BPF_SYSCALL */ /* verifier prototypes for helper functions called from eBPF programs */
kernel/bpf/arraymap.c +1 -3
@@ -270,9 +270,7 @@ static void *prog_fd_array_get_ptr(struct bpf_map *map, int fd)static void prog_fd_array_put_ptr (void *ptr) { -struct bpf_prog *prog = ptr; - -bpf_prog_put_rcu (prog); +bpf_prog_put (ptr); }/* decrement refcnt of all bpf_progs that are stored in this map */
kernel/bpf/syscall.c +3 -10
@@ -487,7 +487,7 @@ static void bpf_prog_uncharge_memlock(struct bpf_prog *prog)free_uid (user); } -static void __prog_put_common (struct rcu_head *rcu) +static void __bpf_prog_put_rcu (struct rcu_head *rcu) { struct bpf_prog_aux *aux = container_of(rcu, struct bpf_prog_aux, rcu);
@@ -496,17 +496,10 @@ static void __prog_put_common(struct rcu_head *rcu)bpf_prog_free (aux->prog); } -/* version of bpf_prog_put() that is called after a grace period */ -void bpf_prog_put_rcu (struct bpf_prog *prog) -{ -if (atomic_dec_and_test (&prog->aux->refcnt)) -call_rcu (&prog->aux->rcu, __prog_put_common); -} -void bpf_prog_put (struct bpf_prog *prog) {if (atomic_dec_and_test (&prog->aux->refcnt)) -__prog_put_common (&prog->aux->rcu); +call_rcu (&prog->aux->rcu, __bpf_prog_put_rcu); }EXPORT_SYMBOL_GPL (bpf_prog_put);
@@ -514,7 +507,7 @@ static int bpf_prog_release(struct inode *inode, struct file *filp) {struct bpf_prog *prog = filp->private_data; -bpf_prog_put_rcu (prog); +bpf_prog_put (prog);return 0 ; }
kernel/events/core.c +1 -1
@@ -7139,7 +7139,7 @@ static void perf_event_free_bpf_prog(struct perf_event *event) prog = event->tp_event->prog;if (prog && event->tp_event->bpf_prog_owner == event) { event->tp_event->prog =NULL ; -bpf_prog_put_rcu (prog); +bpf_prog_put (prog); } }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 34/65 drm/nouveau/fbcon: fix oops without fbdev emulation
In reply to Sasha LevinFrom: Pavel Roskin <[email protected]>
[ Upstream commit 4813766325374af6ed0b66879ba6a0bbb05c83b6 ]
This is similar to an earlier commit 52dfcc5ccfbb ("drm/nouveau: fix for disabled fbdev emulation"), but protects all occurrences of helper.fbdev in the source.
I see oops in nouveau_fbcon_accel_save_disable() called from nouveau_fbcon_set_suspend_work() on Linux 3.13 when CONFIG_DRM_FBDEV_EMULATION option is disabled.
--- drivers/gpu/drm/nouveau/nouveau_fbcon.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/gpu/drm/nouveau/nouveau_fbcon.c +4 -3
@@ -235,7 +235,7 @@ void nouveau_fbcon_accel_save_disable(struct drm_device *dev) {struct nouveau_drm *drm =nouveau_drm (dev); -if (drm->fbcon) { +if (drm->fbcon && drm->fbcon->helper.fbdev) { drm->fbcon->saved_flags = drm->fbcon->helper.fbdev->flags; drm->fbcon->helper.fbdev->flags |=FBINFO_HWACCEL_DISABLED ; }
@@ -245,7 +245,7 @@ void nouveau_fbcon_accel_restore(struct drm_device *dev) {struct nouveau_drm *drm =nouveau_drm (dev); -if (drm->fbcon) { +if (drm->fbcon && drm->fbcon->helper.fbdev) { drm->fbcon->helper.fbdev->flags = drm->fbcon->saved_flags; } }
@@ -257,7 +257,8 @@ nouveau_fbcon_accel_fini(struct drm_device *dev)struct nouveau_fbdev *fbcon = drm->fbcon;if (fbcon && drm->channel) {console_lock (); - fbcon->helper.fbdev->flags |=FBINFO_HWACCEL_DISABLED ; +if (fbcon->helper.fbdev) + fbcon->helper.fbdev->flags |=FBINFO_HWACCEL_DISABLED ;console_unlock ();nouveau_channel_idle (drm->channel);nvif_object_fini (&fbcon->twod);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 35/65 fuse: Dont call set_page_dirty_lock() for ITER_BVEC pages for async_dio
In reply to Sasha LevinFrom: Ashish Samant <[email protected]>
[ Upstream commit 61c12b49e1c9c77d7a1bcc161de540d0fd21cf0c ]
Commit 8fba54aebbdf ("fuse: direct-io: don't dirty ITER_BVEC pages") fixes the ITER_BVEC page deadlock for direct io in fuse by checking in fuse_direct_io(), whether the page is a bvec page or not, before locking it. However, this check is missed when the "async_dio" mount option is enabled. In this case, set_page_dirty_lock() is called from the req->end callback in request_end(), when the fuse thread is returning from userspace to respond to the read request. This will cause the same deadlock because the bvec condition is not checked in this path.
Here is the stack of the deadlocked thread, while returning from userspace:
[13706.656686] INFO: task glusterfs:3006 blocked for more than 120 seconds. [13706.657808] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [13706.658788] glusterfs D ffffffff816c80f0 0 3006 1 0x00000080 [13706.658797] ffff8800d6713a58 0000000000000086 ffff8800d9ad7000 ffff8800d9ad5400 [13706.658799] ffff88011ffd5cc0 ffff8800d6710008 ffff88011fd176c0 7fffffffffffffff [13706.658801] 0000000000000002 ffffffff816c80f0 ffff8800d6713a78 ffffffff816c790e [13706.658803] Call Trace: [13706.658809] [<ffffffff816c80f0>] ? bit_wait_io_timeout+0x80/0x80 [13706.658811] [<ffffffff816c790e>] schedule+0x3e/0x90 [13706.658813] [<ffffffff816ca7e5>] schedule_timeout+0x1b5/0x210 [13706.658816] [<ffffffff81073ffb>] ? gup_pud_range+0x1db/0x1f0 [13706.658817] [<ffffffff810668fe>] ? kvm_clock_read+0x1e/0x20 [13706.658819] [<ffffffff81066909>] ? kvm_clock_get_cycles+0x9/0x10 [13706.658822] [<ffffffff810f5792>] ? ktime_get+0x52/0xc0 [13706.658824] [<ffffffff816c6f04>] io_schedule_timeout+0xa4/0x110 [13706.658826] [<ffffffff816c8126>] bit_wait_io+0x36/0x50 [13706.658828] [<ffffffff816c7d06>] __wait_on_bit_lock+0x76/0xb0 [13706.658831] [<ffffffffa0545636>] ? lock_request+0x46/0x70 [fuse] [13706.658834] [<ffffffff8118800a>] __lock_page+0xaa/0xb0 [13706.658836] [<ffffffff810c8500>] ? wake_atomic_t_function+0x40/0x40 [13706.658838] [<ffffffff81194d08>] set_page_dirty_lock+0x58/0x60 [13706.658841] [<ffffffffa054d968>] fuse_release_user_pages+0x58/0x70 [fuse] [13706.658844] [<ffffffffa0551430>] ? fuse_aio_complete+0x190/0x190 [fuse] [13706.658847] [<ffffffffa0551459>] fuse_aio_complete_req+0x29/0x90 [fuse] [13706.658849] [<ffffffffa05471e9>] request_end+0xd9/0x190 [fuse] [13706.658852] [<ffffffffa0549126>] fuse_dev_do_write+0x336/0x490 [fuse] [13706.658854] [<ffffffffa054963e>] fuse_dev_write+0x6e/0xa0 [fuse] [13706.658857] [<ffffffff812a9ef3>] ? security_file_permission+0x23/0x90 [13706.658859] [<ffffffff81205300>] do_iter_readv_writev+0x60/0x90 [13706.658862] [<ffffffffa05495d0>] ? fuse_dev_splice_write+0x350/0x350 [fuse] [13706.658863] [<ffffffff812062a1>] do_readv_writev+0x171/0x1f0 [13706.658866] [<ffffffff810b3d00>] ? try_to_wake_up+0x210/0x210 [13706.658868] [<ffffffff81206361>] vfs_writev+0x41/0x50 [13706.658870] [<ffffffff81206496>] SyS_writev+0x56/0xf0 [13706.658872] [<ffffffff810257a1>] ? syscall_trace_leave+0xf1/0x160 [13706.658874] [<ffffffff816cbb2e>] system_call_fastpath+0x12/0x71
Fix this by making should_dirty a fuse_io_priv parameter that can be checked in fuse_aio_complete_req().
--- fs/fuse/file.c | 6 +++--- fs/fuse/fuse_i.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-)
fs/fuse/file.c +3 -3
@@ -625,7 +625,7 @@ static void fuse_aio_complete_req(struct fuse_conn *fc, struct fuse_req *req)struct fuse_io_priv *io = req->io;ssize_t pos =-1 ; -fuse_release_user_pages (req, !io->write); +fuse_release_user_pages (req, io->should_dirty);if (io->write) {if (req->misc.write.in.size != req->misc.write.out.size)
@@ -1333,7 +1333,6 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter, loff_t *ppos, int flags) { int write = flags & FUSE_DIO_WRITE; -bool should_dirty = !write &&iter_is_iovec (iter);int cuse = flags &FUSE_DIO_CUSE ;struct file *file = io->file;struct inode *inode = file->f_mapping->host;
@@ -1362,6 +1361,7 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter,mutex_unlock (&inode->i_mutex); } + io->should_dirty = !write &&iter_is_iovec (iter);while (count) {size_t nres;fl_owner_t owner = current->files;
@@ -1378,7 +1378,7 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter, nres =fuse_send_read (req, io, pos, nbytes, owner);if (!io->async) -fuse_release_user_pages (req, should_dirty); +fuse_release_user_pages (req, io->should_dirty);if (req->out.h.error) {if (!res) res = req->out.h.error;
fs/fuse/fuse_i.h +1 -0
@@ -252,6 +252,7 @@ struct fuse_io_priv {size_t size;__u64 offset;bool write; +bool should_dirty;int err;struct kiocb *iocb;struct file *file;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 36/65 ixgbevf: Fix handling of NAPI budget when multiple queues are enabled per vector
In reply to Sasha LevinFrom: William Dauchy <[email protected]>
[ Upstream commit d0f71afffa1c3d5a36a4a278f1dbbd2643176dc3 ]
This is the same patch as for ixgbe but applied differently according to busy polling. See commit 5d6002b7b822c74 ("ixgbe: Fix handling of NAPI budget when multiple queues are enabled per vector")
--- drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +2 -0
@@ -1014,6 +1014,8 @@ static int ixgbevf_poll(struct napi_struct *napi, int budget)ixgbevf_for_each_ring (ring, q_vector->tx) clean_complete &=ixgbevf_clean_tx_irq (q_vector, ring); +if (budget <=0 ) +return budget;#ifdef CONFIG_NET_RX_BUSY_POLL if (!ixgbevf_qv_lock_napi (q_vector))return budget;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 37/65 net/mlx5e: Fix LRO modify
In reply to Sasha LevinFrom: Tariq Toukan <[email protected]>
[ Upstream commit ab0394fe2c258fdb5086c51a251b28f8ee7ab35c ]
Ethtool LRO enable/disable is broken, as of today we only modify TCP TIRs in order to apply the requested configuration.
Hardware requires that all TIRs pointing to the same RQ should share the same LRO configuration. For that all other TIRs' LRO fields must be modified as well.
--- drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_main.c +11 -4
@@ -1304,7 +1304,7 @@ static void mlx5e_build_tir_ctx_lro(void *tirc, struct mlx5e_priv *priv) lro_timer_supported_periods[2])); } -static int mlx5e_modify_tir_lro (struct mlx5e_priv *priv,int tt) +static int mlx5e_modify_tirs_lro (struct mlx5e_priv *priv) {struct mlx5_core_dev *mdev = priv->mdev;
@@ -1312,6 +1312,7 @@ static int mlx5e_modify_tir_lro(struct mlx5e_priv *priv, int tt)void *tirc;int inlen;int err; +int tt; inlen =MLX5_ST_SZ_BYTES (modify_tir_in); in =mlx5_vzalloc (inlen);
@@ -1323,7 +1324,11 @@ static int mlx5e_modify_tir_lro(struct mlx5e_priv *priv, int tt)mlx5e_build_tir_ctx_lro (tirc, priv); - err =mlx5_core_modify_tir (mdev, priv->tirn[tt], in, inlen); +for (tt =0 ; tt <MLX5E_NUM_TT ; tt++) { + err =mlx5_core_modify_tir (mdev, priv->tirn[tt], in, inlen); +if (err) +break ; + }kvfree (in);
@@ -1870,8 +1875,10 @@ static int mlx5e_set_features(struct net_device *netdev,mlx5e_close_locked (priv->netdev); priv->params.lro_en = !!(features &NETIF_F_LRO ); -mlx5e_modify_tir_lro (priv,MLX5E_TT_IPV4_TCP ); -mlx5e_modify_tir_lro (priv,MLX5E_TT_IPV6_TCP ); + err =mlx5e_modify_tirs_lro (priv); +if (err) +mlx5_core_warn (priv->mdev,"lro modify failed, %d\n" , + err);if (was_opened) err =mlx5e_open_locked (priv->netdev);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 38/65 net/mlx5e: Correctly handle RSS indirection table when changing number of channels
In reply to Sasha LevinFrom: Tariq Toukan <[email protected]>
[ Upstream commit 85082dba0a5059c538cfa786d07f5ec5370d22fe ]
Upon changing num_channels, reset the RSS indirection table to match the new value.
--- drivers/net/ethernet/mellanox/mlx5/core/en.h | 2 ++ .../net/ethernet/mellanox/mlx5/core/en_ethtool.c | 2 ++ drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 15 +++++++++++---- 3 files changed, 15 insertions(+), 4 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en.h +2 -0
@@ -586,6 +586,8 @@ int mlx5e_redirect_rqt(struct mlx5e_priv *priv, enum mlx5e_rqt_ix rqt_ix);int mlx5e_open_locked (struct net_device *netdev);int mlx5e_close_locked (struct net_device *netdev); +void mlx5e_build_default_indir_rqt (u32 *indirection_rqt,int len, +int num_channels);static inline void mlx5e_tx_notify_hw (struct mlx5e_sq *sq,struct mlx5e_tx_wqe *wqe,int bf_sz)
drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +2 -0
@@ -385,6 +385,8 @@ static int mlx5e_set_channels(struct net_device *dev,mlx5e_close_locked (dev); priv->params.num_channels = count; +mlx5e_build_default_indir_rqt (priv->params.indirection_rqt, +MLX5E_INDIR_RQT_SIZE , count);if (was_opened) err =mlx5e_open_locked (dev);
drivers/net/ethernet/mellanox/mlx5/core/en_main.c +11 -4
@@ -1186,7 +1186,6 @@ static void mlx5e_fill_indir_rqt_rqns(struct mlx5e_priv *priv, void *rqtc) ix =mlx5e_bits_invert (i,MLX5E_LOG_INDIR_RQT_SIZE ); ix = priv->params.indirection_rqt[ix]; - ix = ix % priv->params.num_channels; MLX5_SET(rqtc, rqtc, rq_num[i], test_bit(MLX5E_STATE_OPENED, &priv->state) ? priv->channel[ix]->rq.rqn :
@@ -1983,12 +1982,20 @@ u16 mlx5e_get_max_inline_cap(struct mlx5_core_dev *mdev)2 /*sizeof(mlx5e_tx_wqe.inline_hdr_start)*/ ; } +void mlx5e_build_default_indir_rqt (u32 *indirection_rqt,int len, +int num_channels) +{ +int i; + +for (i =0 ; i < len; i++) + indirection_rqt[i] = i % num_channels; +} +static void mlx5e_build_netdev_priv (struct mlx5_core_dev *mdev,struct net_device *netdev,int num_channels) {struct mlx5e_priv *priv =netdev_priv (netdev); -int i; priv->params.log_sq_size =MLX5E_PARAMS_DEFAULT_LOG_SQ_SIZE ;
@@ -2012,8 +2019,8 @@ static void mlx5e_build_netdev_priv(struct mlx5_core_dev *mdev,netdev_rss_key_fill (priv->params.toeplitz_hash_key,sizeof (priv->params.toeplitz_hash_key)); -for (i =0 ; i <MLX5E_INDIR_RQT_SIZE ; i++) - priv->params.indirection_rqt[i] = i % num_channels; +mlx5e_build_default_indir_rqt (priv->params.indirection_rqt, +MLX5E_INDIR_RQT_SIZE , num_channels); priv->params.lro_wqe_sz =MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 39/65 ixgbe: fix RSS limit for X550
In reply to Sasha LevinFrom: Emil Tantilov <[email protected]>
[ Upstream commit e9ee3238f8a480bbca58e51d02a93628d7c1f265 ]
X550 allows for up to 64 RSS queues, but the driver can have max of 63 (-1 MSIX vector for link).
On systems with >= 64 CPUs the driver will set the redirection table for all 64 queues which will result in packets being dropped.
--- drivers/net/ethernet/intel/ixgbe/ixgbe.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/intel/ixgbe/ixgbe.h +1 -1
@@ -312,7 +312,7 @@ enum ixgbe_ring_f_enum { };#define IXGBE_MAX_RSS_INDICES 16 -#define IXGBE_MAX_RSS_INDICES_X550 64 +#define IXGBE_MAX_RSS_INDICES_X550 63#define IXGBE_MAX_VMDQ_INDICES 64#define IXGBE_MAX_FDIR_INDICES 63/* based on q_vector limit */ #define IXGBE_MAX_FCOE_INDICES 8
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 40/65 ixgbe: Correct X550EM_x revision check
In reply to Sasha LevinFrom: Mark Rustad <[email protected]>
[ Upstream commit 3ca2b2506ec9a3b1615930a6810d30ec9aba10a1 ]
The X550EM_x revision check needs to check a value, not just a bit. Use a mask and check the value. Also remove the redundant check inside the ixgbe_enter_lplu_t_x550em, because it can only be called when both the mac type and revision check pass.
--- drivers/net/ethernet/intel/ixgbe/ixgbe_type.h | 2 +- drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c | 9 +++------ 2 files changed, 4 insertions(+), 7 deletions(-)
drivers/net/ethernet/intel/ixgbe/ixgbe_type.h +1 -1
@@ -3508,7 +3508,7 @@ struct ixgbe_info {#define IXGBE_FUSES0_GROUP (_i) (0x11158 + ((_i) * 4))#define IXGBE_FUSES0_300MHZ BIT(5) -#define IXGBE_FUSES0_REV1 BIT(6) +#define IXGBE_FUSES0_REV_MASK (3 << 6)#define IXGBE_KRM_PORT_CAR_GEN_CTRL (P ) ((P) ? 0x8010 : 0x4010)#define IXGBE_KRM_LINK_CTRL_1 (P ) ((P) ? 0x820C : 0x420C)
drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c +3 -6
@@ -1873,10 +1873,6 @@ static s32 ixgbe_enter_lplu_t_x550em(struct ixgbe_hw *hw)u32 save_autoneg;bool link_up; -/* SW LPLU not required on later HW revisions. */ -if (IXGBE_FUSES0_REV1 &IXGBE_READ_REG (hw,IXGBE_FUSES0_GROUP (0 ))) -return 0 ; -/* If blocked by MNG FW, then don't restart AN */ if (ixgbe_check_reset_blocked (hw))return 0 ;
@@ -2030,8 +2026,9 @@ static s32 ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw) }/* setup SW LPLU only for first revision */ -if (!(IXGBE_FUSES0_REV1 &IXGBE_READ_REG (hw, -IXGBE_FUSES0_GROUP (0 )))) +if (hw->mac.type == ixgbe_mac_X550EM_x && + !(IXGBE_READ_REG (hw,IXGBE_FUSES0_GROUP (0 )) & +IXGBE_FUSES0_REV_MASK )) phy->ops.enter_lplu = ixgbe_enter_lplu_t_x550em; phy->ops.handle_lasi = ixgbe_handle_lasi_ext_t_x550em;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 41/65 ALSA: timer: Fix zero-division by continue of uninitialized instance
In reply to Sasha LevinFrom: Takashi Iwai <[email protected]>
[ Upstream commit 9f8a7658bcafb2a7853f7a2eae8a94e87e6e695b ]
When a user timer instance is continued without the explicit start beforehand, the system gets eventually zero-division error like:
divide error: 0000 [#1] SMP DEBUG_PAGEALLOC KASAN
CPU: 1 PID: 27320 Comm: syz-executor Not tainted 4.8.0-rc3-next-20160825+ #8 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 task: ffff88003c9b2280 task.stack: ffff880027280000 RIP: 0010:[<ffffffff858e1a6c>] [< inline >] ktime_divns include/linux/ktime.h:195 RIP: 0010:[<ffffffff858e1a6c>] [<ffffffff858e1a6c>] snd_hrtimer_callback+0x1bc/0x3c0 sound/core/hrtimer.c:62 Call Trace: <IRQ> [< inline >] __run_hrtimer kernel/time/hrtimer.c:1238 [<ffffffff81504335>] __hrtimer_run_queues+0x325/0xe70 kernel/time/hrtimer.c:1302 [<ffffffff81506ceb>] hrtimer_interrupt+0x18b/0x420 kernel/time/hrtimer.c:1336 [<ffffffff8126d8df>] local_apic_timer_interrupt+0x6f/0xe0 arch/x86/kernel/apic/apic.c:933 [<ffffffff86e13056>] smp_apic_timer_interrupt+0x76/0xa0 arch/x86/kernel/apic/apic.c:957 [<ffffffff86e1210c>] apic_timer_interrupt+0x8c/0xa0 arch/x86/entry/entry_64.S:487 <EOI> .....
Although a similar issue was spotted and a fix patch was merged in commit [6b760bb2c63a: ALSA: timer: fix division by zero after SNDRV_TIMER_IOCTL_CONTINUE], it seems covering only a part of iceberg.
In this patch, we fix the issue a bit more drastically. Basically the continue of an uninitialized timer is supposed to be a fresh start, so we do it for user timers. For the direct snd_timer_continue() call, there is no way to pass the initial tick value, so we kick out for the uninitialized case.
--- sound/core/timer.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
sound/core/timer.c +14 -0
@@ -35,6 +35,9 @@#include <sound/initval.h> #include <linux/kmod.h> +/* internal flags */ +#define SNDRV_TIMER_IFLG_PAUSED 0x00010000 +#if IS_ENABLED (CONFIG_SND_HRTIMER )#define DEFAULT_TIMER_LIMIT 4#elif IS_ENABLED (CONFIG_SND_RTCTIMER )
@@ -547,6 +550,10 @@ static int snd_timer_stop1(struct snd_timer_instance *timeri, bool stop) } } timeri->flags &= ~(SNDRV_TIMER_IFLG_RUNNING |SNDRV_TIMER_IFLG_START ); +if (stop) + timeri->flags &= ~SNDRV_TIMER_IFLG_PAUSED ; +else + timeri->flags |=SNDRV_TIMER_IFLG_PAUSED ;snd_timer_notify1 (timeri, stop ?SNDRV_TIMER_EVENT_STOP :SNDRV_TIMER_EVENT_PAUSE ); unlock:
@@ -608,6 +615,10 @@ int snd_timer_stop(struct snd_timer_instance *timeri)*/ int snd_timer_continue (struct snd_timer_instance *timeri) { +/* timer can continue only after pause */ +if (!(timeri->flags &SNDRV_TIMER_IFLG_PAUSED )) +return -EINVAL ; +if (timeri->flags &SNDRV_TIMER_IFLG_SLAVE )return snd_timer_start_slave (timeri, false);else
@@ -1837,6 +1848,9 @@ static int snd_timer_user_continue(struct file *file) tu = file->private_data;if (!tu->timeri)return -EBADFD ; +/* start timer instead of continue if it's not used before */ +if (!(tu->timeri->flags &SNDRV_TIMER_IFLG_PAUSED )) +return snd_timer_user_start (file); tu->timeri->lost =0 ;return (err =snd_timer_continue (tu->timeri)) <0 ? err :0 ; }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 42/65 vti6: flush x-netns xfrm cache when vti interface is removed
In reply to Sasha LevinFrom: Nicolas Dichtel <[email protected]>
[ Upstream commit 7f92083eb58f85ea114d97f65fcbe22be5b0468d ]
This is the same fix than commit a5d0dc810abf ("vti: flush x-netns xfrm cache when vti interface is removed")
This patch fixes a refcnt problem when a x-netns vti6 interface is removed:unregister_netdevice: waiting for vti6_test to become free. Usage count = 1
Here is a script to reproduce the problem:
ip link set dev ntfp2 up
ip addr add dev ntfp2 2001::1/64
ip link add vti6_test type vti6 local 2001::1 remote 2001::2 key 1 ip netns add secure
ip link set vti6_test netns secure
ip netns exec secure ip link set vti6_test up
ip netns exec secure ip link s lo up
ip netns exec secure ip addr add dev vti6_test 2003::1/64
ip -6 xfrm policy add dir out tmpl src 2001::1 dst 2001::2 proto esp \
mode tunnel mark 1
ip -6 xfrm policy add dir in tmpl src 2001::2 dst 2001::1 proto esp \
mode tunnel mark 1
ip xfrm state add src 2001::1 dst 2001::2 proto esp spi 1 mode tunnel \
enc des3_ede 0x112233445566778811223344556677881122334455667788 mark 1 ip xfrm state add src 2001::2 dst 2001::1 proto esp spi 1 mode tunnel \ enc des3_ede 0x112233445566778811223344556677881122334455667788 mark 1
ip netns exec secure ping6 -c 4 2003::2
ip netns del secure
--- net/ipv6/ip6_vti.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+)
net/ipv6/ip6_vti.c +31 -0
@@ -1140,6 +1140,33 @@ static struct xfrm6_protocol vti_ipcomp6_protocol __read_mostly = { .priority = 100, }; +static bool is_vti6_tunnel (const struct net_device *dev) +{ +return dev->netdev_ops == &vti6_netdev_ops; +} + +static int vti6_device_event (struct notifier_block *unused, +unsigned long event,void *ptr) +{ +struct net_device *dev =netdev_notifier_info_to_dev (ptr); +struct ip6_tnl *t =netdev_priv (dev); + +if (!is_vti6_tunnel (dev)) +return NOTIFY_DONE ; + +switch (event) { +case NETDEV_DOWN : +if (!net_eq (t->net,dev_net (dev))) +xfrm_garbage_collect (t->net); +break ; + } +return NOTIFY_DONE ; +} + +static struct notifier_block vti6_notifier_block__read_mostly = { + .notifier_call = vti6_device_event, +}; +/** * vti6_tunnel_init - register protocol and reserve needed resources *
@@ -1150,6 +1177,8 @@ static int __init vti6_tunnel_init(void)const char *msg;int err; +register_netdevice_notifier (&vti6_notifier_block); + msg ="tunnel device" ; err =register_pernet_device (&vti6_net_ops);if (err <0 )
@@ -1182,6 +1211,7 @@ static int __init vti6_tunnel_init(void) xfrm_proto_esp_failed:unregister_pernet_device (&vti6_net_ops); pernet_dev_failed: +unregister_netdevice_notifier (&vti6_notifier_block);pr_err ("vti6 init: failed to register %s\n" , msg);return err; }
@@ -1196,6 +1226,7 @@ static void __exit vti6_tunnel_cleanup(void)xfrm6_protocol_deregister (&vti_ah6_protocol,IPPROTO_AH );xfrm6_protocol_deregister (&vti_esp6_protocol,IPPROTO_ESP );unregister_pernet_device (&vti6_net_ops); +unregister_netdevice_notifier (&vti6_notifier_block); }module_init (vti6_tunnel_init);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 43/65 gro: Allow tunnel stacking in the case of FOU/GUE
In reply to Sasha LevinFrom: Alexander Duyck <[email protected]>
[ Upstream commit c3483384ee511ee2af40b4076366cd82a6a47b86 ]
This patch should fix the issues seen with a recent fix to prevent tunnel-in-tunnel frames from being generated with GRO. The fix itself is correct for now as long as we do not add any devices that support NETIF_F_GSO_GRE_CSUM. When such a device is added it could have the potential to mess things up due to the fact that the outer transport header points to the outer UDP header and not the GRE header as would be expected.
--- net/ipv4/fou.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
net/ipv4/fou.c +16 -0
@@ -195,6 +195,14 @@ static struct sk_buff **fou_gro_receive(struct sk_buff **head,u8 proto =NAPI_GRO_CB (skb)->proto;const struct net_offload **offloads; +/* We can clear the encap_mark for FOU as we are essentially doing +* one of two possible things. We are either adding an L4 tunnel +* header to the outer L3 tunnel header, or we are are simply +* treating the GRE tunnel header as though it is a UDP protocol +* specific header such as VXLAN or GENEVE. +*/ +NAPI_GRO_CB (skb)->encap_mark =0 ; +rcu_read_lock (); offloads =NAPI_GRO_CB (skb)->is_ipv6 ? inet6_offloads : inet_offloads; ops =rcu_dereference (offloads[proto]);
@@ -354,6 +362,14 @@ static struct sk_buff **gue_gro_receive(struct sk_buff **head, } } +/* We can clear the encap_mark for GUE as we are essentially doing +* one of two possible things. We are either adding an L4 tunnel +* header to the outer L3 tunnel header, or we are are simply +* treating the GRE tunnel header as though it is a UDP protocol +* specific header such as VXLAN or GENEVE. +*/ +NAPI_GRO_CB (skb)->encap_mark =0 ; +rcu_read_lock (); offloads =NAPI_GRO_CB (skb)->is_ipv6 ? inet6_offloads : inet_offloads; ops =rcu_dereference (offloads[guehdr->proto_ctype]);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 44/65 brcmfmac: Fix glom_skb leak in brcmf_sdiod_recv_chain
In reply to Sasha LevinFrom: "Peter S. Housel" <[email protected]>
[ Upstream commit 5ea59db8a375216e6c915c5586f556766673b5a7 ]
An earlier change to this function (3bdae810721b) fixed a leak in the case of an unsuccessful call to brcmf_sdiod_buffrw(). However, the glom_skb buffer, used for emulating a scattering read, is never used or referenced after its contents are copied into the destination buffers, and therefore always needs to be freed by the end of the function.
--- drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +3 -4
@@ -705,7 +705,7 @@ int brcmf_sdiod_recv_pkt(struct brcmf_sdio_dev *sdiodev, struct sk_buff *pkt)int brcmf_sdiod_recv_chain (struct brcmf_sdio_dev *sdiodev,struct sk_buff_head *pktq,uint totlen) { -struct sk_buff *glom_skb; +struct sk_buff *glom_skb =NULL ;struct sk_buff *skb;u32 addr = sdiodev->sbwad;int err =0 ;
@@ -726,10 +726,8 @@ int brcmf_sdiod_recv_chain(struct brcmf_sdio_dev *sdiodev,return -ENOMEM ; err =brcmf_sdiod_buffrw (sdiodev,SDIO_FUNC_2 , false, addr, glom_skb); -if (err) { -brcmu_pkt_buf_free_skb (glom_skb); +if (err) goto done; - } skb_queue_walk(pktq, skb) {memcpy (skb->data, glom_skb->data, skb->len);
@@ -740,6 +738,7 @@ int brcmf_sdiod_recv_chain(struct brcmf_sdio_dev *sdiodev, pktq); done: +brcmu_pkt_buf_free_skb (glom_skb);return err; }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 45/65 l2tp: hold socket before dropping lock in l2tp_ip{, 6}_recv()
In reply to Sasha LevinFrom: Guillaume Nault <[email protected]>
[ Upstream commit a3c18422a4b4e108bcf6a2328f48867e1003fd95 ]
Socket must be held while under the protection of the l2tp lock; there is no guarantee that sk remains valid after the read_unlock_bh() call.
Same issue for l2tp_ip and l2tp_ip6.
--- net/l2tp/l2tp_ip.c | 11 ++++++----- net/l2tp/l2tp_ip6.c | 11 ++++++----- 2 files changed, 12 insertions(+), 10 deletions(-)
net/l2tp/l2tp_ip.c +6 -5
@@ -184,14 +184,15 @@ static int l2tp_ip_recv(struct sk_buff *skb)read_lock_bh (&l2tp_ip_lock); sk =__l2tp_ip_bind_lookup (net, iph->daddr,0 , tunnel_id); +if (!sk) { +read_unlock_bh (&l2tp_ip_lock); + goto discard; + } + +sock_hold (sk);read_unlock_bh (&l2tp_ip_lock); } -if (sk ==NULL ) - goto discard; - -sock_hold (sk); -if (!xfrm4_policy_check (sk,XFRM_POLICY_IN , skb)) goto discard_put;
net/l2tp/l2tp_ip6.c +6 -5
@@ -196,14 +196,15 @@ static int l2tp_ip6_recv(struct sk_buff *skb)read_lock_bh (&l2tp_ip6_lock); sk =__l2tp_ip6_bind_lookup (&init_net, &iph->daddr,0 , tunnel_id); +if (!sk) { +read_unlock_bh (&l2tp_ip6_lock); + goto discard; + } + +sock_hold (sk);read_unlock_bh (&l2tp_ip6_lock); } -if (sk ==NULL ) - goto discard; - -sock_hold (sk); -if (!xfrm6_policy_check (sk,XFRM_POLICY_IN , skb)) goto discard_put;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 46/65 tty: serial: sprd: fix error return code in sprd_probe()
In reply to Sasha LevinFrom: "Gustavo A. R. Silva" <[email protected]>
[ Upstream commit ec085c5a51b768947ca481f90b66653e36b3c566 ]
platform_get_irq() returns an error code, but the sprd_serial driver ignores it and always returns -ENODEV. This is not correct and, prevents -EPROBE_DEFER from being propagated properly.
Also, notice that platform_get_irq() no longer returns 0 on error:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e330b9a6bb35dc7097a4f02cb1ae7b6f96df92af
Print and propagate the return value of platform_get_irq on failure.
This issue was detected with the help of Coccinelle.
--- drivers/tty/serial/sprd_serial.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/tty/serial/sprd_serial.c +2 -2
@@ -731,8 +731,8 @@ static int sprd_probe(struct platform_device *pdev) irq =platform_get_irq (pdev,0 );if (irq <0 ) { -dev_err (&pdev->dev,"not provide irq resource\n" ); -return -ENODEV ; +dev_err (&pdev->dev,"not provide irq resource: %d\n" , irq); +return irq; } up->irq = irq;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 47/65 video: fbdev: pxa3xx_gcu: fix error return code in pxa3xx_gcu_probe()
In reply to Sasha LevinFrom: "Gustavo A. R. Silva" <[email protected]>
[ Upstream commit 7588f1ecc5f0c914e669d8afb6525f47cd1c4355 ]
platform_get_irq() returns an error code, but the pxa3xx_gcu driver ignores it and always returns -ENODEV. This is not correct and, prevents -EPROBE_DEFER from being propagated properly.
Also, notice that platform_get_irq() no longer returns 0 on error:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e330b9a6bb35dc7097a4f02cb1ae7b6f96df92af
Print and propagate the return value of platform_get_irq on failure.
This issue was detected with the help of Coccinelle.
--- drivers/video/fbdev/pxa3xx-gcu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/video/fbdev/pxa3xx-gcu.c +2 -2
@@ -626,8 +626,8 @@ static int pxa3xx_gcu_probe(struct platform_device *pdev)/* request the IRQ */ irq =platform_get_irq (pdev,0 );if (irq <0 ) { -dev_err (dev,"no IRQ defined\n" ); -return -ENODEV ; +dev_err (dev,"no IRQ defined: %d\n" , irq); +return irq; } ret = devm_request_irq(dev, irq, pxa3xx_gcu_handle_irq,
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 48/65 sparc64 mm: Fix more TSB sizing issues
In reply to Sasha LevinFrom: Mike Kravetz <[email protected]>
[ Upstream commit 1e953d846ac015fbfcf09c857e8f893924cb629c ]
Commit af1b1a9b36b8 ("sparc64 mm: Fix base TSB sizing when hugetlb pages are used") addressed the difference between hugetlb and THP pages when computing TSB sizes. The following additional issues were also discovered while working with the code.
In order to save memory, THP makes use of a huge zero page. This huge zero page does not count against a task's RSS, but it does consume TSB entries. This is similar to hugetlb pages. Therefore, count huge zero page entries in hugetlb_pte_count.
Accounting of THP pages is done in the routine set_pmd_at(). Unfortunately, this does not catch the case where a THP page is split. To handle this case, decrement the count in pmdp_invalidate(). pmdp_invalidate is only called when splitting a THP. However, 'sanity checks' are added in case it is ever called for other purposes.
A more general issue exists with HPAGE_SIZE accounting. hugetlb_pte_count tracks the number of HPAGE_SIZE (8M) pages. This value is used to size the TSB for HPAGE_SIZE pages. However, each HPAGE_SIZE page consists of two REAL_HPAGE_SIZE (4M) pages. The TSB contains an entry for each REAL_HPAGE_SIZE page. Therefore, the number of REAL_HPAGE_SIZE pages should be used to size the huge page TSB. A new compile time constant REAL_HPAGE_PER_HPAGE is used to multiply hugetlb_pte_count before sizing the TSB.
Changes from V1
- Fixed build issue if hugetlb or THP not configured
--- arch/sparc/include/asm/page_64.h | 1 + arch/sparc/mm/fault_64.c | 1 + arch/sparc/mm/tlb.c | 35 ++++++++++++++++++++++++++++---- arch/sparc/mm/tsb.c | 18 ++++++++++------ 4 files changed, 45 insertions(+), 10 deletions(-)
arch/sparc/include/asm/page_64.h +1 -0
@@ -25,6 +25,7 @@#define HPAGE_MASK (~(HPAGE_SIZE - 1UL))#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT)#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA +#define REAL_HPAGE_PER_HPAGE (_AC(1,UL) << (HPAGE_SHIFT - REAL_HPAGE_SHIFT))#endif #ifndef __ASSEMBLY__
arch/sparc/mm/fault_64.c +1 -0
@@ -487,6 +487,7 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)tsb_grow (mm,MM_TSB_BASE , mm_rss);#if defined(CONFIG_HUGETLB_PAGE ) || defined(CONFIG_TRANSPARENT_HUGEPAGE ) mm_rss = mm->context.hugetlb_pte_count + mm->context.thp_pte_count; + mm_rss *=REAL_HPAGE_PER_HPAGE ;if (unlikely (mm_rss > mm->context.tsb_block[MM_TSB_HUGE ].tsb_rss_limit)) {if (mm->context.tsb_block[MM_TSB_HUGE ].tsb)
arch/sparc/mm/tlb.c +31 -4
@@ -174,10 +174,25 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr,return ;if ((pmd_val (pmd) ^pmd_val (orig)) & _PAGE_PMD_HUGE) { -if (pmd_val (pmd) & _PAGE_PMD_HUGE) - mm->context.thp_pte_count++; -else - mm->context.thp_pte_count--; +/* +* Note that this routine only sets pmds for THP pages. +* Hugetlb pages are handled elsewhere. We need to check +* for huge zero page. Huge zero pages are like hugetlb +* pages in that there is no RSS, but there is the need +* for TSB entries. So, huge zero page counts go into +* hugetlb_pte_count. +*/ +if (pmd_val (pmd) & _PAGE_PMD_HUGE) { +if (is_huge_zero_page (pmd_page (pmd))) + mm->context.hugetlb_pte_count++; +else + mm->context.thp_pte_count++; + }else { +if (is_huge_zero_page (pmd_page (orig))) + mm->context.hugetlb_pte_count--; +else + mm->context.thp_pte_count--; + }/* Do not try to allocate the TSB hash table if we * don't have one already. We have various locks held
@@ -204,6 +219,9 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr, } } +/* +* This routine is only called when splitting a THP +*/ void pmdp_invalidate (struct vm_area_struct *vma,unsigned long address,pmd_t *pmdp) {
@@ -213,6 +231,15 @@ void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,set_pmd_at (vma->vm_mm, address, pmdp, entry);flush_tlb_range (vma, address, address +HPAGE_PMD_SIZE ); + +/* +* set_pmd_at() will not be called in a way to decrement +* thp_pte_count when splitting a THP, so do it now. +* Sanity check pmd before doing the actual decrement. +*/ +if ((pmd_val (entry) & _PAGE_PMD_HUGE) && + !is_huge_zero_page (pmd_page (entry))) + (vma->vm_mm)->context.thp_pte_count--; } void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,
arch/sparc/mm/tsb.c +12 -6
@@ -489,8 +489,10 @@ void tsb_grow(struct mm_struct *mm, unsigned long tsb_index, unsigned long rss)int init_new_context (struct task_struct *tsk,struct mm_struct *mm) { +unsigned long mm_rss =get_mm_rss (mm);#if defined(CONFIG_HUGETLB_PAGE ) || defined(CONFIG_TRANSPARENT_HUGEPAGE ) -unsigned long total_huge_pte_count; +unsigned long saved_hugetlb_pte_count; +unsigned long saved_thp_pte_count;#endif unsigned int i;
@@ -503,10 +505,12 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm)* will re-increment the counters as the parent PTEs are * copied into the child address space. */ - total_huge_pte_count = mm->context.hugetlb_pte_count + - mm->context.thp_pte_count; + saved_hugetlb_pte_count = mm->context.hugetlb_pte_count; + saved_thp_pte_count = mm->context.thp_pte_count; mm->context.hugetlb_pte_count =0 ; mm->context.thp_pte_count =0 ; + + mm_rss -= saved_thp_pte_count * (HPAGE_SIZE /PAGE_SIZE );#endif /* copy_mm() copies over the parent's mm_struct before calling
@@ -519,11 +523,13 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm)/* If this is fork, inherit the parent's TSB size. We would * grow it to that size on the first page fault anyways. */ -tsb_grow (mm,MM_TSB_BASE ,get_mm_rss (mm)); +tsb_grow (mm,MM_TSB_BASE , mm_rss);#if defined(CONFIG_HUGETLB_PAGE ) || defined(CONFIG_TRANSPARENT_HUGEPAGE ) -if (unlikely (total_huge_pte_count)) -tsb_grow (mm,MM_TSB_HUGE , total_huge_pte_count); +if (unlikely (saved_hugetlb_pte_count + saved_thp_pte_count)) +tsb_grow (mm,MM_TSB_HUGE , + (saved_hugetlb_pte_count + saved_thp_pte_count) * +REAL_HPAGE_PER_HPAGE );#endif if (unlikely (!mm->context.tsb_block[MM_TSB_BASE ].tsb))
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 49/65 gpu: host1x: fix error return code in host1x_probe()
In reply to Sasha LevinFrom: "Gustavo A. R. Silva" <[email protected]>
[ Upstream commit 7b2c63de20080c18d0de35b292ad61fc9bc8328e ]
platform_get_irq() returns an error code, but the host1x driver ignores it and always returns -ENXIO. This is not correct and, prevents -EPROBE_DEFER from being propagated properly.
Notice that platform_get_irq() no longer returns 0 on error:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e330b9a6bb35dc7097a4f02cb1ae7b6f96df92af
Print and propagate the return value of platform_get_irq on failure.
This issue was detected with the help of Coccinelle.
--- drivers/gpu/host1x/dev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/host1x/dev.c +2 -2
@@ -116,8 +116,8 @@ static int host1x_probe(struct platform_device *pdev) syncpt_irq =platform_get_irq (pdev,0 );if (syncpt_irq <0 ) { -dev_err (&pdev->dev,"failed to get IRQ\n" ); -return -ENXIO ; +dev_err (&pdev->dev,"failed to get IRQ: %d\n" , syncpt_irq); +return syncpt_irq; } host =devm_kzalloc (&pdev->dev,sizeof (*host),GFP_KERNEL );
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 50/65 sparc64: Fix exception handling in UltraSPARC-III memcpy.
In reply to Sasha LevinFrom: "David S. Miller" <[email protected]>
[ Upstream commit 0ede1c401332173ab0693121dc6cde04a4dbf131 ]
Mikael Pettersson reported that some test programs in the strace-4.18 testsuite cause an OOPS.
After some debugging it turns out that garbage values are returned when an exception occurs, causing the fixup memset() to be run with bogus arguments.
The problem is that two of the exception handler stubs write the successfully copied length into the wrong register.
--- arch/sparc/lib/U3memcpy.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/sparc/lib/U3memcpy.S +2 -2
@@ -145,13 +145,13 @@ ENDPROC(U3_retl_o2_plus_GS_plus_0x08) ENTRY(U3_retl_o2_and_7_plus_GS) and %o2, 7, %o2 retl - add %o2, GLOBAL_SPARE, %o2 + add %o2, GLOBAL_SPARE, %o0 ENDPROC(U3_retl_o2_and_7_plus_GS) ENTRY(U3_retl_o2_and_7_plus_GS_plus_8) add GLOBAL_SPARE, 8, GLOBAL_SPARE and %o2, 7, %o2 retl - add %o2, GLOBAL_SPARE, %o2 + add %o2, GLOBAL_SPARE, %o0 ENDPROC(U3_retl_o2_and_7_plus_GS_plus_8) #endif
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 51/65 gpio: msic: fix error return code in platform_msic_gpio_probe()
In reply to Sasha LevinFrom: "Gustavo A. R. Silva" <[email protected]>
[ Upstream commit ca1f3ae3154ad6d08caa740c99be0d86644a4e44 ]
platform_get_irq() returns an error code, but the gpio-msic driver ignores it and always returns -EINVAL. This is not correct, and prevents -EPROBE_DEFER from being propagated properly.
Notice that platform_get_irq() no longer returns 0 on error:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e330b9a6bb35dc7097a4f02cb1ae7b6f96df92af
Print and propagate the return value of platform_get_irq on failure.
--- drivers/gpio/gpio-msic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpio/gpio-msic.c +2 -2
@@ -266,8 +266,8 @@ static int platform_msic_gpio_probe(struct platform_device *pdev)int i;if (irq <0 ) { -dev_err (dev,"no IRQ line\n" ); -return -EINVAL ; +dev_err (dev,"no IRQ line: %d\n" , irq); +return irq; }if (!pdata || !pdata->gpio_base) {
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 52/65 usb: imx21-hcd: fix error return code in imx21_probe()
In reply to Sasha LevinFrom: "Gustavo A. R. Silva" <[email protected]>
[ Upstream commit 46edf52d08342b3dc1f9a61c5200ab8b1c0f5a37 ]
platform_get_irq() returns an error code, but the imx21-hcd driver ignores it and always returns -ENXIO. This is not correct, and prevents -EPROBE_DEFER from being propagated properly.
Notice that platform_get_irq() no longer returns 0 on error:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e330b9a6bb35dc7097a4f02cb1ae7b6f96df92af
Print error message and propagate the return value of platform_get_irq on failure.
This issue was detected with the help of Coccinelle.
--- drivers/usb/host/imx21-hcd.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/usb/host/imx21-hcd.c +4 -2
@@ -1849,8 +1849,10 @@ static int imx21_probe(struct platform_device *pdev)if (!res)return -ENODEV ; irq =platform_get_irq (pdev,0 ); -if (irq <0 ) -return -ENXIO ; +if (irq <0 ) { +dev_err (&pdev->dev,"Failed to get IRQ: %d\n" , irq); +return irq; + } hcd =usb_create_hcd (&imx21_hc_driver, &pdev->dev,dev_name (&pdev->dev));
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 53/65 usb: ehci-omap: fix error return code in ehci_hcd_omap_probe()
In reply to Sasha LevinFrom: "Gustavo A. R. Silva" <[email protected]>
[ Upstream commit 99dbff202e28ad1dadf55b058bcae7908678e963 ]
platform_get_irq() returns an error code, but the ehci-omap driver ignores it and always returns -ENODEV. This is not correct and, prevents -EPROBE_DEFER from being propagated properly.
Also, notice that platform_get_irq() no longer returns 0 on error:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e330b9a6bb35dc7097a4f02cb1ae7b6f96df92af
Print and propagate the return value of platform_get_irq on failure.
This issue was detected with the help of Coccinelle.
--- drivers/usb/host/ehci-omap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/usb/host/ehci-omap.c +2 -2
@@ -130,8 +130,8 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) irq =platform_get_irq (pdev,0 );if (irq <0 ) { -dev_err (dev,"EHCI irq failed\n" ); -return -ENODEV ; +dev_err (dev,"EHCI irq failed: %d\n" , irq); +return irq; } res =platform_get_resource (pdev,IORESOURCE_MEM ,0 );
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 54/65 usb: dwc3: omap: fix error return code in dwc3_omap_probe()
In reply to Sasha LevinFrom: "Gustavo A. R. Silva" <[email protected]>
[ Upstream commit 0ae99ecba7928c7bc66cf14d8a88f0b6ec9fc78e ]
platform_get_irq() returns an error code, but the dwc3-omap driver ignores it and always returns -EINVAL. This is not correct and, prevents -EPROBE_DEFER from being propagated properly.
Notice that platform_get_irq() no longer returns 0 on error:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e330b9a6bb35dc7097a4f02cb1ae7b6f96df92af
Print and propagate the return value of platform_get_irq on failure.
This issue was detected with the help of Coccinelle.
--- drivers/usb/dwc3/dwc3-omap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/usb/dwc3/dwc3-omap.c +2 -2
@@ -469,8 +469,8 @@ static int dwc3_omap_probe(struct platform_device *pdev) irq =platform_get_irq (pdev,0 );if (irq <0 ) { -dev_err (dev,"missing IRQ resource\n" ); -return -EINVAL ; +dev_err (dev,"missing IRQ resource: %d\n" , irq); +return irq; } res =platform_get_resource (pdev,IORESOURCE_MEM ,0 );
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 55/65 spi/bcm63xx-hspi: fix error return code in bcm63xx_hsspi_probe()
In reply to Sasha LevinFrom: "Gustavo A. R. Silva" <[email protected]>
[ Upstream commit 378da4a65f3a0390837b38145bb5d8c2d20c2cf7 ]
platform_get_irq() returns an error code, but the spi-bcm63xx-hsspi driver ignores it and always returns -ENXIO. This is not correct and, prevents -EPROBE_DEFER from being propagated properly.
Notice that platform_get_irq() no longer returns 0 on error:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e330b9a6bb35dc7097a4f02cb1ae7b6f96df92af
Print and propagate the return value of platform_get_irq on failure.
This issue was detected with the help of Coccinelle.
--- drivers/spi/spi-bcm63xx-hsspi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/spi/spi-bcm63xx-hsspi.c +2 -2
@@ -336,8 +336,8 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev) irq =platform_get_irq (pdev,0 );if (irq <0 ) { -dev_err (dev,"no irq\n" ); -return -ENXIO ; +dev_err (dev,"no irq: %d\n" , irq); +return irq; } res_mem =platform_get_resource (pdev,IORESOURCE_MEM ,0 );
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 56/65 MIPS: Handle non word sized instructions when examining frame
In reply to Sasha LevinFrom: Matt Redfearn <[email protected]>
[ Upstream commit 11887ed172a6960673f130dad8f8fb42778f64d7 ]
Commit 34c2f668d0f6b ("MIPS: microMIPS: Add unaligned access support.") added fairly broken support for handling 16bit microMIPS instructions in get_frame_info(). It adjusts the instruction pointer by 16bits in the case of a 16bit sp move instruction, but not any other 16bit instruction.
Commit b6c7a324df37 ("MIPS: Fix get_frame_info() handling of microMIPS function size") goes some way to fixing get_frame_info() to iterate over microMIPS instuctions, but the instruction pointer is still manipulated using a postincrement, and is of union mips_instruction type. Since the union is sized to the largest member (a word), but microMIPS instructions are a mix of halfword and word sizes, the function does not always iterate correctly, ending up misaligned with the instruction stream and interpreting it incorrectly.
Since the instruction modifying the stack pointer is usually the first in the function, that one is usually handled correctly. But the instruction which saves the return address to the sp is some variable number of instructions into the frame and is frequently missed due to not being on a word boundary, leading to incomplete walking of the stack.
Fix this by incrementing the instruction pointer based on the size of the previously decoded instruction (& remove the hack introduced by commit 34c2f668d0f6b ("MIPS: microMIPS: Add unaligned access support.") which adjusts the instruction pointer in the case of a 16bit sp move instruction, but not any other).
Patchwork: https://patchwork.linux-mips.org/patch/16953/
--- arch/mips/kernel/process.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
arch/mips/kernel/process.c +6 -3
@@ -341,6 +341,7 @@ static int get_frame_info(struct mips_frame_info *info)bool is_mmips =IS_ENABLED (CONFIG_CPU_MICROMIPS );union mips_instruction insn, *ip, *ip_end;const unsigned int max_insns =128 ; +unsigned int last_insn_size =0 ;unsigned int i; info->pc_offset =-1 ;
@@ -352,15 +353,19 @@ static int get_frame_info(struct mips_frame_info *info) ip_end = (void *)ip + info->func_size; -for (i =0 ; i < max_insns && ip < ip_end; i++, ip++) { +for (i =0 ; i < max_insns && ip < ip_end; i++) { + ip = (void *)ip + last_insn_size;if (is_mmips &&mm_insn_16bit (ip->halfword[0 ])) { insn.halfword[0 ] =0 ; insn.halfword[1 ] = ip->halfword[0 ]; + last_insn_size =2 ; }else if (is_mmips) { insn.halfword[0 ] = ip->halfword[1 ]; insn.halfword[1 ] = ip->halfword[0 ]; + last_insn_size =4 ; }else { insn.word = ip->word; + last_insn_size =4 ; }if (is_jump_ins (&insn))
@@ -382,8 +387,6 @@ static int get_frame_info(struct mips_frame_info *info) tmp = (ip->halfword[0 ] >>1 ); info->frame_size = -(signed short)(tmp & 0xf); } - ip = (void *) &ip->halfword[1 ]; - ip--; } else#endif info->frame_size = - ip->i_format.simmediate;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 57/65 spi/bcm63xx: fix error return code in bcm63xx_spi_probe()
In reply to Sasha LevinFrom: "Gustavo A. R. Silva" <[email protected]>
[ Upstream commit ba8afe94723e9ba665aee9cca649fb2c80f7304c ]
platform_get_irq() returns an error code, but the spi-bcm63xx driver ignores it and always returns -ENXIO. This is not correct and, prevents -EPROBE_DEFER from being propagated properly.
Notice that platform_get_irq() no longer returns 0 on error:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e330b9a6bb35dc7097a4f02cb1ae7b6f96df92af
Print and propagate the return value of platform_get_irq on failure.
This issue was detected with the help of Coccinelle.
--- drivers/spi/spi-bcm63xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/spi/spi-bcm63xx.c +2 -2
@@ -496,8 +496,8 @@ static int bcm63xx_spi_probe(struct platform_device *pdev) irq =platform_get_irq (pdev,0 );if (irq <0 ) { -dev_err (dev,"no irq\n" ); -return -ENXIO ; +dev_err (dev,"no irq: %d\n" , irq); +return irq; } clk =devm_clk_get (dev,"spi" );
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 58/65 spi: xlp: fix error return code in xlp_spi_probe()
In reply to Sasha LevinFrom: "Gustavo A. R. Silva" <[email protected]>
[ Upstream commit 9a6b94796ae6feaf275ec6200e9b2964db208182 ]
platform_get_irq() returns an error code, but the spi-xlp driver ignores it and always returns -EINVAL. This is not correct and, prevents -EPROBE_DEFER from being propagated properly.
Notice that platform_get_irq() no longer returns 0 on error:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e330b9a6bb35dc7097a4f02cb1ae7b6f96df92af
Print and propagate the return value of platform_get_irq on failure.
This issue was detected with the help of Coccinelle.
--- drivers/spi/spi-xlp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/spi/spi-xlp.c +2 -2
@@ -392,8 +392,8 @@ static int xlp_spi_probe(struct platform_device *pdev) irq =platform_get_irq (pdev,0 );if (irq <0 ) { -dev_err (&pdev->dev,"no IRQ resource found\n" ); -return -EINVAL ; +dev_err (&pdev->dev,"no IRQ resource found: %d\n" , irq); +return irq; } err =devm_request_irq (&pdev->dev, irq, xlp_spi_interrupt,0 , pdev->name, xspi);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 59/65 ASoC: spear: fix error return code in spdif_in_probe()
In reply to Sasha LevinFrom: "Gustavo A. R. Silva" <[email protected]>
[ Upstream commit 27d30400c448264c1ac9434cb836de0c230af213 ]
platform_get_irq() returns an error code, but the spdif_in driver ignores it and always returns -EINVAL. This is not correct, and prevents -EPROBE_DEFER from being propagated properly.
Notice that platform_get_irq() no longer returns 0 on error:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e330b9a6bb35dc7097a4f02cb1ae7b6f96df92af
Print error message and propagate the return value of platform_get_irq on failure.
--- sound/soc/spear/spdif_in.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
sound/soc/spear/spdif_in.c +4 -2
@@ -223,8 +223,10 @@ static int spdif_in_probe(struct platform_device *pdev) host->io_base = io_base; host->irq =platform_get_irq (pdev,0 ); -if (host->irq <0 ) -return -EINVAL ; +if (host->irq <0 ) { +dev_warn (&pdev->dev,"failed to get IRQ: %d\n" , host->irq); +return host->irq; + } host->clk =devm_clk_get (&pdev->dev,NULL );if (IS_ERR (host->clk))
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 60/65 PM / devfreq: tegra: fix error return code in tegra_devfreq_probe()
In reply to Sasha LevinFrom: "Gustavo A. R. Silva" <[email protected]>
[ Upstream commit 9e578b37505018622dfafc40eed7cd78ff2af221 ]
platform_get_irq() returns an error code, but the tegra-devfreq driver ignores it and always returns -ENODEV. This is not correct, and prevents -EPROBE_DEFER from being propagated properly.
Notice that platform_get_irq() no longer returns 0 on error:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e330b9a6bb35dc7097a4f02cb1ae7b6f96df92af
Print and propagate the return value of platform_get_irq on failure.
--- drivers/devfreq/tegra-devfreq.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/devfreq/tegra-devfreq.c +3 -3
@@ -688,9 +688,9 @@ static int tegra_devfreq_probe(struct platform_device *pdev) } irq =platform_get_irq (pdev,0 ); -if (irq <=0 ) { -dev_err (&pdev->dev,"Failed to get IRQ\n" ); -return -ENODEV ; +if (irq <0 ) { +dev_err (&pdev->dev,"Failed to get IRQ: %d\n" , irq); +return irq; }platform_set_drvdata (pdev, tegra);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 61/65 bonding: avoid defaulting hard_header_len to ETH_HLEN on slave removal
In reply to Sasha LevinFrom: Paolo Abeni <[email protected]>
[ Upstream commit 19cdead3e2ef8ed765c5d1ce48057ca9d97b5094 ]
On slave list updates, the bonding driver computes its hard_header_len as the maximum of all enslaved devices's hard_header_len. If the slave list is empty, e.g. on last enslaved device removal, ETH_HLEN is used.
Since the bonding header_ops are set only when the first enslaved device is attached, the above can lead to header_ops->create() being called with the wrong skb headroom in place.
If bond0 is configured on top of ipoib devices, with the following commands:
ifup bond0
for slave in $BOND_SLAVES_LIST; do
ip link set dev $slave nomaster
done
ping -c 1 <ip on bond0 subnet>
we will obtain a skb_under_panic() with a similar call trace:
skb_push+0x3d/0x40 push_pseudo_header+0x17/0x30 [ib_ipoib] ipoib_hard_header+0x4e/0x80 [ib_ipoib] arp_create+0x12f/0x220 arp_send_dst.part.19+0x28/0x50 arp_solicit+0x115/0x290 neigh_probe+0x4d/0x70 __neigh_event_send+0xa7/0x230 neigh_resolve_output+0x12e/0x1c0 ip_finish_output2+0x14b/0x390 ip_finish_output+0x136/0x1e0 ip_output+0x76/0xe0 ip_local_out+0x35/0x40 ip_send_skb+0x19/0x40 ip_push_pending_frames+0x33/0x40 raw_sendmsg+0x7d3/0xb50 inet_sendmsg+0x31/0xb0 sock_sendmsg+0x38/0x50 SYSC_sendto+0x102/0x190 SyS_sendto+0xe/0x10 do_syscall_64+0x67/0x180 entry_SYSCALL64_slow_path+0x25/0x25
This change addresses the issue avoiding updating the bonding device hard_header_len when the slaves list become empty, forbidding to shrink it below the value used by header_ops->create().
The bug is there since commit 54ef31371407 ("[PATCH] bonding: Handle large hard_header_len") but the panic can be triggered only since commit fc791b633515 ("IB/ipoib: move back IB LL address into the hard header").
--- drivers/net/bonding/bond_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/bonding/bond_main.c +1 -1
@@ -1106,11 +1106,11 @@ static void bond_compute_features(struct bonding *bond) gso_max_size =min (gso_max_size, slave->dev->gso_max_size); gso_max_segs =min (gso_max_segs, slave->dev->gso_max_segs); } + bond_dev->hard_header_len = max_hard_header_len; done: bond_dev->vlan_features = vlan_features; bond_dev->hw_enc_features = enc_features |NETIF_F_GSO_ENCAP_ALL ; - bond_dev->hard_header_len = max_hard_header_len; bond_dev->gso_max_segs = gso_max_segs;netif_set_gso_max_size (bond_dev, gso_max_size);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 62/65 scsi: aacraid: Fix typo in blink status
In reply to Sasha LevinFrom: Raghava Aditya Renukunta <[email protected]>
[ Upstream commit 934767c56b0d9dbb95a40e9e6e4d9dcdc3a165ad ]
The return status of the adapter check on KERNEL_PANIC is supposed to be the upper 16 bits of the OMR status register.
--- drivers/scsi/aacraid/src.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/aacraid/src.c +1 -1
@@ -444,7 +444,7 @@ static int aac_src_check_health(struct aac_dev *dev)return -1 ; err_blink: -return (status >16 ) &0xFF ; +return (status >>16 ) &0xFF ; }/**
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 63/65 MIPS: microMIPS: Fix decoding of swsp16 instruction
In reply to Sasha LevinFrom: Matt Redfearn <[email protected]>
[ Upstream commit cea8cd498f4f1c30ea27e3664b3c671e495c4fce ]
When the immediate encoded in the instruction is accessed, it is sign extended due to being a signed value being assigned to a signed integer. The ISA specifies that this operation is an unsigned operation. The sign extension leads us to incorrectly decode:
801e9c8e: cbf1 sw ra,68(sp)
As having an immediate of 1073741809.
Since the instruction format does not specify signed/unsigned, and this is currently the only location to use this instuction format, change it to an unsigned immediate.
Patchwork: https://patchwork.linux-mips.org/patch/16957/
--- arch/mips/include/uapi/asm/inst.h | 2 +- arch/mips/kernel/process.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
arch/mips/include/uapi/asm/inst.h +1 -1
@@ -846,7 +846,7 @@ struct mm16_r3_format { /* Load from global pointer format */ struct mm16_r5_format { /* Load/store from stack pointer format */ __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rt : 5, - __BITFIELD_FIELD(signed int simmediate : 5, + __BITFIELD_FIELD(unsigned int imm : 5, __BITFIELD_FIELD(unsigned int : 16, /* Ignored */ ;)))) };
arch/mips/kernel/process.c +1 -1
@@ -207,7 +207,7 @@ static inline int is_ra_save_ins(union mips_instruction *ip, int *poff)if (ip->mm16_r5_format.rt !=31 )return 0 ; - *poff = ip->mm16_r5_format.simmediate; + *poff = ip->mm16_r5_format.imm; *poff = (*poff <<2 ) /sizeof (ulong);return 1 ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 64/65 igb: Remove superfluous reset to PHY and page 0 selection
In reply to Sasha LevinFrom: Christian Grönke <[email protected]>
[ Upstream commit 2a83fba6cae89dd9c0625e68ff8ffff791c67ac0 ]
This patch reverts two previous applied patches to fix an issue that appeared when using SGMII based SFP modules. In the current state the driver will try to reset the PHY before obtaining the phy_addr of the SGMII attached PHY. That leads to an error in e1000_write_phy_reg_sgmii_82575. Causing the initialization to fail:
igb: Intel(R) Gigabit Ethernet Network Driver - version 5.4.0-k
igb: Copyright (c) 2007-2014 Intel Corporation.
igb: probe of ????:??:??.? failed with error -3The patches being reverted are:
commit 182785335447957409282ca745aa5bc3968facee
Author: Aaron Sierra <[email protected]>
Date: Tue Nov 29 10:03:56 2016 -0600
igb: reset the PHY before reading the PHY ID
commit 440aeca4b9858248d8f16d724d9fa87a4f65fa33
Author: Matwey V Kornilov <[email protected]>
Date: Thu Nov 24 13:32:48 2016 +0300
igb: Explicitly select page 0 at initialization
The first reverted patch directly causes the problem mentioned above. In case of SGMII the phy_addr is not known at this point and will only be obtained by 'igb_get_phy_id_82575' further down in the code. The second removed patch selects forces selection of page 0 in the PHY. Something that the reset tries to address as well.
As pointed out by Alexander Duzck, the patch below fixes the same issue but in the proper location:
commit 4e684f59d760a2c7c716bb60190783546e2d08a1
Author: Chris J Arges <[email protected]>
Date: Wed Nov 2 09:13:42 2016 -0500
igb: Workaround for igb i210 firmware issue
Reverts: 440aeca4b9858248d8f16d724d9fa87a4f65fa33.
Reverts: 182785335447957409282ca745aa5bc3968facee.
--- drivers/net/ethernet/intel/igb/e1000_82575.c | 11 ----------- 1 file changed, 11 deletions(-)
drivers/net/ethernet/intel/igb/e1000_82575.c +0 -11
@@ -223,17 +223,6 @@ static s32 igb_init_phy_params_82575(struct e1000_hw *hw) hw->bus.func = (rd32 (E1000_STATUS ) &E1000_STATUS_FUNC_MASK ) >>E1000_STATUS_FUNC_SHIFT ; -/* Make sure the PHY is in a good state. Several people have reported -* firmware leaving the PHY's page select register set to something -* other than the default of zero, which causes the PHY ID read to -* access something other than the intended register. -*/ - ret_val = hw->phy.ops.reset (hw); -if (ret_val) { -hw_dbg ("Error resetting the PHY.\n" ); - goto out; - } -/* Set phy->phy_addr and phy->id. */ ret_val =igb_get_phy_id_82575 (hw);if (ret_val)
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 65/65 MIPS: DEC: Fix an int-handler.S CPU_DADDI_WORKAROUNDS regression
In reply to Sasha LevinFrom: "Maciej W. Rozycki" <[email protected]>
[ Upstream commit 68fe55680d0f3342969f49412fceabb90bdfadba ]
Fix a commit 3021773c7c3e ("MIPS: DEC: Avoid la pseudo-instruction in delay slots") regression and remove assembly errors:
arch/mips/dec/int-handler.S: Assembler messages:arch/mips/dec/int-handler.S:162: Error: Macro used $at after ".set noat" arch/mips/dec/int-handler.S:163: Error: Macro used $at after ".set noat" arch/mips/dec/int-handler.S:229: Error: Macro used $at after ".set noat" arch/mips/dec/int-handler.S:230: Error: Macro used $at after ".set noat"
triggering with with the CPU_DADDI_WORKAROUNDS option set and the DADDIU instruction. This is because with that option in place the instruction becomes a macro, which expands to an LI/DADDU (or actually ADDIU/DADDU) sequence that uses $at as a temporary register.
With CPU_DADDI_WORKAROUNDS we only support `-msym32' compilation though, and this is already enforced in arch/mips/Makefile, so choose the 32-bit expansion variant for the supported configurations and then replace the 64-bit variant with #error just in case.
Patchwork: https://patchwork.linux-mips.org/patch/16893/
--- arch/mips/dec/int-handler.S | 34 ++++++---------------------------- 1 file changed, 6 insertions(+), 28 deletions(-)
arch/mips/dec/int-handler.S +6 -28
@@ -147,23 +147,12 @@ * Find irq with highest priority */ # open coded PTR_LA t1, cpu_mask_nr_tbl -#if (_MIPS_SZPTR == 32) +#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32) # open coded la t1, cpu_mask_nr_tbl lui t1, %hi(cpu_mask_nr_tbl) addiu t1, %lo(cpu_mask_nr_tbl) - -#endif -#if (_MIPS_SZPTR == 64) - # open coded dla t1, cpu_mask_nr_tbl - .set push - .set noat - lui t1, %highest(cpu_mask_nr_tbl) - lui AT, %hi(cpu_mask_nr_tbl) - daddiu t1, t1, %higher(cpu_mask_nr_tbl) - daddiu AT, AT, %lo(cpu_mask_nr_tbl) - dsll t1, 32 - daddu t1, t1, AT - .set pop +#else +#error GCC `-msym32' option required for 64-bit DECstation builds #endif 1: lw t2,(t1) nop
@@ -214,23 +203,12 @@ * Find irq with highest priority */ # open coded PTR_LA t1,asic_mask_nr_tbl -#if (_MIPS_SZPTR == 32) +#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32) # open coded la t1, asic_mask_nr_tbl lui t1, %hi(asic_mask_nr_tbl) addiu t1, %lo(asic_mask_nr_tbl) - -#endif -#if (_MIPS_SZPTR == 64) - # open coded dla t1, asic_mask_nr_tbl - .set push - .set noat - lui t1, %highest(asic_mask_nr_tbl) - lui AT, %hi(asic_mask_nr_tbl) - daddiu t1, t1, %higher(asic_mask_nr_tbl) - daddiu AT, AT, %lo(asic_mask_nr_tbl) - dsll t1, 32 - daddu t1, t1, AT - .set pop +#else +#error GCC `-msym32' option required for 64-bit DECstation builds #endif 2: lw t2,(t1) nop
Signature · 1 line
2.17.1