aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmit Pundir <amit.pundir@linaro.org>2015-09-11 00:06:45 +0530
committerAmit Pundir <amit.pundir@linaro.org>2015-09-11 00:32:41 +0530
commit27dbd0a8ae942d1cf6f6bb3d99744fae7cca155f (patch)
tree2253c2a716e7b6713345e72bdb22928f5524e8a0
parent46505bc0b16772238fe481c38718b415a280530c (diff)
parent3ac97f2411ad66f872bd0fe401ad94af5ff4d7d3 (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/Kconfig7
-rw-r--r--drivers/staging/android/ion/ion_page_pool.c8
-rw-r--r--drivers/staging/android/ion/ion_priv.h34
-rw-r--r--drivers/staging/android/ion/ion_system_heap.c6
-rw-r--r--drivers/usb/gadget/configfs.c87
-rw-r--r--drivers/usb/gadget/function/f_midi.c69
-rw-r--r--net/ipv4/tcp.c15
-rw-r--r--net/netfilter/xt_socket.c33
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);