From 04f87da71ab532ee1d794cbb2a464d2f35cd118d Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 23 Aug 2011 14:50:29 +0200 Subject: block: separate priority boosting from REQ_META Add a new REQ_PRIO to let requests preempt others in the cfq I/O schedule, and lave REQ_META purely for marking requests as metadata in blktrace. All existing callers of REQ_META except for XFS are updated to also set REQ_PRIO for now. Backported to 3.0.x by Ketut Putu Kumajaya Change-Id: Iad5ba7a105438776f74788c0aedaf85210c613f9 --- include/linux/blk_types.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h index 6395692..cee53e3 100644 --- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h @@ -124,6 +124,7 @@ enum rq_flag_bits { __REQ_SYNC, /* request is sync (sync write or read) */ __REQ_META, /* metadata io request */ + __REQ_PRIO, /* boost priority in cfq */ __REQ_DISCARD, /* request to discard sectors */ __REQ_NOIDLE, /* don't anticipate more IO after this one */ @@ -160,14 +161,15 @@ enum rq_flag_bits { #define REQ_FAILFAST_DRIVER (1 << __REQ_FAILFAST_DRIVER) #define REQ_SYNC (1 << __REQ_SYNC) #define REQ_META (1 << __REQ_META) +#define REQ_PRIO (1 << __REQ_PRIO) #define REQ_DISCARD (1 << __REQ_DISCARD) #define REQ_NOIDLE (1 << __REQ_NOIDLE) #define REQ_FAILFAST_MASK \ (REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER) #define REQ_COMMON_MASK \ - (REQ_WRITE | REQ_FAILFAST_MASK | REQ_SYNC | REQ_META | REQ_DISCARD | \ - REQ_NOIDLE | REQ_FLUSH | REQ_FUA | REQ_SECURE) + (REQ_WRITE | REQ_FAILFAST_MASK | REQ_SYNC | REQ_META | REQ_PRIO | \ + REQ_DISCARD | REQ_NOIDLE | REQ_FLUSH | REQ_FUA | REQ_SECURE) #define REQ_CLONE_MASK REQ_COMMON_MASK #define REQ_RAHEAD (1 << __REQ_RAHEAD) -- cgit v1.1 From 5e60df5a7c346658adad7e8eafb1450491a660bb Mon Sep 17 00:00:00 2001 From: Hannes Frederic Sowa Date: Mon, 14 Dec 2015 22:03:39 +0100 Subject: net: add validation for the socket syscall protocol argument MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 郭永刚 reported that one could simply crash the kernel as root by using a simple program: int socket_fd; struct sockaddr_in addr; addr.sin_port = 0; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_family = 10; socket_fd = socket(10,3,0x40000000); connect(socket_fd , &addr,16); AF_INET, AF_INET6 sockets actually only support 8-bit protocol identifiers. inet_sock's skc_protocol field thus is sized accordingly, thus larger protocol identifiers simply cut off the higher bits and store a zero in the protocol fields. This could lead to e.g. NULL function pointer because as a result of the cut off inet_num is zero and we call down to inet_autobind, which is NULL for raw sockets. kernel: Call Trace: kernel: [] ? inet_autobind+0x2e/0x70 kernel: [] inet_dgram_connect+0x54/0x80 kernel: [] SYSC_connect+0xd9/0x110 kernel: [] ? ptrace_notify+0x5b/0x80 kernel: [] ? syscall_trace_enter_phase2+0x108/0x200 kernel: [] SyS_connect+0xe/0x10 kernel: [] tracesys_phase2+0x84/0x89 I found no particular commit which introduced this problem. Change-Id: If01a1f7d3c652e8e67d5090eb8ea91389829b2ea CVE: CVE-2015-8543 Cc: Cong Wang Reported-by: 郭永刚 Signed-off-by: Hannes Frederic Sowa Signed-off-by: David S. Miller --- include/net/sock.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/net/sock.h b/include/net/sock.h index b6abd4f..1831207 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -303,6 +303,7 @@ struct sock { sk_no_check : 2, sk_userlocks : 4, sk_protocol : 8, +#define SK_PROTOCOL_MAX U8_MAX sk_type : 16; kmemcheck_bitfield_end(flags); int sk_wmem_queued; -- cgit v1.1 From a7a9d8516ec987f32d62e33594210a0fee392498 Mon Sep 17 00:00:00 2001 From: Andrey Vagin Date: Fri, 28 Mar 2014 13:54:32 +0400 Subject: netfilter: nf_conntrack: reserve two bytes for nf_ct_ext->len "len" contains sizeof(nf_ct_ext) and size of extensions. In a worst case it can contain all extensions. Bellow you can find sizes for all types of extensions. Their sum is definitely bigger than 256. nf_ct_ext_types[0]->len = 24 nf_ct_ext_types[1]->len = 32 nf_ct_ext_types[2]->len = 24 nf_ct_ext_types[3]->len = 32 nf_ct_ext_types[4]->len = 152 nf_ct_ext_types[5]->len = 2 nf_ct_ext_types[6]->len = 16 nf_ct_ext_types[7]->len = 8 I have seen "len" up to 280 and my host has crashes w/o this patch. The right way to fix this problem is reducing the size of the ecache extension (4) and Florian is going to do this, but these changes will be quite large to be appropriate for a stable tree. Change-Id: Id44470ab1d54526993927cdda68342e591a5d6c3 Fixes: 5b423f6a40a0 (netfilter: nf_conntrack: fix racy timer handling with reliable) Cc: Pablo Neira Ayuso Cc: Patrick McHardy Cc: Jozsef Kadlecsik Cc: "David S. Miller" Signed-off-by: Andrey Vagin Signed-off-by: Pablo Neira Ayuso --- include/net/netfilter/nf_conntrack_extend.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/net/netfilter/nf_conntrack_extend.h b/include/net/netfilter/nf_conntrack_extend.h index 2dcf317..d918074 100644 --- a/include/net/netfilter/nf_conntrack_extend.h +++ b/include/net/netfilter/nf_conntrack_extend.h @@ -33,8 +33,8 @@ enum nf_ct_ext_id { /* Extensions: optional stuff which isn't permanently in struct. */ struct nf_ct_ext { struct rcu_head rcu; - u8 offset[NF_CT_EXT_NUM]; - u8 len; + u16 offset[NF_CT_EXT_NUM]; + u16 len; char data[0]; }; -- cgit v1.1 From 13696bfd759e22d99eab7a81b18341b05772aad4 Mon Sep 17 00:00:00 2001 From: Hannes Frederic Sowa Date: Fri, 23 Jan 2015 12:01:26 +0100 Subject: ipv4: try to cache dst_entries which would cause a redirect Not caching dst_entries which cause redirects could be exploited by hosts on the same subnet, causing a severe DoS attack. This effect aggravated since commit f88649721268999 ("ipv4: fix dst race in sk_dst_get()"). Lookups causing redirects will be allocated with DST_NOCACHE set which will force dst_release to free them via RCU. Unfortunately waiting for RCU grace period just takes too long, we can end up with >1M dst_entries waiting to be released and the system will run OOM. rcuos threads cannot catch up under high softirq load. Attaching the flag to emit a redirect later on to the specific skb allows us to cache those dst_entries thus reducing the pressure on allocation and deallocation. This issue was discovered by Marcelo Leitner. Cc: Julian Anastasov Signed-off-by: Marcelo Leitner Signed-off-by: Florian Westphal Signed-off-by: Hannes Frederic Sowa Signed-off-by: Julian Anastasov Signed-off-by: David S. Miller Conflicts: include/net/ip.h net/ipv4/route.c Change-Id: I53e4b500a4db2f5fece937a42a3bd810b2640c44 --- include/net/ip.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/net/ip.h b/include/net/ip.h index 29e31ae..8729846 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -37,11 +37,12 @@ struct inet_skb_parm { struct ip_options opt; /* Compiled IP options */ unsigned char flags; -#define IPSKB_FORWARDED 1 -#define IPSKB_XFRM_TUNNEL_SIZE 2 -#define IPSKB_XFRM_TRANSFORMED 4 -#define IPSKB_FRAG_COMPLETE 8 -#define IPSKB_REROUTED 16 +#define IPSKB_FORWARDED BIT(0) +#define IPSKB_XFRM_TUNNEL_SIZE BIT(1) +#define IPSKB_XFRM_TRANSFORMED BIT(2) +#define IPSKB_FRAG_COMPLETE BIT(3) +#define IPSKB_REROUTED BIT(4) +#define IPSKB_DOREDIRECT BIT(5) }; static inline unsigned int ip_hdrlen(const struct sk_buff *skb) -- cgit v1.1 From 0280906bb6e2548b41cb6788e3ec62feb1749db8 Mon Sep 17 00:00:00 2001 From: Vasily Kulikov Date: Fri, 8 Jan 2016 11:19:14 -0500 Subject: include/linux/poison.h: fix LIST_POISON{1,2} offset Poison pointer values should be small enough to find a room in non-mmap'able/hardly-mmap'able space. E.g. on x86 "poison pointer space" is located starting from 0x0. Given unprivileged users cannot mmap anything below mmap_min_addr, it should be safe to use poison pointers lower than mmap_min_addr. The current poison pointer values of LIST_POISON{1,2} might be too big for mmap_min_addr values equal or less than 1 MB (common case, e.g. Ubuntu uses only 0x10000). There is little point to use such a big value given the "poison pointer space" below 1 MB is not yet exhausted. Changing it to a smaller value solves the problem for small mmap_min_addr setups. The values are suggested by Solar Designer: http://www.openwall.com/lists/oss-security/2015/05/02/6 Bug: 26186802 Change-Id: I2663f4e4d8725547c90ea14e082f10ae0cf80679 Signed-off-by: Yuan Lin --- include/linux/poison.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/poison.h b/include/linux/poison.h index 2110a81..253c9b4 100644 --- a/include/linux/poison.h +++ b/include/linux/poison.h @@ -19,8 +19,8 @@ * under normal circumstances, used to verify that nobody uses * non-initialized list entries. */ -#define LIST_POISON1 ((void *) 0x00100100 + POISON_POINTER_DELTA) -#define LIST_POISON2 ((void *) 0x00200200 + POISON_POINTER_DELTA) +#define LIST_POISON1 ((void *) 0x100 + POISON_POINTER_DELTA) +#define LIST_POISON2 ((void *) 0x200 + POISON_POINTER_DELTA) /********** include/linux/timer.h **********/ /* -- cgit v1.1 From 260325caf43c98bd8ca8146ffe4730017ebdab44 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Mon, 28 Jul 2014 16:26:53 -0700 Subject: mnt: Only change user settable mount flags in remount commit a6138db815df5ee542d848318e5dae681590fccd upstream. Kenton Varda discovered that by remounting a read-only bind mount read-only in a user namespace the MNT_LOCK_READONLY bit would be cleared, allowing an unprivileged user to the remount a read-only mount read-write. Correct this by replacing the mask of mount flags to preserve with a mask of mount flags that may be changed, and preserve all others. This ensures that any future bugs with this mask and remount will fail in an easy to detect way where new mount flags simply won't change. Change-Id: I8ab8bda03a14b9b43e78f1dc6c818bbec048e986 Acked-by: Serge E. Hallyn Signed-off-by: "Eric W. Biederman" Cc: Francis Moreau Signed-off-by: Zefan Li --- include/linux/mount.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/mount.h b/include/linux/mount.h index 604f122..dacabd6 100644 --- a/include/linux/mount.h +++ b/include/linux/mount.h @@ -42,7 +42,9 @@ struct mnt_namespace; * flag, consider how it interacts with shared mounts. */ #define MNT_SHARED_MASK (MNT_UNBINDABLE) -#define MNT_PROPAGATION_MASK (MNT_SHARED | MNT_UNBINDABLE) +#define MNT_USER_SETTABLE_MASK (MNT_NOSUID | MNT_NODEV | MNT_NOEXEC \ + | MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME \ + | MNT_READONLY) #define MNT_INTERNAL 0x4000 -- cgit v1.1 From b6e29030f9325ccc841ad02e4687dedf6d9bba08 Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Fri, 20 Dec 2013 15:10:03 +0200 Subject: mm: Fix NULL pointer dereference in madvise(MADV_WILLNEED) support Sasha Levin found a NULL pointer dereference that is due to a missing page table lock, which in turn is due to the pmd entry in question being a transparent huge-table entry. The code - introduced in commit 1998cc048901 ("mm: make madvise(MADV_WILLNEED) support swap file prefetch") - correctly checks for this situation using pmd_none_or_trans_huge_or_clear_bad(), but it turns out that that function doesn't work correctly. pmd_none_or_trans_huge_or_clear_bad() expected that pmd_bad() would trigger if the transparent hugepage bit was set, but it doesn't do that if pmd_numa() is also set. Note that the NUMA bit only gets set on real NUMA machines, so people trying to reproduce this on most normal development systems would never actually trigger this. Fix it by removing the very subtle (and subtly incorrect) expectation, and instead just checking pmd_trans_huge() explicitly. Reported-by: Sasha Levin Acked-by: Andrea Arcangeli [ Additionally remove the now stale test for pmd_trans_huge() inside the pmd_bad() case - Linus ] Signed-off-by: Linus Torvalds Change-Id: I3f3763f236ef102de735297cd175cf514d40d28f --- include/asm-generic/pgtable.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h index 831924a..2fda790 100644 --- a/include/asm-generic/pgtable.h +++ b/include/asm-generic/pgtable.h @@ -488,11 +488,10 @@ static inline int pmd_none_or_trans_huge_or_clear_bad(pmd_t *pmd) #ifdef CONFIG_TRANSPARENT_HUGEPAGE barrier(); #endif - if (pmd_none(pmdval)) + if (pmd_none(pmdval) || pmd_trans_huge(pmdval)) return 1; if (unlikely(pmd_bad(pmdval))) { - if (!pmd_trans_huge(pmdval)) - pmd_clear_bad(pmd); + pmd_clear_bad(pmd); return 1; } return 0; -- cgit v1.1 From 60d05551c60819bea1c8cfe1e5427a47a21bccd1 Mon Sep 17 00:00:00 2001 From: Sabrina Dubroca Date: Thu, 15 Oct 2015 12:25:00 -0500 Subject: net: add length argument to skb_copy_and_csum_datagram_iovec Without this length argument, we can read past the end of the iovec in memcpy_toiovec because we have no way of knowing the total length of the iovec's buffers. This is needed for stable kernels where 89c22d8c3b27 ("net: Fix skb csum races when peeking") has been backported but that don't have the ioviter conversion, which is almost all the stable trees <= 3.18. This also fixes a kernel crash for NFS servers when the client uses -onfsvers=3,proto=udp to mount the export. Change-Id: I1865e3d7a1faee42a5008a9ad58c4d3323ea4bab Signed-off-by: Sabrina Dubroca Reviewed-by: Hannes Frederic Sowa (cherry picked from commit c91234366e4cfd4f70c73e7d79ede92a6e462a88) --- include/linux/skbuff.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index f430316..cfcbb17 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -1863,7 +1863,8 @@ extern int skb_copy_datagram_iovec(const struct sk_buff *from, int size); extern int skb_copy_and_csum_datagram_iovec(struct sk_buff *skb, int hlen, - struct iovec *iov); + struct iovec *iov, + int len); extern int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset, const struct iovec *from, -- cgit v1.1 From f0f6cbaf4d48a251a2a37078f82ae96c4f6079fe Mon Sep 17 00:00:00 2001 From: John Stultz Date: Fri, 3 Feb 2012 00:19:07 -0800 Subject: Input: add infrastructure for selecting clockid for event time stamps As noted by Arve and others, since wall time can jump backwards, it is difficult to use for input because one cannot determine if one event occurred before another or for how long a key was pressed. However, the timestamp field is part of the kernel ABI, and cannot be changed without possibly breaking existing users. This patch adds a new IOCTL that allows a clockid to be set in the evdev_client struct that will specify which time base to use for event timestamps (ie: CLOCK_MONOTONIC instead of CLOCK_REALTIME). For now we only support CLOCK_MONOTONIC and CLOCK_REALTIME, but in the future we could support other clockids if appropriate. The default remains CLOCK_REALTIME, so we don't change the ABI. Signed-off-by: John Stultz Reviewed-by: Daniel Kurtz Signed-off-by: Dmitry Torokhov Conflicts: include/linux/input.h Change-Id: I7b9b442dcd7930a1e72c688327e6fb7275107128 --- include/linux/input.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/input.h b/include/linux/input.h index 5694583..af73bfd 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -132,6 +132,8 @@ struct input_keymap_entry { #define EVIOCGSUSPENDBLOCK _IOR('E', 0x91, int) /* get suspend block enable */ #define EVIOCSSUSPENDBLOCK _IOW('E', 0x91, int) /* set suspend block enable */ +#define EVIOCSCLOCKID _IOW('E', 0xa0, int) /* Set clockid to be used for timestamps */ + /* * Device properties and quirks */ -- cgit v1.1 From af47328e8d37683c911edf5703cdc45d8047490e Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Mon, 18 Jan 2016 16:36:09 +0100 Subject: pipe: limit the per-user amount of pages allocated in pipes On no-so-small systems, it is possible for a single process to cause an OOM condition by filling large pipes with data that are never read. A typical process filling 4000 pipes with 1 MB of data will use 4 GB of memory. On small systems it may be tricky to set the pipe max size to prevent this from happening. This patch makes it possible to enforce a per-user soft limit above which new pipes will be limited to a single page, effectively limiting them to 4 kB each, as well as a hard limit above which no new pipes may be created for this user. This has the effect of protecting the system against memory abuse without hurting other users, and still allowing pipes to work correctly though with less data at once. The limit are controlled by two new sysctls : pipe-user-pages-soft, and pipe-user-pages-hard. Both may be disabled by setting them to zero. The default soft limit allows the default number of FDs per process (1024) to create pipes of the default size (64kB), thus reaching a limit of 64MB before starting to create only smaller pipes. With 256 processes limited to 1024 FDs each, this results in 1024*64kB + (256*1024 - 1024) * 4kB = 1084 MB of memory allocated for a user. The hard limit is disabled by default to avoid breaking existing applications that make intensive use of pipes (eg: for splicing). Reported-by: socketpair@gmail.com Reported-by: Tetsuo Handa Mitigates: CVE-2013-4312 (Linux 2.0+) Suggested-by: Linus Torvalds Signed-off-by: Willy Tarreau Signed-off-by: Al Viro Conflicts: Documentation/sysctl/fs.txt fs/pipe.c include/linux/sched.h Change-Id: Ic7c678af18129943e16715fdaa64a97a7f0854be --- include/linux/pipe_fs_i.h | 4 ++++ include/linux/sched.h | 1 + 2 files changed, 5 insertions(+) (limited to 'include') diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index 0072a53..1aefc3f 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h @@ -43,6 +43,7 @@ struct pipe_buffer { * @fasync_writers: writer side fasync * @inode: inode this pipe is attached to * @bufs: the circular array of pipe buffers + * @user: the user who created this pipe **/ struct pipe_inode_info { wait_queue_head_t wait; @@ -57,6 +58,7 @@ struct pipe_inode_info { struct fasync_struct *fasync_writers; struct inode *inode; struct pipe_buffer *bufs; + struct user_struct *user; }; /* @@ -142,6 +144,8 @@ void pipe_unlock(struct pipe_inode_info *); void pipe_double_lock(struct pipe_inode_info *, struct pipe_inode_info *); extern unsigned int pipe_max_size, pipe_min_size; +extern unsigned long pipe_user_pages_hard; +extern unsigned long pipe_user_pages_soft; int pipe_proc_fn(struct ctl_table *, int, void __user *, size_t *, loff_t *); diff --git a/include/linux/sched.h b/include/linux/sched.h index 8ff666c..ad2f17f 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -705,6 +705,7 @@ struct user_struct { unsigned long mq_bytes; /* How many bytes can be allocated to mqueue? */ #endif unsigned long locked_shm; /* How many pages of mlocked shm ? */ + atomic_long_t pipe_bufs; /* how many pages are allocated in pipe buffers */ #ifdef CONFIG_KEYS struct key *uid_keyring; /* UID specific keyring */ -- cgit v1.1 From f991b824bffa2034b7c5403a22245a97642b6d31 Mon Sep 17 00:00:00 2001 From: Simon Shields Date: Fri, 13 May 2016 23:57:48 +1000 Subject: remove pmem Change-Id: I53ceca9c1e0896241513e166de39684d3654f068 --- include/linux/android_pmem.h | 93 -------------------------------------------- 1 file changed, 93 deletions(-) delete mode 100644 include/linux/android_pmem.h (limited to 'include') diff --git a/include/linux/android_pmem.h b/include/linux/android_pmem.h deleted file mode 100644 index f633621..0000000 --- a/include/linux/android_pmem.h +++ /dev/null @@ -1,93 +0,0 @@ -/* include/linux/android_pmem.h - * - * Copyright (C) 2007 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _ANDROID_PMEM_H_ -#define _ANDROID_PMEM_H_ - -#define PMEM_IOCTL_MAGIC 'p' -#define PMEM_GET_PHYS _IOW(PMEM_IOCTL_MAGIC, 1, unsigned int) -#define PMEM_MAP _IOW(PMEM_IOCTL_MAGIC, 2, unsigned int) -#define PMEM_GET_SIZE _IOW(PMEM_IOCTL_MAGIC, 3, unsigned int) -#define PMEM_UNMAP _IOW(PMEM_IOCTL_MAGIC, 4, unsigned int) -/* This ioctl will allocate pmem space, backing the file, it will fail - * if the file already has an allocation, pass it the len as the argument - * to the ioctl */ -#define PMEM_ALLOCATE _IOW(PMEM_IOCTL_MAGIC, 5, unsigned int) -/* This will connect a one pmem file to another, pass the file that is already - * backed in memory as the argument to the ioctl - */ -#define PMEM_CONNECT _IOW(PMEM_IOCTL_MAGIC, 6, unsigned int) -/* Returns the total size of the pmem region it is sent to as a pmem_region - * struct (with offset set to 0). - */ -#define PMEM_GET_TOTAL_SIZE _IOW(PMEM_IOCTL_MAGIC, 7, unsigned int) -#define PMEM_CACHE_FLUSH _IOW(PMEM_IOCTL_MAGIC, 8, unsigned int) - -struct android_pmem_platform_data -{ - const char* name; - /* starting physical address of memory region */ - unsigned long start; - /* size of memory region */ - unsigned long size; - /* set to indicate the region should not be managed with an allocator */ - unsigned no_allocator; - /* set to indicate maps of this region should be cached, if a mix of - * cached and uncached is desired, set this and open the device with - * O_SYNC to get an uncached region */ - unsigned cached; - /* The MSM7k has bits to enable a write buffer in the bus controller*/ - unsigned buffered; -}; - -struct pmem_region { - unsigned long offset; - unsigned long len; -}; - -#ifdef CONFIG_ANDROID_PMEM -int is_pmem_file(struct file *file); -int get_pmem_file(int fd, unsigned long *start, unsigned long *vstart, - unsigned long *end, struct file **filp); -int get_pmem_user_addr(struct file *file, unsigned long *start, - unsigned long *end); -void put_pmem_file(struct file* file); -void flush_pmem_file(struct file *file, unsigned long start, unsigned long len); -int pmem_setup(struct android_pmem_platform_data *pdata, - long (*ioctl)(struct file *, unsigned int, unsigned long), - int (*release)(struct inode *, struct file *)); -int pmem_remap(struct pmem_region *region, struct file *file, - unsigned operation); - -#else -static inline int is_pmem_file(struct file *file) { return 0; } -static inline int get_pmem_file(int fd, unsigned long *start, - unsigned long *vstart, unsigned long *end, - struct file **filp) { return -ENOSYS; } -static inline int get_pmem_user_addr(struct file *file, unsigned long *start, - unsigned long *end) { return -ENOSYS; } -static inline void put_pmem_file(struct file* file) { return; } -static inline void flush_pmem_file(struct file *file, unsigned long start, - unsigned long len) { return; } -static inline int pmem_setup(struct android_pmem_platform_data *pdata, - long (*ioctl)(struct file *, unsigned int, unsigned long), - int (*release)(struct inode *, struct file *)) { return -ENOSYS; } - -static inline int pmem_remap(struct pmem_region *region, struct file *file, - unsigned operation) { return -ENOSYS; } -#endif - -#endif //_ANDROID_PPP_H_ - -- cgit v1.1 From 540f1d84d4f8fb27e73dfcb6f3b13c39fa667041 Mon Sep 17 00:00:00 2001 From: RGIB Date: Wed, 25 May 2016 18:27:06 +0200 Subject: smdk4412 : modem_if KK driver from N5100ZTCNL4 Change-Id: I903a0f614751f374e1705df5c35f4e1e21190b13 --- include/linux/platform_data/modem.h | 244 +++++++++++++++++++++++------------- 1 file changed, 157 insertions(+), 87 deletions(-) mode change 100644 => 100755 include/linux/platform_data/modem.h (limited to 'include') diff --git a/include/linux/platform_data/modem.h b/include/linux/platform_data/modem.h old mode 100644 new mode 100755 index 9598763..bc4433e --- a/include/linux/platform_data/modem.h +++ b/include/linux/platform_data/modem.h @@ -1,5 +1,4 @@ /* - * Copyright (C) 2010 Google, Inc. * Copyright (C) 2010 Samsung Electronics. * * This software is licensed under the terms of the GNU General Public @@ -16,14 +15,21 @@ #ifndef __MODEM_IF_H__ #define __MODEM_IF_H__ +#include +#include + enum modem_t { IMC_XMM6260, IMC_XMM6262, VIA_CBP71, VIA_CBP72, + VIA_CBP82, + SEC_CMC220, SEC_CMC221, + SEC_SS222, QC_MDM6600, QC_ESC6270, + QC_QSC6085, SPRD_SC8803, DUMMY, MAX_MODEM_TYPE @@ -33,10 +39,11 @@ enum dev_format { IPC_FMT, IPC_RAW, IPC_RFS, + IPC_MULTI_RAW, IPC_CMD, IPC_BOOT, - IPC_MULTI_RAW, IPC_RAMDUMP, + IPC_DEBUG, MAX_DEV_FORMAT, }; #define MAX_IPC_DEV (IPC_RFS + 1) /* FMT, RAW, RFS */ @@ -51,13 +58,14 @@ enum modem_io { enum modem_link { LINKDEV_UNDEFINED, LINKDEV_MIPI, - LINKDEV_DPRAM, - LINKDEV_SPI, LINKDEV_USB, LINKDEV_HSIC, - LINKDEV_C2C, + LINKDEV_DPRAM, LINKDEV_PLD, - LINKDEV_MAX, + LINKDEV_C2C, + LINKDEV_SHMEM, + LINKDEV_SPI, + LINKDEV_MAX }; #define LINKTYPE(modem_link) (1u << (modem_link)) @@ -66,6 +74,12 @@ enum modem_network { CDMA_NETWORK, TDSCDMA_NETWORK, LTE_NETWORK, + MAX_MODEM_NETWORK +}; + +enum ap_type { + S5P, + MAX_AP_TYPE }; enum sipc_ver { @@ -74,15 +88,16 @@ enum sipc_ver { SIPC_VER_41 = 41, SIPC_VER_42 = 42, SIPC_VER_50 = 50, - MAX_SIPC_VER, + MAX_SIPC_VER }; /** * struct modem_io_t - declaration for io_device * @name: device name - * @id: contain format & channel information + * @id: for SIPC4, contains format & channel information * (id & 11100000b)>>5 = format (eg, 0=FMT, 1=RAW, 2=RFS) * (id & 00011111b) = channel (valid only if format is RAW) + * for SIPC5, contains only 8-bit channel ID * @format: device format * @io_type: type of this io_device * @links: list of link_devices to use this io_device @@ -94,7 +109,7 @@ enum sipc_ver { * TX is only one link_device. * @app: the name of the application that will use this IO device * - * This structure is used in board-*-modem.c + * This structure is used in board-*-modems.c */ struct modem_io_t { char *name; @@ -103,11 +118,7 @@ struct modem_io_t { enum modem_io io_type; enum modem_link links; enum modem_link tx_link; -#ifdef CONFIG_MACH_U1 char *app; -#else - bool rx_gather; -#endif }; struct modemlink_pm_data { @@ -126,10 +137,14 @@ struct modemlink_pm_data { void *hub_pm_data; bool has_usbhub; +#ifdef CONFIG_EXYNOS4_CPUFREQ /* cpu/bus frequency lock */ atomic_t freqlock; + atomic_t freq_dpramlock; int (*freq_lock)(struct device *dev); int (*freq_unlock)(struct device *dev); + unsigned gpio_cpufreq_lock; +#endif int autosuspend_delay_ms; /* if zero, the default value is used */ void (*ehci_reg_dump)(struct device *); @@ -140,31 +155,25 @@ struct modemlink_pm_link_activectl { int gpio_request_host_active; }; -#define RES_CP_ACTIVE_IRQ_ID 0 -#define RES_DPRAM_MEM_ID 1 -#define RES_DPRAM_IRQ_ID 2 -#define RES_DPRAM_SFR_ID 3 +#define RES_DPRAM_MEM_ID 0 +#define RES_DPRAM_SFR_ID 1 -#ifdef CONFIG_MACH_U1 -#define STR_CP_ACTIVE_IRQ "cp_active_irq" #define STR_DPRAM_BASE "dpram_base" -#define STR_DPRAM_IRQ "dpram_irq" #define STR_DPRAM_SFR_BASE "dpram_sfr_base" -#endif enum dpram_type { EXT_DPRAM, AP_IDPRAM, CP_IDPRAM, - SHM_DPRAM, + PLD_DPRAM, MAX_DPRAM_TYPE }; -#define DPRAM_SIZE_8KB 0x02000 -#define DPRAM_SIZE_16KB 0x04000 -#define DPRAM_SIZE_32KB 0x08000 -#define DPRAM_SIZE_64KB 0x10000 -#define DPRAM_SIZE_128KB 0x20000 +#define DPRAM_SIZE_8KB (8 << 10) +#define DPRAM_SIZE_16KB (16 << 10) +#define DPRAM_SIZE_32KB (32 << 10) +#define DPRAM_SIZE_64KB (64 << 10) +#define DPRAM_SIZE_128KB (128 << 10) enum dpram_speed { DPRAM_SPEED_LOW, @@ -193,7 +202,16 @@ struct dpram_ipc_device { }; struct dpram_ipc_map { -#if defined(CONFIG_LINK_DEVICE_PLD) + u16 __iomem *magic; + u16 __iomem *access; + + struct dpram_ipc_device dev[MAX_IPC_DEV]; + + u16 __iomem *mbx_cp2ap; + u16 __iomem *mbx_ap2cp; +}; + +struct pld_ipc_map { u16 __iomem *mbx_ap2cp; u16 __iomem *magic_ap2cp; u16 __iomem *access_ap2cp; @@ -205,50 +223,52 @@ struct dpram_ipc_map { struct dpram_ipc_device dev[MAX_IPC_DEV]; u16 __iomem *address_buffer; -#else - u16 __iomem *magic; - u16 __iomem *access; - - struct dpram_ipc_device dev[MAX_IPC_DEV]; - - u16 __iomem *mbx_cp2ap; - u16 __iomem *mbx_ap2cp; -#endif }; -struct modemlink_dpram_control { - void (*reset)(void); - void (*clear_intr)(void); - u16 (*recv_intr)(void); - void (*send_intr)(u16); - u16 (*recv_msg)(void); - void (*send_msg)(u16); +struct modemlink_dpram_data { + enum dpram_type type; /* DPRAM type */ + enum ap_type ap; /* AP type for AP_IDPRAM */ - int (*wakeup)(void); - void (*sleep)(void); + /* Stirct I/O access (e.g. ioread16(), etc.) is required */ + bool strict_io_access; - void (*setup_speed)(enum dpram_speed); + /* Aligned access is required */ + int aligned; - enum dpram_type dp_type; /* DPRAM type */ - int aligned; /* aligned access is required */ -#ifdef CONFIG_MACH_U1 - bool disabled; /* Disabled during phone booting */ -#endif - u8 __iomem *dp_base; - u32 dp_size; + /* Disabled during phone booting */ + bool disabled; - int dpram_irq; - unsigned long dpram_irq_flags; + /* Virtual base address and size */ + u8 __iomem *base; + u32 size; - int max_ipc_dev; - struct dpram_ipc_map *ipc_map; + /* Pointer to an IPC map (DPRAM or PLD) */ + void *ipc_map; + + /* Timeout of waiting for RES_ACK from CP (in msec) */ + unsigned long res_ack_wait_timeout; unsigned boot_size_offset; unsigned boot_tag_offset; unsigned boot_count_offset; unsigned max_boot_frame_size; + + void (*setup_speed)(enum dpram_speed); + void (*clear_int2ap)(void); }; +enum shmem_type { + REAL_SHMEM, + C2C_SHMEM, + MAX_SHMEM_TYPE +}; + +#define STR_SHMEM_BASE "shmem_base" + +#define SHMEM_SIZE_1MB (1 << 20) /* 1 MB */ +#define SHMEM_SIZE_2MB (2 << 20) /* 2 MB */ +#define SHMEM_SIZE_4MB (4 << 20) /* 4 MB */ + /* platform data */ struct modem_data { char *name; @@ -257,20 +277,45 @@ struct modem_data { unsigned gpio_cp_off; unsigned gpio_reset_req_n; unsigned gpio_cp_reset; + + /* for broadcasting AP's PM state (active or sleep) */ unsigned gpio_pda_active; + + /* for checking aliveness of CP */ unsigned gpio_phone_active; + int irq_phone_active; + + /* for AP-CP IPC interrupt */ + unsigned gpio_ipc_int2ap; + int irq_ipc_int2ap; + unsigned long irqf_ipc_int2ap; /* IRQ flags */ + unsigned gpio_ipc_int2cp; + + /* for AP-CP power management (PM) handshaking */ + unsigned gpio_ap_wakeup; + int irq_ap_wakeup; + unsigned gpio_ap_status; + unsigned gpio_cp_wakeup; + unsigned gpio_cp_status; + int irq_cp_status; + + /* for USB/HSIC PM */ + unsigned gpio_host_wakeup; + int irq_host_wakeup; + unsigned gpio_host_active; + unsigned gpio_slave_wakeup; + unsigned gpio_hub_suspend; + unsigned gpio_cp_dump_int; unsigned gpio_ap_dump_int; unsigned gpio_flm_uart_sel; + unsigned gpio_cp_warm_reset; #if defined(CONFIG_MACH_M0_CTC) unsigned gpio_flm_uart_sel_rev06; - unsigned gpio_host_wakeup; #endif - unsigned gpio_cp_warm_reset; + unsigned gpio_sim_detect; -#if defined(CONFIG_LINK_DEVICE_DPRAM) || defined(CONFIG_LINK_DEVICE_PLD) - unsigned gpio_dpram_int; -#endif + int irq_sim_detect; #ifdef CONFIG_LINK_DEVICE_PLD unsigned gpio_fpga1_creset; @@ -284,14 +329,6 @@ struct modem_data { unsigned gpio_fpga2_cs_n; #endif -#ifdef CONFIG_LTE_MODEM_CMC221 - unsigned gpio_dpram_status; - unsigned gpio_dpram_wakeup; - unsigned gpio_slave_wakeup; - unsigned gpio_host_active; - unsigned gpio_host_wakeup; - int irq_host_wakeup; -#endif #ifdef CONFIG_MACH_U1_KOR_LGT unsigned gpio_cp_reset_msm; unsigned gpio_boot_sw_sel; @@ -316,41 +353,74 @@ struct modem_data { #endif /* Switch with 2 links in a modem */ - unsigned gpio_dynamic_switching; + unsigned gpio_link_switch; + +#ifdef CONFIG_EXYNOS4_CPUFREQ + /* cpu/bus frequency lock */ + unsigned gpio_cpufreq_lock; +#endif /* Modem component */ - enum modem_network modem_net; - enum modem_t modem_type; - enum modem_link link_types; - char *link_name; -#if defined(CONFIG_LINK_DEVICE_DPRAM) || defined(CONFIG_LINK_DEVICE_PLD) + enum modem_network modem_net; + enum modem_t modem_type; + enum modem_link link_types; + char *link_name; + /* Link to DPRAM control functions dependent on each platform */ - struct modemlink_dpram_control *dpram_ctl; -#endif + struct modemlink_dpram_data *dpram; /* SIPC version */ enum sipc_ver ipc_version; + /* the number of real IPC devices -> (IPC_RAW + 1) or (IPC_RFS + 1) */ + int max_ipc_dev; + /* Information of IO devices */ - unsigned num_iodevs; - struct modem_io_t *iodevs; + unsigned num_iodevs; + struct modem_io_t *iodevs; /* Modem link PM support */ struct modemlink_pm_data *link_pm_data; - void (*gpio_revers_bias_clear)(void); - void (*gpio_revers_bias_restore)(void); - /* Handover with 2+ modems */ bool use_handover; - /* Debugging option */ - bool use_mif_log; /* SIM Detect polarity */ bool sim_polarity; + + void (*gpio_revers_bias_clear)(void); + void (*gpio_revers_bias_restore)(void); }; -#define LOG_TAG "mif: " +#define MODEM_BOOT_DEV_SPI "modem_boot_spi" + +struct modem_boot_spi_platform_data { + const char *name; + unsigned int gpio_cp_status; +}; + +struct modem_boot_spi { + struct miscdevice dev; + struct spi_device *spi_dev; + struct mutex lock; + unsigned gpio_cp_status; +}; +#define to_modem_boot_spi(misc) container_of(misc, struct modem_boot_spi, dev); + +struct utc_time { + u16 year; + u8 mon:4, + day:4; + u8 hour; + u8 min; + u8 sec; + u16 msec; +} __packed; + +extern void get_utc_time(struct utc_time *utc); + +#define LOG_TAG "mif: " +#define CALLER (__builtin_return_address(0)) #define mif_err(fmt, ...) \ pr_err(LOG_TAG "%s: " pr_fmt(fmt), __func__, ##__VA_ARGS__) -- cgit v1.1 From 206f43e8ae09166ba608f520c60bb208661769ca Mon Sep 17 00:00:00 2001 From: Roberto Gibellini Date: Fri, 27 May 2016 02:34:23 -0700 Subject: Revert "smdk4412 : modem_if KK driver from N5100ZTCNL4" This reverts commit 540f1d84d4f8fb27e73dfcb6f3b13c39fa667041. Change-Id: I8671bdc7f46a11375b6f710efa4af6bf32aea908 --- include/linux/platform_data/modem.h | 244 +++++++++++++----------------------- 1 file changed, 87 insertions(+), 157 deletions(-) mode change 100755 => 100644 include/linux/platform_data/modem.h (limited to 'include') diff --git a/include/linux/platform_data/modem.h b/include/linux/platform_data/modem.h old mode 100755 new mode 100644 index bc4433e..9598763 --- a/include/linux/platform_data/modem.h +++ b/include/linux/platform_data/modem.h @@ -1,4 +1,5 @@ /* + * Copyright (C) 2010 Google, Inc. * Copyright (C) 2010 Samsung Electronics. * * This software is licensed under the terms of the GNU General Public @@ -15,21 +16,14 @@ #ifndef __MODEM_IF_H__ #define __MODEM_IF_H__ -#include -#include - enum modem_t { IMC_XMM6260, IMC_XMM6262, VIA_CBP71, VIA_CBP72, - VIA_CBP82, - SEC_CMC220, SEC_CMC221, - SEC_SS222, QC_MDM6600, QC_ESC6270, - QC_QSC6085, SPRD_SC8803, DUMMY, MAX_MODEM_TYPE @@ -39,11 +33,10 @@ enum dev_format { IPC_FMT, IPC_RAW, IPC_RFS, - IPC_MULTI_RAW, IPC_CMD, IPC_BOOT, + IPC_MULTI_RAW, IPC_RAMDUMP, - IPC_DEBUG, MAX_DEV_FORMAT, }; #define MAX_IPC_DEV (IPC_RFS + 1) /* FMT, RAW, RFS */ @@ -58,14 +51,13 @@ enum modem_io { enum modem_link { LINKDEV_UNDEFINED, LINKDEV_MIPI, + LINKDEV_DPRAM, + LINKDEV_SPI, LINKDEV_USB, LINKDEV_HSIC, - LINKDEV_DPRAM, - LINKDEV_PLD, LINKDEV_C2C, - LINKDEV_SHMEM, - LINKDEV_SPI, - LINKDEV_MAX + LINKDEV_PLD, + LINKDEV_MAX, }; #define LINKTYPE(modem_link) (1u << (modem_link)) @@ -74,12 +66,6 @@ enum modem_network { CDMA_NETWORK, TDSCDMA_NETWORK, LTE_NETWORK, - MAX_MODEM_NETWORK -}; - -enum ap_type { - S5P, - MAX_AP_TYPE }; enum sipc_ver { @@ -88,16 +74,15 @@ enum sipc_ver { SIPC_VER_41 = 41, SIPC_VER_42 = 42, SIPC_VER_50 = 50, - MAX_SIPC_VER + MAX_SIPC_VER, }; /** * struct modem_io_t - declaration for io_device * @name: device name - * @id: for SIPC4, contains format & channel information + * @id: contain format & channel information * (id & 11100000b)>>5 = format (eg, 0=FMT, 1=RAW, 2=RFS) * (id & 00011111b) = channel (valid only if format is RAW) - * for SIPC5, contains only 8-bit channel ID * @format: device format * @io_type: type of this io_device * @links: list of link_devices to use this io_device @@ -109,7 +94,7 @@ enum sipc_ver { * TX is only one link_device. * @app: the name of the application that will use this IO device * - * This structure is used in board-*-modems.c + * This structure is used in board-*-modem.c */ struct modem_io_t { char *name; @@ -118,7 +103,11 @@ struct modem_io_t { enum modem_io io_type; enum modem_link links; enum modem_link tx_link; +#ifdef CONFIG_MACH_U1 char *app; +#else + bool rx_gather; +#endif }; struct modemlink_pm_data { @@ -137,14 +126,10 @@ struct modemlink_pm_data { void *hub_pm_data; bool has_usbhub; -#ifdef CONFIG_EXYNOS4_CPUFREQ /* cpu/bus frequency lock */ atomic_t freqlock; - atomic_t freq_dpramlock; int (*freq_lock)(struct device *dev); int (*freq_unlock)(struct device *dev); - unsigned gpio_cpufreq_lock; -#endif int autosuspend_delay_ms; /* if zero, the default value is used */ void (*ehci_reg_dump)(struct device *); @@ -155,25 +140,31 @@ struct modemlink_pm_link_activectl { int gpio_request_host_active; }; -#define RES_DPRAM_MEM_ID 0 -#define RES_DPRAM_SFR_ID 1 +#define RES_CP_ACTIVE_IRQ_ID 0 +#define RES_DPRAM_MEM_ID 1 +#define RES_DPRAM_IRQ_ID 2 +#define RES_DPRAM_SFR_ID 3 +#ifdef CONFIG_MACH_U1 +#define STR_CP_ACTIVE_IRQ "cp_active_irq" #define STR_DPRAM_BASE "dpram_base" +#define STR_DPRAM_IRQ "dpram_irq" #define STR_DPRAM_SFR_BASE "dpram_sfr_base" +#endif enum dpram_type { EXT_DPRAM, AP_IDPRAM, CP_IDPRAM, - PLD_DPRAM, + SHM_DPRAM, MAX_DPRAM_TYPE }; -#define DPRAM_SIZE_8KB (8 << 10) -#define DPRAM_SIZE_16KB (16 << 10) -#define DPRAM_SIZE_32KB (32 << 10) -#define DPRAM_SIZE_64KB (64 << 10) -#define DPRAM_SIZE_128KB (128 << 10) +#define DPRAM_SIZE_8KB 0x02000 +#define DPRAM_SIZE_16KB 0x04000 +#define DPRAM_SIZE_32KB 0x08000 +#define DPRAM_SIZE_64KB 0x10000 +#define DPRAM_SIZE_128KB 0x20000 enum dpram_speed { DPRAM_SPEED_LOW, @@ -202,16 +193,7 @@ struct dpram_ipc_device { }; struct dpram_ipc_map { - u16 __iomem *magic; - u16 __iomem *access; - - struct dpram_ipc_device dev[MAX_IPC_DEV]; - - u16 __iomem *mbx_cp2ap; - u16 __iomem *mbx_ap2cp; -}; - -struct pld_ipc_map { +#if defined(CONFIG_LINK_DEVICE_PLD) u16 __iomem *mbx_ap2cp; u16 __iomem *magic_ap2cp; u16 __iomem *access_ap2cp; @@ -223,52 +205,50 @@ struct pld_ipc_map { struct dpram_ipc_device dev[MAX_IPC_DEV]; u16 __iomem *address_buffer; -}; +#else + u16 __iomem *magic; + u16 __iomem *access; + + struct dpram_ipc_device dev[MAX_IPC_DEV]; -struct modemlink_dpram_data { - enum dpram_type type; /* DPRAM type */ - enum ap_type ap; /* AP type for AP_IDPRAM */ + u16 __iomem *mbx_cp2ap; + u16 __iomem *mbx_ap2cp; +#endif +}; - /* Stirct I/O access (e.g. ioread16(), etc.) is required */ - bool strict_io_access; +struct modemlink_dpram_control { + void (*reset)(void); + void (*clear_intr)(void); + u16 (*recv_intr)(void); + void (*send_intr)(u16); + u16 (*recv_msg)(void); + void (*send_msg)(u16); - /* Aligned access is required */ - int aligned; + int (*wakeup)(void); + void (*sleep)(void); - /* Disabled during phone booting */ - bool disabled; + void (*setup_speed)(enum dpram_speed); - /* Virtual base address and size */ - u8 __iomem *base; - u32 size; + enum dpram_type dp_type; /* DPRAM type */ + int aligned; /* aligned access is required */ +#ifdef CONFIG_MACH_U1 + bool disabled; /* Disabled during phone booting */ +#endif + u8 __iomem *dp_base; + u32 dp_size; - /* Pointer to an IPC map (DPRAM or PLD) */ - void *ipc_map; + int dpram_irq; + unsigned long dpram_irq_flags; - /* Timeout of waiting for RES_ACK from CP (in msec) */ - unsigned long res_ack_wait_timeout; + int max_ipc_dev; + struct dpram_ipc_map *ipc_map; unsigned boot_size_offset; unsigned boot_tag_offset; unsigned boot_count_offset; unsigned max_boot_frame_size; - - void (*setup_speed)(enum dpram_speed); - void (*clear_int2ap)(void); }; -enum shmem_type { - REAL_SHMEM, - C2C_SHMEM, - MAX_SHMEM_TYPE -}; - -#define STR_SHMEM_BASE "shmem_base" - -#define SHMEM_SIZE_1MB (1 << 20) /* 1 MB */ -#define SHMEM_SIZE_2MB (2 << 20) /* 2 MB */ -#define SHMEM_SIZE_4MB (4 << 20) /* 4 MB */ - /* platform data */ struct modem_data { char *name; @@ -277,45 +257,20 @@ struct modem_data { unsigned gpio_cp_off; unsigned gpio_reset_req_n; unsigned gpio_cp_reset; - - /* for broadcasting AP's PM state (active or sleep) */ unsigned gpio_pda_active; - - /* for checking aliveness of CP */ unsigned gpio_phone_active; - int irq_phone_active; - - /* for AP-CP IPC interrupt */ - unsigned gpio_ipc_int2ap; - int irq_ipc_int2ap; - unsigned long irqf_ipc_int2ap; /* IRQ flags */ - unsigned gpio_ipc_int2cp; - - /* for AP-CP power management (PM) handshaking */ - unsigned gpio_ap_wakeup; - int irq_ap_wakeup; - unsigned gpio_ap_status; - unsigned gpio_cp_wakeup; - unsigned gpio_cp_status; - int irq_cp_status; - - /* for USB/HSIC PM */ - unsigned gpio_host_wakeup; - int irq_host_wakeup; - unsigned gpio_host_active; - unsigned gpio_slave_wakeup; - unsigned gpio_hub_suspend; - unsigned gpio_cp_dump_int; unsigned gpio_ap_dump_int; unsigned gpio_flm_uart_sel; - unsigned gpio_cp_warm_reset; #if defined(CONFIG_MACH_M0_CTC) unsigned gpio_flm_uart_sel_rev06; + unsigned gpio_host_wakeup; #endif - + unsigned gpio_cp_warm_reset; unsigned gpio_sim_detect; - int irq_sim_detect; +#if defined(CONFIG_LINK_DEVICE_DPRAM) || defined(CONFIG_LINK_DEVICE_PLD) + unsigned gpio_dpram_int; +#endif #ifdef CONFIG_LINK_DEVICE_PLD unsigned gpio_fpga1_creset; @@ -329,6 +284,14 @@ struct modem_data { unsigned gpio_fpga2_cs_n; #endif +#ifdef CONFIG_LTE_MODEM_CMC221 + unsigned gpio_dpram_status; + unsigned gpio_dpram_wakeup; + unsigned gpio_slave_wakeup; + unsigned gpio_host_active; + unsigned gpio_host_wakeup; + int irq_host_wakeup; +#endif #ifdef CONFIG_MACH_U1_KOR_LGT unsigned gpio_cp_reset_msm; unsigned gpio_boot_sw_sel; @@ -353,74 +316,41 @@ struct modem_data { #endif /* Switch with 2 links in a modem */ - unsigned gpio_link_switch; - -#ifdef CONFIG_EXYNOS4_CPUFREQ - /* cpu/bus frequency lock */ - unsigned gpio_cpufreq_lock; -#endif + unsigned gpio_dynamic_switching; /* Modem component */ - enum modem_network modem_net; - enum modem_t modem_type; - enum modem_link link_types; - char *link_name; - + enum modem_network modem_net; + enum modem_t modem_type; + enum modem_link link_types; + char *link_name; +#if defined(CONFIG_LINK_DEVICE_DPRAM) || defined(CONFIG_LINK_DEVICE_PLD) /* Link to DPRAM control functions dependent on each platform */ - struct modemlink_dpram_data *dpram; + struct modemlink_dpram_control *dpram_ctl; +#endif /* SIPC version */ enum sipc_ver ipc_version; - /* the number of real IPC devices -> (IPC_RAW + 1) or (IPC_RFS + 1) */ - int max_ipc_dev; - /* Information of IO devices */ - unsigned num_iodevs; - struct modem_io_t *iodevs; + unsigned num_iodevs; + struct modem_io_t *iodevs; /* Modem link PM support */ struct modemlink_pm_data *link_pm_data; + void (*gpio_revers_bias_clear)(void); + void (*gpio_revers_bias_restore)(void); + /* Handover with 2+ modems */ bool use_handover; + /* Debugging option */ + bool use_mif_log; /* SIM Detect polarity */ bool sim_polarity; - - void (*gpio_revers_bias_clear)(void); - void (*gpio_revers_bias_restore)(void); }; -#define MODEM_BOOT_DEV_SPI "modem_boot_spi" - -struct modem_boot_spi_platform_data { - const char *name; - unsigned int gpio_cp_status; -}; - -struct modem_boot_spi { - struct miscdevice dev; - struct spi_device *spi_dev; - struct mutex lock; - unsigned gpio_cp_status; -}; -#define to_modem_boot_spi(misc) container_of(misc, struct modem_boot_spi, dev); - -struct utc_time { - u16 year; - u8 mon:4, - day:4; - u8 hour; - u8 min; - u8 sec; - u16 msec; -} __packed; - -extern void get_utc_time(struct utc_time *utc); - -#define LOG_TAG "mif: " -#define CALLER (__builtin_return_address(0)) +#define LOG_TAG "mif: " #define mif_err(fmt, ...) \ pr_err(LOG_TAG "%s: " pr_fmt(fmt), __func__, ##__VA_ARGS__) -- cgit v1.1 From c47282825bbde9f692d61b50dfd9f0f8f51afdf2 Mon Sep 17 00:00:00 2001 From: Andreas Blaesius Date: Sun, 12 Jun 2016 00:10:11 +0200 Subject: Revert "Add ZRAM_FOR_ANDROID" Change-Id: I6aff6a484dd94730f2032ceb838e0741ca6fa878 --- include/linux/mm_types.h | 6 ------ 1 file changed, 6 deletions(-) (limited to 'include') diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 0f230ce..059839c 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -198,9 +198,6 @@ struct vm_area_struct { #ifdef CONFIG_NUMA struct mempolicy *vm_policy; /* NUMA policy for the VMA */ #endif -#ifdef CONFIG_ZRAM_FOR_ANDROID - int vma_swap_done; -#endif /* CONFIG_ZRAM_FOR_ANDROID */ }; struct core_thread { @@ -333,9 +330,6 @@ struct mm_struct { #ifdef CONFIG_CPUMASK_OFFSTACK struct cpumask cpumask_allocation; #endif -#ifdef CONFIG_ZRAM_FOR_ANDROID - int mm_swap_done; -#endif /* CONFIG_ZRAM_FOR_ANDROID */ }; static inline void mm_init_cpumask(struct mm_struct *mm) -- cgit v1.1 From 06cdf4f03cc2a0beb383782320c4b02df7a0d94d Mon Sep 17 00:00:00 2001 From: Dan Magenheimer Date: Thu, 12 Jan 2012 14:03:25 -0500 Subject: mm: zcache/tmem/cleancache: s/flush/invalidate/ Complete the renaming from "flush" to "invalidate" across both tmem frontends (cleancache and frontswap) and both tmem backends (Xen and zcache), as required by akpm. This change is completely cosmetic. [v10: no change] [v9: akpm@linux-foundation.org: change "flush" to "invalidate", part 3] Signed-off-by: Dan Magenheimer Cc: Kamezawa Hiroyuki Cc: Jan Beulich Acked-by: Seth Jennings Cc: Jeremy Fitzhardinge Cc: Hugh Dickins Cc: Johannes Weiner Cc: Nitin Gupta Cc: Matthew Wilcox Cc: Chris Mason Cc: Rik Riel Cc: Andrew Morton [v11: Remove the frontswap part] Signed-off-by: Konrad Rzeszutek Wilk Conflicts: drivers/xen/tmem.c include/linux/cleancache.h Change-Id: Id9661e5fc4bb6f416129f38c1e3df80319653041 --- include/linux/cleancache.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/linux/cleancache.h b/include/linux/cleancache.h index 04ffb2e..1ccdcea 100644 --- a/include/linux/cleancache.h +++ b/include/linux/cleancache.h @@ -28,9 +28,9 @@ struct cleancache_ops { pgoff_t, struct page *); void (*put_page)(int, struct cleancache_filekey, pgoff_t, struct page *); - void (*flush_page)(int, struct cleancache_filekey, pgoff_t); - void (*flush_inode)(int, struct cleancache_filekey); - void (*flush_fs)(int); + void (*invalidate_page)(int, struct cleancache_filekey, pgoff_t); + void (*invalidate_inode)(int, struct cleancache_filekey); + void (*invalidate_fs)(int); }; extern struct cleancache_ops -- cgit v1.1 From 286588f748a4ecfe52cd671af74bf7c0285293f0 Mon Sep 17 00:00:00 2001 From: Minchan Kim Date: Thu, 30 Jan 2014 15:45:50 -0800 Subject: zsmalloc: move it under mm This patch moves zsmalloc under mm directory. Before that, description will explain why we have needed custom allocator. Zsmalloc is a new slab-based memory allocator for storing compressed pages. It is designed for low fragmentation and high allocation success rate on large object, but <= PAGE_SIZE allocations. zsmalloc differs from the kernel slab allocator in two primary ways to achieve these design goals. zsmalloc never requires high order page allocations to back slabs, or "size classes" in zsmalloc terms. Instead it allows multiple single-order pages to be stitched together into a "zspage" which backs the slab. This allows for higher allocation success rate under memory pressure. Also, zsmalloc allows objects to span page boundaries within the zspage. This allows for lower fragmentation than could be had with the kernel slab allocator for objects between PAGE_SIZE/2 and PAGE_SIZE. With the kernel slab allocator, if a page compresses to 60% of it original size, the memory savings gained through compression is lost in fragmentation because another object of the same size can't be stored in the leftover space. This ability to span pages results in zsmalloc allocations not being directly addressable by the user. The user is given an non-dereferencable handle in response to an allocation request. That handle must be mapped, using zs_map_object(), which returns a pointer to the mapped region that can be used. The mapping is necessary since the object data may reside in two different noncontigious pages. The zsmalloc fulfills the allocation needs for zram perfectly [sjenning@linux.vnet.ibm.com: borrow Seth's quote] Signed-off-by: Minchan Kim Acked-by: Nitin Gupta Reviewed-by: Konrad Rzeszutek Wilk Cc: Bob Liu Cc: Greg Kroah-Hartman Cc: Hugh Dickins Cc: Jens Axboe Cc: Luigi Semenzato Cc: Mel Gorman Cc: Pekka Enberg Cc: Rik van Riel Cc: Seth Jennings Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Change-Id: Ib026c17143131089494dc394c4a35e230220ec83 Conflicts: drivers/staging/Kconfig drivers/staging/Makefile Conflicts: mm/Kconfig mm/Makefile --- include/linux/zsmalloc.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 include/linux/zsmalloc.h (limited to 'include') diff --git a/include/linux/zsmalloc.h b/include/linux/zsmalloc.h new file mode 100644 index 0000000..c2eb174 --- /dev/null +++ b/include/linux/zsmalloc.h @@ -0,0 +1,50 @@ +/* + * zsmalloc memory allocator + * + * Copyright (C) 2011 Nitin Gupta + * + * This code is released using a dual license strategy: BSD/GPL + * You can choose the license that better fits your requirements. + * + * Released under the terms of 3-clause BSD License + * Released under the terms of GNU General Public License Version 2.0 + */ + +#ifndef _ZS_MALLOC_H_ +#define _ZS_MALLOC_H_ + +#include + +/* + * zsmalloc mapping modes + * + * NOTE: These only make a difference when a mapped object spans pages. + * They also have no effect when PGTABLE_MAPPING is selected. + */ +enum zs_mapmode { + ZS_MM_RW, /* normal read-write mapping */ + ZS_MM_RO, /* read-only (no copy-out at unmap time) */ + ZS_MM_WO /* write-only (no copy-in at map time) */ + /* + * NOTE: ZS_MM_WO should only be used for initializing new + * (uninitialized) allocations. Partial writes to already + * initialized allocations should use ZS_MM_RW to preserve the + * existing data. + */ +}; + +struct zs_pool; + +struct zs_pool *zs_create_pool(gfp_t flags); +void zs_destroy_pool(struct zs_pool *pool); + +unsigned long zs_malloc(struct zs_pool *pool, size_t size); +void zs_free(struct zs_pool *pool, unsigned long obj); + +void *zs_map_object(struct zs_pool *pool, unsigned long handle, + enum zs_mapmode mm); +void zs_unmap_object(struct zs_pool *pool, unsigned long handle); + +u64 zs_get_total_size_bytes(struct zs_pool *pool); + +#endif -- cgit v1.1 From 5636a0d05a0441c9eb503f9cf56e6a961e979a7f Mon Sep 17 00:00:00 2001 From: Minchan Kim Date: Thu, 30 Jan 2014 15:45:55 -0800 Subject: zsmalloc: add copyright Add my copyright to the zsmalloc source code which I maintain. Signed-off-by: Minchan Kim Cc: Nitin Gupta Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/zsmalloc.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/zsmalloc.h b/include/linux/zsmalloc.h index c2eb174..e44d634 100644 --- a/include/linux/zsmalloc.h +++ b/include/linux/zsmalloc.h @@ -2,6 +2,7 @@ * zsmalloc memory allocator * * Copyright (C) 2011 Nitin Gupta + * Copyright (C) 2012, 2013 Minchan Kim * * This code is released using a dual license strategy: BSD/GPL * You can choose the license that better fits your requirements. -- cgit v1.1 From 3948a0f192249f3cb564a1b5010b4089cc685bee Mon Sep 17 00:00:00 2001 From: Kyungsik Lee Date: Mon, 8 Jul 2013 16:01:45 -0700 Subject: decompressor: add LZ4 decompressor module Add support for LZ4 decompression in the Linux Kernel. LZ4 Decompression APIs for kernel are based on LZ4 implementation by Yann Collet. Benchmark Results(PATCH v3) Compiler: Linaro ARM gcc 4.6.2 1. ARMv7, 1.5GHz based board Kernel: linux 3.4 Uncompressed Kernel Size: 14MB Compressed Size Decompression Speed LZO 6.7MB 20.1MB/s, 25.2MB/s(UA) LZ4 7.3MB 29.1MB/s, 45.6MB/s(UA) 2. ARMv7, 1.7GHz based board Kernel: linux 3.7 Uncompressed Kernel Size: 14MB Compressed Size Decompression Speed LZO 6.0MB 34.1MB/s, 52.2MB/s(UA) LZ4 6.5MB 86.7MB/s - UA: Unaligned memory Access support - Latest patch set for LZO applied This patch set is for adding support for LZ4-compressed Kernel. LZ4 is a very fast lossless compression algorithm and it also features an extremely fast decoder [1]. But we have five of decompressors already and one question which does arise, however, is that of where do we stop adding new ones? This issue had been discussed and came to the conclusion [2]. Russell King said that we should have: - one decompressor which is the fastest - one decompressor for the highest compression ratio - one popular decompressor (eg conventional gzip) If we have a replacement one for one of these, then it should do exactly that: replace it. The benchmark shows that an 8% increase in image size vs a 66% increase in decompression speed compared to LZO(which has been known as the fastest decompressor in the Kernel). Therefore the "fast but may not be small" compression title has clearly been taken by LZ4 [3]. [1] http://code.google.com/p/lz4/ [2] http://thread.gmane.org/gmane.linux.kbuild.devel/9157 [3] http://thread.gmane.org/gmane.linux.kbuild.devel/9347 LZ4 homepage: http://fastcompression.blogspot.com/p/lz4.html LZ4 source repository: http://code.google.com/p/lz4/ Signed-off-by: Kyungsik Lee Signed-off-by: Yann Collet Cc: "H. Peter Anvin" Cc: Ingo Molnar Cc: Thomas Gleixner Cc: Russell King Cc: Borislav Petkov Cc: Florian Fainelli Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/lz4.h | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 include/linux/lz4.h (limited to 'include') diff --git a/include/linux/lz4.h b/include/linux/lz4.h new file mode 100644 index 0000000..7f6c75a --- /dev/null +++ b/include/linux/lz4.h @@ -0,0 +1,51 @@ +#ifndef __LZ4_H__ +#define __LZ4_H__ +/* + * LZ4 Kernel Interface + * + * Copyright (C) 2013, LG Electronics, Kyungsik Lee + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/* + * lz4_compressbound() + * Provides the maximum size that LZ4 may output in a "worst case" scenario + * (input data not compressible) + */ +static inline size_t lz4_compressbound(size_t isize) +{ + return isize + (isize / 255) + 16; +} + +/* + * lz4_decompress() + * src : source address of the compressed data + * src_len : is the input size, whcih is returned after decompress done + * dest : output buffer address of the decompressed data + * actual_dest_len: is the size of uncompressed data, supposing it's known + * return : Success if return 0 + * Error if return (< 0) + * note : Destination buffer must be already allocated. + * slightly faster than lz4_decompress_unknownoutputsize() + */ +int lz4_decompress(const char *src, size_t *src_len, char *dest, + size_t actual_dest_len); + +/* + * lz4_decompress_unknownoutputsize() + * src : source address of the compressed data + * src_len : is the input size, therefore the compressed size + * dest : output buffer address of the decompressed data + * dest_len: is the max size of the destination buffer, which is + * returned with actual size of decompressed data after + * decompress done + * return : Success if return 0 + * Error if return (< 0) + * note : Destination buffer must be already allocated. + */ +int lz4_decompress_unknownoutputsize(const char *src, size_t src_len, + char *dest, size_t *dest_len); +#endif -- cgit v1.1 From ae59e751939d817c5dea1f07981d4b19c30c3a04 Mon Sep 17 00:00:00 2001 From: Kyungsik Lee Date: Mon, 8 Jul 2013 16:01:46 -0700 Subject: lib: add support for LZ4-compressed kernel Add support for extracting LZ4-compressed kernel images, as well as LZ4-compressed ramdisk images in the kernel boot process. Signed-off-by: Kyungsik Lee Cc: "H. Peter Anvin" Cc: Ingo Molnar Cc: Thomas Gleixner Cc: Russell King Cc: Borislav Petkov Cc: Florian Fainelli Cc: Yann Collet Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Conflicts: scripts/Makefile.lib Change-Id: I2ad2607d9edf0f41c7e7a621f1da72174b142e2d --- include/linux/decompress/unlz4.h | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 include/linux/decompress/unlz4.h (limited to 'include') diff --git a/include/linux/decompress/unlz4.h b/include/linux/decompress/unlz4.h new file mode 100644 index 0000000..d5b68bf --- /dev/null +++ b/include/linux/decompress/unlz4.h @@ -0,0 +1,10 @@ +#ifndef DECOMPRESS_UNLZ4_H +#define DECOMPRESS_UNLZ4_H + +int unlz4(unsigned char *inbuf, int len, + int(*fill)(void*, unsigned int), + int(*flush)(void*, unsigned int), + unsigned char *output, + int *pos, + void(*error)(char *x)); +#endif -- cgit v1.1 From 42ebaa6de16ebbef4a9e240b1726633f053b8e38 Mon Sep 17 00:00:00 2001 From: Chanho Min Date: Mon, 8 Jul 2013 16:01:49 -0700 Subject: lib: add lz4 compressor module This patchset is for supporting LZ4 compression and the crypto API using it. As shown below, the size of data is a little bit bigger but compressing speed is faster under the enabled unaligned memory access. We can use lz4 de/compression through crypto API as well. Also, It will be useful for another potential user of lz4 compression. lz4 Compression Benchmark: Compiler: ARM gcc 4.6.4 ARMv7, 1 GHz based board Kernel: linux 3.4 Uncompressed data Size: 101 MB Compressed Size compression Speed LZO 72.1MB 32.1MB/s, 33.0MB/s(UA) LZ4 75.1MB 30.4MB/s, 35.9MB/s(UA) LZ4HC 59.8MB 2.4MB/s, 2.5MB/s(UA) - UA: Unaligned memory Access support - Latest patch set for LZO applied This patch: Add support for LZ4 compression in the Linux Kernel. LZ4 Compression APIs for kernel are based on LZ4 implementation by Yann Collet and were changed for kernel coding style. LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html LZ4 source repository : http://code.google.com/p/lz4/ svn revision : r90 Two APIs are added: lz4_compress() support basic lz4 compression whereas lz4hc_compress() support high compression or CPU performance get lower but compression ratio get higher. Also, we require the pre-allocated working memory with the defined size and destination buffer must be allocated with the size of lz4_compressbound. [akpm@linux-foundation.org: make lz4_compresshcctx() static] Signed-off-by: Chanho Min Cc: "Darrick J. Wong" Cc: Bob Pearson Cc: Richard Weinberger Cc: Herbert Xu Cc: Yann Collet Cc: Kyungsik Lee Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/lz4.h | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'include') diff --git a/include/linux/lz4.h b/include/linux/lz4.h index 7f6c75a..d21c13f 100644 --- a/include/linux/lz4.h +++ b/include/linux/lz4.h @@ -9,6 +9,8 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#define LZ4_MEM_COMPRESS (4096 * sizeof(unsigned char *)) +#define LZ4HC_MEM_COMPRESS (65538 * sizeof(unsigned char *)) /* * lz4_compressbound() @@ -21,6 +23,40 @@ static inline size_t lz4_compressbound(size_t isize) } /* + * lz4_compress() + * src : source address of the original data + * src_len : size of the original data + * dst : output buffer address of the compressed data + * This requires 'dst' of size LZ4_COMPRESSBOUND. + * dst_len : is the output size, which is returned after compress done + * workmem : address of the working memory. + * This requires 'workmem' of size LZ4_MEM_COMPRESS. + * return : Success if return 0 + * Error if return (< 0) + * note : Destination buffer and workmem must be already allocated with + * the defined size. + */ +int lz4_compress(const unsigned char *src, size_t src_len, + unsigned char *dst, size_t *dst_len, void *wrkmem); + + /* + * lz4hc_compress() + * src : source address of the original data + * src_len : size of the original data + * dst : output buffer address of the compressed data + * This requires 'dst' of size LZ4_COMPRESSBOUND. + * dst_len : is the output size, which is returned after compress done + * workmem : address of the working memory. + * This requires 'workmem' of size LZ4HC_MEM_COMPRESS. + * return : Success if return 0 + * Error if return (< 0) + * note : Destination buffer and workmem must be already allocated with + * the defined size. + */ +int lz4hc_compress(const unsigned char *src, size_t src_len, + unsigned char *dst, size_t *dst_len, void *wrkmem); + +/* * lz4_decompress() * src : source address of the compressed data * src_len : is the input size, whcih is returned after decompress done -- cgit v1.1 From fab4f77d0ecc98293ec060bc9c77303db7dbdc46 Mon Sep 17 00:00:00 2001 From: Sergey Senozhatsky Date: Wed, 11 Sep 2013 14:26:32 -0700 Subject: lz4: fix compression/decompression signedness mismatch LZ4 compression and decompression functions require different in signedness input/output parameters: unsigned char for compression and signed char for decompression. Change decompression API to require "(const) unsigned char *". Signed-off-by: Sergey Senozhatsky Cc: Kyungsik Lee Cc: Geert Uytterhoeven Cc: Yann Collet Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/lz4.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/linux/lz4.h b/include/linux/lz4.h index d21c13f..4356686 100644 --- a/include/linux/lz4.h +++ b/include/linux/lz4.h @@ -67,8 +67,8 @@ int lz4hc_compress(const unsigned char *src, size_t src_len, * note : Destination buffer must be already allocated. * slightly faster than lz4_decompress_unknownoutputsize() */ -int lz4_decompress(const char *src, size_t *src_len, char *dest, - size_t actual_dest_len); +int lz4_decompress(const unsigned char *src, size_t *src_len, + unsigned char *dest, size_t actual_dest_len); /* * lz4_decompress_unknownoutputsize() @@ -82,6 +82,6 @@ int lz4_decompress(const char *src, size_t *src_len, char *dest, * Error if return (< 0) * note : Destination buffer must be already allocated. */ -int lz4_decompress_unknownoutputsize(const char *src, size_t src_len, - char *dest, size_t *dest_len); +int lz4_decompress_unknownoutputsize(const unsigned char *src, size_t src_len, + unsigned char *dest, size_t *dest_len); #endif -- cgit v1.1 From 032a8919a9dfc0043218efa04efccf58509e239f Mon Sep 17 00:00:00 2001 From: Minchan Kim Date: Thu, 9 Oct 2014 15:29:50 -0700 Subject: zsmalloc: change return value unit of zs_get_total_size_bytes zs_get_total_size_bytes returns a amount of memory zsmalloc consumed with *byte unit* but zsmalloc operates *page unit* rather than byte unit so let's change the API so benefit we could get is that reduce unnecessary overhead (ie, change page unit with byte unit) in zsmalloc. Since return type is pages, "zs_get_total_pages" is better than "zs_get_total_size_bytes". Signed-off-by: Minchan Kim Reviewed-by: Dan Streetman Cc: Sergey Senozhatsky Cc: Jerome Marchand Cc: Cc: Cc: Luigi Semenzato Cc: Nitin Gupta Cc: Seth Jennings Cc: David Horner Cc: Joonsoo Kim Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Conflicts: mm/zsmalloc.c Change-Id: If5697d7b7f8ebaab3b58c1f9f84de747eb909ca3 --- include/linux/zsmalloc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/zsmalloc.h b/include/linux/zsmalloc.h index e44d634..05c2147 100644 --- a/include/linux/zsmalloc.h +++ b/include/linux/zsmalloc.h @@ -46,6 +46,6 @@ void *zs_map_object(struct zs_pool *pool, unsigned long handle, enum zs_mapmode mm); void zs_unmap_object(struct zs_pool *pool, unsigned long handle); -u64 zs_get_total_size_bytes(struct zs_pool *pool); +unsigned long zs_get_total_pages(struct zs_pool *pool); #endif -- cgit v1.1 From a6ce37fb73dce407da9d7d1d03408602be84177c Mon Sep 17 00:00:00 2001 From: Vinayak Menon Date: Wed, 25 Feb 2015 19:43:59 +0530 Subject: mm: swap: don't delay swap free for fast swap devices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are couple of issues with swapcache usage when ZRAM is used as swap device. 1) Kernel does a swap readahead which can be around 6 to 8 pages depending on total ram, which is not required for zram since accesses are fast. 2) Kernel delays the freeing up of swapcache expecting a later hit, which again is useless in the case of zram. 3) This is not related to swapcache, but zram usage itself. As mentioned in (2) kernel delays freeing of swapcache, but along with that it delays zram compressed page free also. i.e. there can be 2 copies, though one is compressed. This patch addresses these issues using two new flags QUEUE_FLAG_FAST and SWP_FAST, to indicate that accesses to the device will be fast and cheap, and instructs the swap layer to free up swap space agressively, and not to do read ahead. Change-Id: I5d2d5176a5f9420300bb2f843f6ecbdb25ea80e4 Signed-off-by: Vinayak Menon Signed-off-by: D. Andrei Măceș Conflicts: include/linux/blkdev.h include/linux/swap.h mm/swap_state.c mm/swapfile.c Conflicts: include/linux/blkdev.h --- include/linux/blkdev.h | 2 ++ include/linux/swap.h | 20 +++++++++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 1b13021..af75d16 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -403,6 +403,7 @@ struct request_queue #define QUEUE_FLAG_NOXMERGES 15 /* No extended merges */ #define QUEUE_FLAG_ADD_RANDOM 16 /* Contributes to random pool */ #define QUEUE_FLAG_SECDISCARD 17 /* supports SECDISCARD */ +#define QUEUE_FLAG_FAST 20 /* fast block device (e.g. ram based) */ #define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \ (1 << QUEUE_FLAG_STACKABLE) | \ @@ -487,6 +488,7 @@ static inline void queue_flag_clear(unsigned int flag, struct request_queue *q) #define blk_queue_discard(q) test_bit(QUEUE_FLAG_DISCARD, &(q)->queue_flags) #define blk_queue_secdiscard(q) (blk_queue_discard(q) && \ test_bit(QUEUE_FLAG_SECDISCARD, &(q)->queue_flags)) +#define blk_queue_fast(q) test_bit(QUEUE_FLAG_FAST, &(q)->queue_flags) #define blk_noretry_request(rq) \ ((rq)->cmd_flags & (REQ_FAILFAST_DEV|REQ_FAILFAST_TRANSPORT| \ diff --git a/include/linux/swap.h b/include/linux/swap.h index e73799d..be5eecc 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -150,6 +150,7 @@ enum { SWP_BLKDEV = (1 << 6), /* its a block device */ /* add others here before... */ SWP_SCANNING = (1 << 8), /* refcount in scan_swap_map */ + SWP_FAST = (1 << 9), /* blkdev access is fast and cheap */ }; #define SWAP_CLUSTER_MAX 32 @@ -201,9 +202,6 @@ struct swap_list_t { int next; /* swapfile to be used next */ }; -/* Swap 50% full? Release swapcache more aggressively.. */ -#define vm_swap_full() (nr_swap_pages*2 < total_swap_pages) - /* linux/mm/page_alloc.c */ extern unsigned long totalram_pages; extern unsigned long totalreserve_pages; @@ -320,6 +318,21 @@ extern struct page *swapin_readahead(swp_entry_t, gfp_t, /* linux/mm/swapfile.c */ extern long nr_swap_pages; extern long total_swap_pages; +extern bool is_swap_fast(swp_entry_t entry); + +/* Swap 50% full? Release swapcache more aggressively.. */ +static inline bool vm_swap_full(struct swap_info_struct *si) +{ + /* + * If the swap device is fast, return true + * not to delay swap free. + */ + if (si->flags & SWP_FAST) + return true; + + return nr_swap_pages*2 < total_swap_pages; +} + extern void si_swapinfo(struct sysinfo *); extern swp_entry_t get_swap_page(void); extern swp_entry_t get_swap_page_of_type(int); @@ -379,6 +392,7 @@ static inline void mem_cgroup_uncharge_swap(swp_entry_t ent) #define nr_swap_pages 0L #define total_swap_pages 0L #define total_swapcache_pages 0UL +#define vm_swap_full(si) 0 #define si_swapinfo(val) \ do { (val)->freeswap = (val)->totalswap = 0; } while (0) -- cgit v1.1 From 4698b1b9e737365e206f1ef55a864d8e205fe8f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=2E=20Andrei=20M=C4=83ce=C8=99?= Date: Wed, 30 Sep 2015 15:18:37 -0400 Subject: mm: Need page_swap_info() helper method from upstream Stolen from commit f981c5950fa85916ba49bea5d9a7a5078f47e569: "mm: methods for teaching filesystems about PG_swapcache pages" Change-Id: I6673913f9c825d3a6de88a652e99bcaf04eb1dd6 --- include/linux/swap.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/swap.h b/include/linux/swap.h index be5eecc..bd6e937 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -348,6 +348,7 @@ extern int swap_type_of(dev_t, sector_t, struct block_device **); extern unsigned int count_swap_pages(int, int); extern sector_t map_swap_page(struct page *, struct block_device **); extern sector_t swapdev_block(int, pgoff_t); +extern struct swap_info_struct *page_swap_info(struct page *); extern int reuse_swap_page(struct page *); extern int try_to_free_swap(struct page *); struct backing_dev_info; -- cgit v1.1 From 1e291c9a70e255278ddb451097f0d65126556b61 Mon Sep 17 00:00:00 2001 From: Dan Magenheimer Date: Wed, 25 Jan 2012 16:58:46 -0800 Subject: mm: implement WasActive page flag (for improving cleancache) (Feedback welcome if there is a different/better way to do this without using a page flag!) Since about 2.6.27, the page replacement algorithm maintains an "active" bit to help decide which pages are most eligible to reclaim, see http://linux-mm.org/PageReplacementDesign This "active' information is also useful to cleancache but is lost by the time that cleancache has the opportunity to preserve the pageful of data. This patch adds a new page flag "WasActive" to retain the state. The flag may possibly be useful elsewhere. It is up to each cleancache backend to utilize the bit as it desires. The matching patch for zcache is included here for clarification/discussion purposes, though it will need to go through GregKH and the staging tree. The patch resolves issues reported with cleancache which occur especially during streaming workloads on older processors, see https://lkml.org/lkml/2011/8/17/351 Signed-off-by: Dan Magenheimer Conflicts: include/linux/page-flags.h Change-Id: I0fcb2302a7b9c5e66db005229f679baee90f262f Conflicts: include/linux/page-flags.h --- include/linux/page-flags.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include') diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index 87a0009..657ba2c 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h @@ -51,6 +51,9 @@ * PG_hwpoison indicates that a page got corrupted in hardware and contains * data with incorrect ECC bits that triggered a machine check. Accessing is * not safe since it may cause another machine check. Don't touch! + * + * PG_wasactive reflects that a page previously was promoted to active status. + * Such pages should be considered higher priority for cleancache backends. */ /* @@ -107,6 +110,9 @@ enum pageflags { #ifdef CONFIG_TRANSPARENT_HUGEPAGE PG_compound_lock, #endif +#ifdef CONFIG_CLEANCACHE + PG_was_active, +#endif __NR_PAGEFLAGS, /* Filesystems */ @@ -264,6 +270,10 @@ __PAGEFLAG(SlobFree, slob_free) __PAGEFLAG(SlubFrozen, slub_frozen) +#ifdef CONFIG_CLEANCACHE +PAGEFLAG(WasActive, was_active) +#endif + /* * Private page markings that may be used by the filesystem that owns the page * for its own purposes. -- cgit v1.1 From 51ec83132ab250883b0a1393dd73cbfdb92226cb Mon Sep 17 00:00:00 2001 From: Hong-Mei Li Date: Wed, 3 Jun 2015 14:28:48 -0700 Subject: kernel: avoid adding non-thread-group task to LMK rbtree To maintain the task adj RB tree, we add a task to the RB tree when fork, and delete it when exit. The place is exactly the same as the linear p->tasks list, only when the task is thread_group_leader. But to handle the oom_score_adj change case, which did not check the thread_group_leader, we may del/add a non-leader task to the RB tree. Finally leave the task in the RB tree, since we would not really delete a non-leader task from the tree. The orphan task would finally be freed, and cause later use-after-free panic when accessing RB tree. Solution: Move the rbtree adj_node to signal_struct, which is shared between task and all threads. This can make sure we only add one node for a thread group. Change-Id: I1e8dfe490656408863b3726c7bc9e4ee6dc5abc1 Signed-off-by: Hong-Mei Li Reviewed-on: http://gerrit.mot.com/754224 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Zhi-Ming Yuan Reviewed-by: Yi-Wei Zhao Submit-Approved: Jira Key (cherry picked from commit b3f12a2465542888ec5c868c38022e0e5f7631ca) Signed-off-by: Abdul Salam Reviewed-on: http://gerrit.mot.com/766108 Reviewed-by: Sudharsan Yettapu Reviewed-by: Ravikumar Vembu (cherry picked from commit 558ef1fceae5d4c8509cb2a40d98c841525f7ea3) Reviewed-on: http://gerrit.mot.com/768300 Conflicts: kernel/fork.c --- include/linux/sched.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/linux/sched.h b/include/linux/sched.h index ad2f17f..6d2e888 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -645,11 +645,13 @@ struct signal_struct { struct rw_semaphore threadgroup_fork_lock; #endif - int oom_adj; /* OOM kill score adjustment (bit shift) */ - int oom_score_adj; /* OOM kill score adjustment */ - int oom_score_adj_min; /* OOM kill score adjustment minimum value. + int oom_adj; /* OOM kill score adjustment (bit shift) */ + short oom_score_adj; /* OOM kill score adjustment */ + short oom_score_adj_min;/* OOM kill score adjustment min value. * Only settable by CAP_SYS_RESOURCE. */ - +#ifdef CONFIG_ANDROID_LMK_ADJ_RBTREE + struct rb_node adj_node; +#endif struct mutex cred_guard_mutex; /* guard against foreign influences on * credential calculations * (notably. ptrace) */ -- cgit v1.1 From 6f04da23b1e3aa60626bfef868ee89a77cebd637 Mon Sep 17 00:00:00 2001 From: Hong-Mei Li Date: Fri, 28 Jun 2013 19:26:38 +0800 Subject: staging: android: lowmemorykiller: implement task's adj rbtree MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Based on the current LMK implementation, LMK has to scan all processes to select the correct task to kill during low memory. The basic idea for the optimization is to : queue all tasks with oom_score_adj priority, and then LMK just selects the proper task from the queue(rbtree) to kill. performance improvement: the current implementation: average time to find a task to kill : 1004us the optimized implementation: average time to find a task to kill: 43us Change-Id: I4dbbdd5673314dbbdabb71c3eff0dc229ce4ea91 Signed-off-by: Hong-Mei Li Reviewed-on: http://gerrit.pcs.mot.com/548917 SLT-Approved: Slta Waiver Tested-by: Jira Key Reviewed-by: Yi-Wei Zhao Submit-Approved: Jira Key Signed-off-by: D. Andrei Măceș Conflicts: drivers/staging/android/Kconfig drivers/staging/android/lowmemorykiller.c fs/proc/base.c mm/oom_kill.c Conflicts: drivers/staging/android/lowmemorykiller.c mm/oom_kill.c Conflicts: mm/oom_kill.c Conflicts: drivers/staging/android/lowmemorykiller.c mm/oom_kill.c --- include/linux/sched.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include') diff --git a/include/linux/sched.h b/include/linux/sched.h index 6d2e888..6b030a5 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1284,6 +1284,9 @@ struct task_struct { #endif struct list_head tasks; +#ifdef CONFIG_ANDROID_LMK_ADJ_RBTREE + struct rb_node adj_node; +#endif #ifdef CONFIG_SMP struct plist_node pushable_tasks; #endif @@ -1623,6 +1626,13 @@ static inline struct pid *task_tgid(struct task_struct *task) return task->group_leader->pids[PIDTYPE_PID].pid; } +#ifdef CONFIG_ANDROID_LMK_ADJ_RBTREE +extern void add_2_adj_tree(struct task_struct *task); +extern void delete_from_adj_tree(struct task_struct *task); +#else +static inline void add_2_adj_tree(struct task_struct *task) { } +static inline void delete_from_adj_tree(struct task_struct *task) { } +#endif /* * Without tasklist or rcu lock it is not safe to dereference * the result of task_pgrp/task_session even if task == current, -- cgit v1.1 From 6112c4d4e3408cf2aea5a626a3e39ba3922094c5 Mon Sep 17 00:00:00 2001 From: Zhao Wei Liew Date: Wed, 17 Aug 2016 08:26:53 +0100 Subject: power: max17042_battery: Set type to UNKNOWN This is a fuelgauge driver, not an actual battery driver. Setting its type to 'Battery' will confuse healthd, causing healthd to pick this driver instead of the actual battery driver for reading battery stats. Issue-Id: NIGHTLIES-3279 Change-Id: Ia45e74599d391a90cb526aa07a2525b64c3eec96 --- include/linux/power_supply.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h index 8289fca..35b7ed6 100644 --- a/include/linux/power_supply.h +++ b/include/linux/power_supply.h @@ -146,6 +146,7 @@ enum power_supply_type { POWER_SUPPLY_TYPE_WIRELESS, POWER_SUPPLY_TYPE_UARTOFF, POWER_SUPPLY_TYPE_OTG, + POWER_SUPPLY_TYPE_UNKNOWN, }; enum { -- cgit v1.1 From 8aa6fa75955db416644e6c9367b350c25cb6745c Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Mon, 5 Oct 2015 16:13:04 +0200 Subject: mm: add a field to store names for private anonymous memory Userspace processes often have multiple allocators that each do anonymous mmaps to get memory. When examining memory usage of individual processes or systems as a whole, it is useful to be able to break down the various heaps that were allocated by each layer and examine their size, RSS, and physical memory usage. This patch adds a user pointer to the shared union in vm_area_struct that points to a null terminated string inside the user process containing a name for the vma. vmas that point to the same address will be merged, but vmas that point to equivalent strings at different addresses will not be merged. Userspace can set the name for a region of memory by calling prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, start, len, (unsigned long)name); Setting the name to NULL clears it. The names of named anonymous vmas are shown in /proc/pid/maps as [anon:] and in /proc/pid/smaps in a new "Name" field that is only present for named vmas. If the userspace pointer is no longer valid all or part of the name will be replaced with "". The idea to store a userspace pointer to reduce the complexity within mm (at the expense of the complexity of reading /proc/pid/mem) came from Dave Hansen. This results in no runtime overhead in the mm subsystem other than comparing the anon_name pointers when considering vma merging. The pointer is stored in a union with fieds that are only used on file-backed mappings, so it does not increase memory usage. Change-Id: I53b093d98dc24f41377824f34e076edced4a6f07 --- include/linux/mm.h | 2 +- include/linux/mm_types.h | 15 +++++++++++++++ include/linux/prctl.h | 3 +++ 3 files changed, 19 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/mm.h b/include/linux/mm.h index d5dc6af..92a055b 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1418,7 +1418,7 @@ extern int vma_adjust(struct vm_area_struct *vma, unsigned long start, extern struct vm_area_struct *vma_merge(struct mm_struct *, struct vm_area_struct *prev, unsigned long addr, unsigned long end, unsigned long vm_flags, struct anon_vma *, struct file *, pgoff_t, - struct mempolicy *); + struct mempolicy *, const char __user *); extern struct anon_vma *find_mergeable_anon_vma(struct vm_area_struct *); extern int split_vma(struct mm_struct *, struct vm_area_struct *, unsigned long addr, int new_below); diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 059839c..557f9b6 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -162,6 +162,10 @@ struct vm_area_struct { * linkage into the address_space->i_mmap prio tree, or * linkage to the list of like vmas hanging off its node, or * linkage of vma in the address_space->i_mmap_nonlinear list. + * + * For private anonymous mappings, a pointer to a null terminated string + * in the user process containing the name given to the vma, or NULL + * if unnamed. */ union { struct { @@ -171,6 +175,7 @@ struct vm_area_struct { } vm_set; struct raw_prio_tree_node prio_tree_node; + const char __user *anon_name; } shared; /* @@ -345,4 +350,14 @@ static inline cpumask_t *mm_cpumask(struct mm_struct *mm) return mm->cpu_vm_mask_var; } + +/* Return the name for an anonymous mapping or NULL for a file-backed mapping */ +static inline const char __user *vma_get_anon_name(struct vm_area_struct *vma) +{ + if (vma->vm_file) + return NULL; + + return vma->shared.anon_name; +} + #endif /* _LINUX_MM_TYPES_H */ diff --git a/include/linux/prctl.h b/include/linux/prctl.h index a3baeb2..dd90287 100644 --- a/include/linux/prctl.h +++ b/include/linux/prctl.h @@ -102,4 +102,7 @@ #define PR_MCE_KILL_GET 34 +#define PR_SET_VMA 0x53564d41 +# define PR_SET_VMA_ANON_NAME 0 + #endif /* _LINUX_PRCTL_H */ -- cgit v1.1 From ca3aa2bccc89a21ccf2bbfdf59545cbf0cb9c977 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 17 Aug 2016 05:56:26 -0700 Subject: tcp: fix use after free in tcp_xmit_retransmit_queue() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When tcp_sendmsg() allocates a fresh and empty skb, it puts it at the tail of the write queue using tcp_add_write_queue_tail() Then it attempts to copy user data into this fresh skb. If the copy fails, we undo the work and remove the fresh skb. Unfortunately, this undo lacks the change done to tp->highest_sack and we can leave a dangling pointer (to a freed skb) Later, tcp_xmit_retransmit_queue() can dereference this pointer and access freed memory. For regular kernels where memory is not unmapped, this might cause SACK bugs because tcp_highest_sack_seq() is buggy, returning garbage instead of tp->snd_nxt, but with various debug features like CONFIG_DEBUG_PAGEALLOC, this can crash the kernel. This bug was found by Marco Grassi thanks to syzkaller. Change-Id: I264f97d30d0a623011d9ee811c63fa0e0c2149a2 Fixes: 6859d49475d4 ("[TCP]: Abstract tp->highest_sack accessing & point to next skb") Reported-by: Marco Grassi Signed-off-by: Eric Dumazet Cc: Ilpo Järvinen Cc: Yuchung Cheng Cc: Neal Cardwell Acked-by: Neal Cardwell Reviewed-by: Cong Wang Signed-off-by: David S. Miller --- include/net/tcp.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/net/tcp.h b/include/net/tcp.h index 0f6a452..4fdc312 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1250,6 +1250,8 @@ static inline void tcp_check_send_head(struct sock *sk, struct sk_buff *skb_unli { if (sk->sk_send_head == skb_unlinked) sk->sk_send_head = NULL; + if (tcp_sk(sk)->highest_sack == skb_unlinked) + tcp_sk(sk)->highest_sack = NULL; } static inline void tcp_init_send_head(struct sock *sk) -- cgit v1.1 From 6c0837fc69be45a1a1bf91c433ac3a4955597c4e Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 20 Oct 2016 00:49:40 +0200 Subject: mm: remove gup_flags FOLL_WRITE games from __get_user_pages() This is an ancient bug that was actually attempted to be fixed once (badly) by me eleven years ago in commit 4ceb5db9757a ("Fix get_user_pages() race for write access") but that was then undone due to problems on s390 by commit f33ea7f404e5 ("fix get_user_pages bug"). In the meantime, the s390 situation has long been fixed, and we can now fix it by checking the pte_dirty() bit properly (and do it better). The s390 dirty bit was implemented in abf09bed3cce ("s390/mm: implement software dirty bits") which made it into v3.9. Earlier kernels will have to look at the page state itself. Also, the VM has become more scalable, and what used a purely theoretical race back then has become easier to trigger. To fix it, we introduce a new internal FOLL_COW flag to mark the "yes, we already did a COW" rather than play racy games with FOLL_WRITE that is very fundamental, and then use the pte dirty flag to validate that the FOLL_COW flag is still valid. Change-Id: Id9bec3722797dff7d0ff0d9f6097c4229e31fd62 Reported-and-tested-by: Phil "not Paul" Oester Acked-by: Hugh Dickins Reviewed-by: Michal Hocko Cc: Andy Lutomirski Cc: Kees Cook Cc: Oleg Nesterov Cc: Willy Tarreau Cc: Nick Piggin Cc: Greg Thelen Cc: stable@vger.kernel.org Signed-off-by: Linus Torvalds [wt: s/gup.c/memory.c; s/follow_page_pte/follow_page_mask; s/faultin_page/__get_user_page] Signed-off-by: Willy Tarreau --- include/linux/mm.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/mm.h b/include/linux/mm.h index 92a055b..b465c7f 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1574,6 +1574,7 @@ struct page *follow_page(struct vm_area_struct *, unsigned long address, #define FOLL_SPLIT 0x80 /* don't return transhuge pages, split them */ #define FOLL_HWPOISON 0x100 /* check page is hwpoisoned */ #define FOLL_NO_CMA 0x200 /* avoid putting pages to CMA regions */ +#define FOLL_COW 0x4000 /* internal GUP flag */ typedef int (*pte_fn_t)(pte_t *pte, pgtable_t token, unsigned long addr, void *data); -- cgit v1.1 From ab5cf14fb4432d2550896d37e77aa88c335ce9b8 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Fri, 15 Jun 2012 14:31:33 +0800 Subject: BACKPORT: perf: Introduce perf_pmu_migrate_context() Originally from Peter Zijlstra. The helper migrates perf events from one cpu to another cpu. Conflicts (perf: Fix race in removing an event): kernel/events/core.c Change-Id: I7885fe36c9e2803b10477d556163197085be3d19 Signed-off-by: Zheng Yan Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1339741902-8449-5-git-send-email-zheng.z.yan@intel.com Signed-off-by: Ingo Molnar --- include/linux/perf_event.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index e4d3640..42dc246 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -979,6 +979,8 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu, struct task_struct *task, perf_overflow_handler_t callback); +extern void perf_pmu_migrate_context(struct pmu *pmu, + int src_cpu, int dst_cpu); extern u64 perf_event_read_value(struct perf_event *event, u64 *enabled, u64 *running); -- cgit v1.1 From 699bf014212c71ebdb99850682947e8ad19a7499 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Thu, 24 Jan 2013 21:53:17 +0100 Subject: BACKPORT: lockdep: Silence warning if CONFIG_LOCKDEP isn't set MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since commit c9a4962881929df7f1ef6e63e1b9da304faca4dd ("nfsd: make client_lock per net") compiling nfs4state.o without CONFIG_LOCKDEP set, triggers this GCC warning: fs/nfsd/nfs4state.c: In function ‘free_client’: fs/nfsd/nfs4state.c:1051:19: warning: unused variable ‘nn’ [-Wunused-variable] The cause of that warning is that lockdep_assert_held() compiles away if CONFIG_LOCKDEP is not set. Silence this warning by using the argument to lockdep_assert_held() as a nop if CONFIG_LOCKDEP is not set. Signed-off-by: Paul Bolle Cc: Peter Zijlstra Cc: Stanislav Kinsbursky Cc: J. Bruce Fields Link: http://lkml.kernel.org/r/1359060797.1325.33.camel@x61.thuisdomein Signed-off-by: Ingo Molnar -- include/linux/lockdep.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Change-Id: I4a4e78fd92dccffe5fc7c3a2617ef7d4cf59f738 --- include/linux/lockdep.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h index ef820a3..ee4410a 100644 --- a/include/linux/lockdep.h +++ b/include/linux/lockdep.h @@ -390,7 +390,7 @@ struct lock_class_key { }; #define lockdep_depth(tsk) (0) -#define lockdep_assert_held(l) do { } while (0) +#define lockdep_assert_held(l) do { (void)(l); } while (0) #endif /* !LOCKDEP */ -- cgit v1.1 From 12bf2ab391d33a49d74b123b66ef87c4ffa14e2e Mon Sep 17 00:00:00 2001 From: John Dias Date: Mon, 10 Oct 2016 14:44:30 -0700 Subject: perf: protect group_leader from races that cause ctx double-free When moving a group_leader perf event from a software-context to a hardware-context, there's a race in checking and updating that context. The existing locking solution doesn't work; note that it tries to grab a lock inside the group_leader's context object, which you can only get at by going through a pointer that should be protected from these races. To avoid that problem, and to produce a simple solution, we can just use a lock per group_leader to protect all checks on the group_leader's context. The new lock is grabbed and released when no context locks are held. RM-290 Bug: 30955111 Bug: 31095224 Change-Id: If37124c100ca6f4aa962559fba3bd5dbbec8e052 --- include/linux/perf_event.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include') diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 42dc246..82660a6 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -757,6 +757,12 @@ struct perf_event { int nr_siblings; int group_flags; struct perf_event *group_leader; + + /* + * Protect the pmu, attributes and context of a group leader. + * Note: does not protect the pointer to the group_leader. + */ + struct mutex group_leader_mutex; struct pmu *pmu; enum perf_event_active_state state; -- cgit v1.1