diff options
author | Amit Pundir <amit.pundir@linaro.org> | 2015-09-11 00:06:45 +0530 |
---|---|---|
committer | Amit Pundir <amit.pundir@linaro.org> | 2015-09-11 00:32:41 +0530 |
commit | 27dbd0a8ae942d1cf6f6bb3d99744fae7cca155f (patch) | |
tree | 2253c2a716e7b6713345e72bdb22928f5524e8a0 | |
parent | 46505bc0b16772238fe481c38718b415a280530c (diff) | |
parent | 3ac97f2411ad66f872bd0fe401ad94af5ff4d7d3 (diff) |
Merge branch 'android-3.18' of https://android.googlesource.com/kernel/commontracking-linaro-android-llct-llct-20150910.0
* android-3.18:
net: fix crash in tcp_nuke_addr()
net: xt_qtaguid/xt_socket: fix refcount underflow and crash
net: fix iterating over hashtable in tcp_nuke_addr()
nf: IDLETIMER: fix lockdep warning
ANDROID: usb: gadget: create F_midi device
usb: gadget: midi: avoid redundant f_midi_set_alt() call
usb: gadget: f_midi: fix error recovery path
usb: gadget: f_midi: fix segfault when reading empty id
usb: gadget: fix misspelling of current function in string
usb: gadget: midi: f_midi_alloc() can be static
usb: gadget: f_midi: add configfs support
usb: gadget: f_midi: use usb_gstrings_attach
usb: gadget: f_midi: remove compatibility layer
usb: gadget: f_midi: convert to new function interface with backward compatibility
usb: gadget: f_midi: check kstrdup() return value
usb: gadget: f_midi: enable use of the index parameter
usb: gadget: configfs: Fix interfaces array NULL-termination
usb: gadget: Add device attribute to determine gadget state
usb: phy: fix dual role sysfs build if kernel modules are supported
ion: Handle the memory mapping correctly on x86
Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
Conflicts:
drivers/usb/gadget/Kconfig
drivers/usb/gadget/function/Makefile
drivers/usb/gadget/legacy/gmidi.c
==> All the conflicts in these ^^ files are due to merging
of AOSP backport of upstream Midi USB gadget. So keep the
upstream changes and discard AOSP changes.
drivers/usb/gadget/configfs.c
==> Add changes from AOSP commit 492097142eef "usb: gadget:
Add device attribute to determine gadget state" and remove
linaro fix commit acfdf575920d "usb: gadget: configfs: fix
unused variable warnings".
drivers/usb/gadget/function/f_midi.c
==> Add changes from AOSP commit 19088ddf7fd9
"ANDROID: usb: gadget: create F_midi device".
net/ipv4/tcp.c
==> Add changes from AOSP commit 3ac97f2411ad "net: fix
crash in tcp_nuke_addr()" and remove linaro fix commit
33e405ea3985 "net/ipv4: android: don't nuke sockets on
TCP_TIME_WAIT"
net/netfilter/xt_socket.c
==> Add changes from AOSP commit 6265ed1db967 "net:
xt_qtaguid/xt_socket: fix refcount underflow and crash".
-rw-r--r-- | drivers/staging/android/ion/Kconfig | 7 | ||||
-rw-r--r-- | drivers/staging/android/ion/ion_page_pool.c | 8 | ||||
-rw-r--r-- | drivers/staging/android/ion/ion_priv.h | 34 | ||||
-rw-r--r-- | drivers/staging/android/ion/ion_system_heap.c | 6 | ||||
-rw-r--r-- | drivers/usb/gadget/configfs.c | 87 | ||||
-rw-r--r-- | drivers/usb/gadget/function/f_midi.c | 69 | ||||
-rw-r--r-- | net/ipv4/tcp.c | 15 | ||||
-rw-r--r-- | net/netfilter/xt_socket.c | 33 |
8 files changed, 213 insertions, 46 deletions
diff --git a/drivers/staging/android/ion/Kconfig b/drivers/staging/android/ion/Kconfig index 345234624492..301948cc48bd 100644 --- a/drivers/staging/android/ion/Kconfig +++ b/drivers/staging/android/ion/Kconfig @@ -33,3 +33,10 @@ config ION_TEGRA help Choose this option if you wish to use ion on an nVidia Tegra. +config ION_POOL_CACHE_POLICY + bool "Ion set page pool cache policy" + depends on ION + default y if X86 + help + Choose this option if need to explicity set cache policy of the + pages in the page pool. diff --git a/drivers/staging/android/ion/ion_page_pool.c b/drivers/staging/android/ion/ion_page_pool.c index 4b88f11e52d3..b0217488ef92 100644 --- a/drivers/staging/android/ion/ion_page_pool.c +++ b/drivers/staging/android/ion/ion_page_pool.c @@ -30,6 +30,8 @@ static void *ion_page_pool_alloc_pages(struct ion_page_pool *pool) if (!page) return NULL; + ion_page_pool_alloc_set_cache_policy(pool, page); + ion_pages_sync_for_device(NULL, page, PAGE_SIZE << pool->order, DMA_BIDIRECTIONAL); return page; @@ -38,6 +40,7 @@ static void *ion_page_pool_alloc_pages(struct ion_page_pool *pool) static void ion_page_pool_free_pages(struct ion_page_pool *pool, struct page *page) { + ion_page_pool_free_set_cache_policy(pool, page); __free_pages(page, pool->order); } @@ -103,6 +106,11 @@ void ion_page_pool_free(struct ion_page_pool *pool, struct page *page) ion_page_pool_free_pages(pool, page); } +void ion_page_pool_free_immediate(struct ion_page_pool *pool, struct page *page) +{ + ion_page_pool_free_pages(pool, page); +} + static int ion_page_pool_total(struct ion_page_pool *pool, bool high) { int count = pool->low_count; diff --git a/drivers/staging/android/ion/ion_priv.h b/drivers/staging/android/ion/ion_priv.h index 52f1cd1a67ed..b8bf87aceb34 100644 --- a/drivers/staging/android/ion/ion_priv.h +++ b/drivers/staging/android/ion/ion_priv.h @@ -26,6 +26,9 @@ #include <linux/sched.h> #include <linux/shrinker.h> #include <linux/types.h> +#ifdef CONFIG_ION_POOL_CACHE_POLICY +#include <asm/cacheflush.h> +#endif #include "ion.h" @@ -380,6 +383,37 @@ struct ion_page_pool *ion_page_pool_create(gfp_t gfp_mask, unsigned int order); void ion_page_pool_destroy(struct ion_page_pool *); struct page *ion_page_pool_alloc(struct ion_page_pool *); void ion_page_pool_free(struct ion_page_pool *, struct page *); +void ion_page_pool_free_immediate(struct ion_page_pool *, struct page *); + +#ifdef CONFIG_ION_POOL_CACHE_POLICY +static inline void ion_page_pool_alloc_set_cache_policy + (struct ion_page_pool *pool, + struct page *page){ + void *va = page_address(page); + + if (va) + set_memory_wc((unsigned long)va, 1 << pool->order); +} + +static inline void ion_page_pool_free_set_cache_policy + (struct ion_page_pool *pool, + struct page *page){ + void *va = page_address(page); + + if (va) + set_memory_wb((unsigned long)va, 1 << pool->order); + +} +#else +static inline void ion_page_pool_alloc_set_cache_policy + (struct ion_page_pool *pool, + struct page *page){ } + +static inline void ion_page_pool_free_set_cache_policy + (struct ion_page_pool *pool, + struct page *page){ } +#endif + /** ion_page_pool_shrink - shrinks the size of the memory cached in the pool * @pool: the pool diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c index da2a63c0a9ba..1f9feb7480b2 100644 --- a/drivers/staging/android/ion/ion_system_heap.c +++ b/drivers/staging/android/ion/ion_system_heap.c @@ -85,8 +85,10 @@ static void free_buffer_page(struct ion_system_heap *heap, if (!cached && !(buffer->private_flags & ION_PRIV_FLAG_SHRINKER_FREE)) { struct ion_page_pool *pool = heap->pools[order_to_index(order)]; - - ion_page_pool_free(pool, page); + if (buffer->private_flags & ION_PRIV_FLAG_SHRINKER_FREE) + ion_page_pool_free_immediate(pool, page); + else + ion_page_pool_free(pool, page); } else { __free_pages(page, order); } diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index 00a0fb5321a0..570a5f421c01 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -1651,6 +1651,54 @@ static struct device_attribute *android_usb_attributes[] = { &dev_attr_state, NULL }; + +static int android_device_create(struct gadget_info *gi) +{ + struct device_attribute **attrs; + struct device_attribute *attr; + + INIT_WORK(&gi->work, android_work); + android_device = device_create(android_class, NULL, + MKDEV(0, 0), NULL, "android0"); + if (IS_ERR(android_device)) + return PTR_ERR(android_device); + + dev_set_drvdata(android_device, gi); + + attrs = android_usb_attributes; + while ((attr = *attrs++)) { + int err; + + err = device_create_file(android_device, attr); + if (err) { + device_destroy(android_device->class, + android_device->devt); + return err; + } + } + + return 0; +} + +static void android_device_destroy(void) +{ + struct device_attribute **attrs; + struct device_attribute *attr; + + attrs = android_usb_attributes; + while ((attr = *attrs++)) + device_remove_file(android_device, attr); + device_destroy(android_device->class, android_device->devt); +} +#else +static inline int android_device_create(struct gadget_info *gi) +{ + return 0; +} + +static inline void android_device_destroy(void) +{ +} #endif static struct config_group *gadgets_make( @@ -1658,11 +1706,9 @@ static struct config_group *gadgets_make( const char *name) { struct gadget_info *gi; -#ifdef CONFIG_USB_CONFIGFS_UEVENT struct device_attribute **attrs; struct device_attribute *attr; int err; -#endif gi = kzalloc(sizeof(*gi), GFP_KERNEL); if (!gi) @@ -1702,25 +1748,11 @@ static struct config_group *gadgets_make( gi->composite.gadget_driver.function = kstrdup(name, GFP_KERNEL); gi->composite.name = gi->composite.gadget_driver.function; -#ifdef CONFIG_USB_CONFIGFS_UEVENT - INIT_WORK(&gi->work, android_work); - android_device = device_create(android_class, NULL, - MKDEV(0, 0), NULL, "android0"); - if (IS_ERR(android_device)) + if (!gi->composite.gadget_driver.function) goto err; - dev_set_drvdata(android_device, gi); - - attrs = android_usb_attributes; - while ((attr = *attrs++)) { - err = device_create_file(android_device, attr); - if (err) - goto err1; - } -#endif - - if (!gi->composite.gadget_driver.function) - goto err1; + if (android_device_create(gi) < 0) + goto err; #ifdef CONFIG_USB_OTG gi->otg.bLength = sizeof(struct usb_otg_descriptor); @@ -1732,33 +1764,18 @@ static struct config_group *gadgets_make( &gadget_root_type); return &gi->group; -err1: -#ifdef CONFIG_USB_CONFIGFS_UEVENT - attrs = android_usb_attributes; - while ((attr = *attrs++)) - device_remove_file(android_device, attr); - - device_destroy(android_device->class, - android_device->devt); err: -#endif kfree(gi); return ERR_PTR(-ENOMEM); } static void gadgets_drop(struct config_group *group, struct config_item *item) { -#ifdef CONFIG_USB_CONFIGFS_UEVENT struct device_attribute **attrs; struct device_attribute *attr; - attrs = android_usb_attributes; - while ((attr = *attrs++)) - device_remove_file(android_device, attr); - device_destroy(android_device->class, android_device->devt); -#endif - config_item_put(item); + android_device_destroy(); } static struct configfs_group_operations gadgets_ops = { diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c index ad50a67c1465..ee1bfc905fb9 100644 --- a/drivers/usb/gadget/function/f_midi.c +++ b/drivers/usb/gadget/function/f_midi.c @@ -329,6 +329,10 @@ static int f_midi_set_alt(struct usb_function *f, unsigned intf, unsigned alt) unsigned i; int err; + /* For Control Device interface we do nothing */ + if (intf == 0) + return 0; + err = f_midi_start_ep(midi, f, midi->in_ep); if (err) return err; @@ -1044,6 +1048,65 @@ static void f_midi_free_inst(struct usb_function_instance *f) kfree(opts); } +#ifdef CONFIG_USB_CONFIGFS_UEVENT +extern struct device *create_function_device(char *name); +static ssize_t alsa_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct usb_function_instance *fi_midi = dev_get_drvdata(dev); + struct f_midi *midi; + + if (!fi_midi->f) + dev_warn(dev, "f_midi: function not set\n"); + + if (fi_midi && fi_midi->f) { + midi = func_to_midi(fi_midi->f); + if (midi->rmidi && midi->rmidi->card) + return sprintf(buf, "%d %d\n", + midi->rmidi->card->number, midi->rmidi->device); + } + + /* print PCM card and device numbers */ + return sprintf(buf, "%d %d\n", -1, -1); +} + +static DEVICE_ATTR(alsa, S_IRUGO, alsa_show, NULL); + +static struct device_attribute *alsa_function_attributes[] = { + &dev_attr_alsa, + NULL +}; + +static int create_alsa_device(struct usb_function_instance *fi) +{ + struct device *dev; + struct device_attribute **attrs; + struct device_attribute *attr; + int err = 0; + + dev = create_function_device("f_midi"); + if (IS_ERR(dev)) + return PTR_ERR(dev); + + attrs = alsa_function_attributes; + if (attrs) { + while ((attr = *attrs++) && !err) + err = device_create_file(dev, attr); + if (err) { + device_destroy(dev->class, dev->devt); + return -EINVAL; + } + } + dev_set_drvdata(dev, fi); + return 0; +} +#else +static int create_alsa_device(struct usb_function_instance *fi) +{ + return 0; +} +#endif + static struct usb_function_instance *f_midi_alloc_inst(void) { struct f_midi_opts *opts; @@ -1061,6 +1124,11 @@ static struct usb_function_instance *f_midi_alloc_inst(void) opts->in_ports = 1; opts->out_ports = 1; + if (create_alsa_device(&opts->func_inst)) { + kfree(opts); + return ERR_PTR(-ENODEV); + } + config_group_init_type_name(&opts->func_inst.group, "", &midi_func_type); @@ -1162,6 +1230,7 @@ static struct usb_function *f_midi_alloc(struct usb_function_instance *fi) midi->func.disable = f_midi_disable; midi->func.free_func = f_midi_free; + fi->f = &midi->func; return &midi->func; setup_fail: diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index b0d011e153d3..bb96a939940e 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -3244,7 +3244,7 @@ int tcp_nuke_addr(struct net *net, struct sockaddr *addr) return -EAFNOSUPPORT; } - for (bucket = 0; bucket < tcp_hashinfo.ehash_mask; bucket++) { + for (bucket = 0; bucket <= tcp_hashinfo.ehash_mask; bucket++) { struct hlist_nulls_node *node; struct sock *sk; spinlock_t *lock = inet_ehash_lockp(&tcp_hashinfo, bucket); @@ -3254,10 +3254,19 @@ restart: sk_nulls_for_each(sk, node, &tcp_hashinfo.ehash[bucket].chain) { struct inet_sock *inet = inet_sk(sk); - if (sysctl_ip_dynaddr && sk->sk_state == TCP_SYN_SENT) + if (sk->sk_state == TCP_TIME_WAIT) { + /* + * Sockets that are in TIME_WAIT state are + * instances of lightweight inet_timewait_sock, + * we should simply skip them (or we'll try to + * access non-existing fields and crash). + */ continue; - if (sk->sk_state == TCP_TIME_WAIT) + } + + if (sysctl_ip_dynaddr && sk->sk_state == TCP_SYN_SENT) continue; + if (sock_flag(sk, SOCK_DEAD)) continue; diff --git a/net/netfilter/xt_socket.c b/net/netfilter/xt_socket.c index 6941c9783da7..fedcbb793b89 100644 --- a/net/netfilter/xt_socket.c +++ b/net/netfilter/xt_socket.c @@ -197,8 +197,19 @@ struct sock *xt_socket_lookup_slow_v4(const struct sk_buff *skb, } #endif - return xt_socket_get_sock_v4(dev_net(skb->dev), protocol, saddr, daddr, - sport, dport, indev); + if (sk) + atomic_inc(&sk->sk_refcnt); + else + sk = xt_socket_get_sock_v4(dev_net(skb->dev), protocol, + saddr, daddr, sport, dport, + par->in); + + pr_debug("proto %hhu %pI4:%hu -> %pI4:%hu (orig %pI4:%hu) sock %p\n", + protocol, &saddr, ntohs(sport), + &daddr, ntohs(dport), + &iph->daddr, hp ? ntohs(hp->dest) : 0, sk); + + return sk; } EXPORT_SYMBOL(xt_socket_lookup_slow_v4); @@ -232,8 +243,7 @@ socket_match(const struct sk_buff *skb, struct xt_action_param *par, transparent) pskb->mark = sk->sk_mark; - if (sk != skb->sk) - sock_gen_put(sk); + sock_gen_put(sk); if (wildcard || !transparent) sk = NULL; @@ -372,8 +382,19 @@ struct sock *xt_socket_lookup_slow_v6(const struct sk_buff *skb, return NULL; } - return xt_socket_get_sock_v6(dev_net(skb->dev), tproto, saddr, daddr, - sport, dport, indev); + if (sk) + atomic_inc(&sk->sk_refcnt); + else + sk = xt_socket_get_sock_v6(dev_net(skb->dev), tproto, + saddr, daddr, sport, dport, + par->in); + + pr_debug("proto %hhd %pI6:%hu -> %pI6:%hu " + "(orig %pI6:%hu) sock %p\n", + tproto, saddr, ntohs(sport), + daddr, ntohs(dport), + &iph->daddr, hp ? ntohs(hp->dest) : 0, sk); + return sk; } EXPORT_SYMBOL(xt_socket_lookup_slow_v6); |