Commit 54c0a4b4 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'akpm' (incoming from Andrew)

Merge misc updates from Andrew Morton:

 - a few hotfixes

 - dynamic-debug updates

 - ipc updates

 - various other sweepings off the factory floor

* akpm: (31 commits)
  firmware/google: drop 'select EFI' to avoid recursive dependency
  compat: fix sys_fanotify_mark
  checkpatch.pl: check for function declarations without arguments
  mm/migrate.c: fix setting of cpupid on page migration twice against normal page
  softirq: use const char * const for softirq_to_name, whitespace neatening
  softirq: convert printks to pr_<level>
  softirq: use ffs() in __do_softirq()
  kernel/kexec.c: use vscnprintf() instead of vsnprintf() in vmcoreinfo_append_str()
  splice: fix unexpected size truncation
  ipc: fix compat msgrcv with negative msgtyp
  ipc,msg: document barriers
  ipc: delete seq_max field in struct ipc_ids
  ipc: simplify sysvipc_proc_open() return
  ipc: remove useless return statement
  ipc: remove braces for single statements
  ipc: standardize code comments
  ipc: whitespace cleanup
  ipc: change kern_ipc_perm.deleted type to bool
  ipc: introduce ipc_valid_object() helper to sort out IPC_RMID races
  ipc/sem.c: avoid overflow of semop undo (semadj) value
  ...
parents 1b17366d c2218e26
...@@ -731,7 +731,7 @@ static void __init request_standard_resources(const struct machine_desc *mdesc) ...@@ -731,7 +731,7 @@ static void __init request_standard_resources(const struct machine_desc *mdesc)
kernel_data.end = virt_to_phys(_end - 1); kernel_data.end = virt_to_phys(_end - 1);
for_each_memblock(memory, region) { for_each_memblock(memory, region) {
res = memblock_virt_alloc(sizeof(*res), 0); res = memblock_virt_alloc_low(sizeof(*res), 0);
res->name = "System RAM"; res->name = "System RAM";
res->start = __pfn_to_phys(memblock_region_memory_base_pfn(region)); res->start = __pfn_to_phys(memblock_region_memory_base_pfn(region));
res->end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1; res->end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1;
......
...@@ -35,17 +35,11 @@ static struct console early_ocd_console = { ...@@ -35,17 +35,11 @@ static struct console early_ocd_console = {
static int __init setup_early_printk(char *buf) static int __init setup_early_printk(char *buf)
{ {
int keep_early;
if (!buf || early_console) if (!buf || early_console)
return 0; return 0;
if (strstr(buf, "keep"))
keep_early = 1;
early_console = &early_ocd_console; early_console = &early_ocd_console;
if (strstr(buf, "keep"))
if (keep_early)
early_console->flags &= ~CON_BOOT; early_console->flags &= ~CON_BOOT;
else else
early_console->flags |= CON_BOOT; early_console->flags |= CON_BOOT;
......
...@@ -51,9 +51,9 @@ extern int devmem_is_allowed(unsigned long pagenr); ...@@ -51,9 +51,9 @@ extern int devmem_is_allowed(unsigned long pagenr);
extern unsigned long max_low_pfn_mapped; extern unsigned long max_low_pfn_mapped;
extern unsigned long max_pfn_mapped; extern unsigned long max_pfn_mapped;
static inline phys_addr_t get_max_low_mapped(void) static inline phys_addr_t get_max_mapped(void)
{ {
return (phys_addr_t)max_low_pfn_mapped << PAGE_SHIFT; return (phys_addr_t)max_pfn_mapped << PAGE_SHIFT;
} }
bool pfn_range_is_mapped(unsigned long start_pfn, unsigned long end_pfn); bool pfn_range_is_mapped(unsigned long start_pfn, unsigned long end_pfn);
......
...@@ -1119,7 +1119,7 @@ void __init setup_arch(char **cmdline_p) ...@@ -1119,7 +1119,7 @@ void __init setup_arch(char **cmdline_p)
setup_real_mode(); setup_real_mode();
memblock_set_current_limit(get_max_low_mapped()); memblock_set_current_limit(get_max_mapped());
dma_contiguous_reserve(0); dma_contiguous_reserve(0);
/* /*
......
...@@ -12,8 +12,7 @@ menu "Google Firmware Drivers" ...@@ -12,8 +12,7 @@ menu "Google Firmware Drivers"
config GOOGLE_SMI config GOOGLE_SMI
tristate "SMI interface for Google platforms" tristate "SMI interface for Google platforms"
depends on ACPI && DMI depends on ACPI && DMI && EFI
select EFI
select EFI_VARS select EFI_VARS
help help
Say Y here if you want to enable SMI callbacks for Google Say Y here if you want to enable SMI callbacks for Google
......
...@@ -886,9 +886,9 @@ COMPAT_SYSCALL_DEFINE6(fanotify_mark, ...@@ -886,9 +886,9 @@ COMPAT_SYSCALL_DEFINE6(fanotify_mark,
{ {
return sys_fanotify_mark(fanotify_fd, flags, return sys_fanotify_mark(fanotify_fd, flags,
#ifdef __BIG_ENDIAN #ifdef __BIG_ENDIAN
((__u64)mask1 << 32) | mask0,
#else
((__u64)mask0 << 32) | mask1, ((__u64)mask0 << 32) | mask1,
#else
((__u64)mask1 << 32) | mask0,
#endif #endif
dfd, pathname); dfd, pathname);
} }
......
...@@ -948,7 +948,7 @@ static int ocfs2_unlink(struct inode *dir, ...@@ -948,7 +948,7 @@ static int ocfs2_unlink(struct inode *dir,
ocfs2_free_dir_lookup_result(&orphan_insert); ocfs2_free_dir_lookup_result(&orphan_insert);
ocfs2_free_dir_lookup_result(&lookup); ocfs2_free_dir_lookup_result(&lookup);
if (status && (status != -ENOTEMPTY)) if (status && (status != -ENOTEMPTY) && (status != -ENOENT))
mlog_errno(status); mlog_errno(status);
return status; return status;
......
...@@ -175,6 +175,27 @@ static inline void * __init memblock_virt_alloc_nopanic( ...@@ -175,6 +175,27 @@ static inline void * __init memblock_virt_alloc_nopanic(
NUMA_NO_NODE); NUMA_NO_NODE);
} }
#ifndef ARCH_LOW_ADDRESS_LIMIT
#define ARCH_LOW_ADDRESS_LIMIT 0xffffffffUL
#endif
static inline void * __init memblock_virt_alloc_low(
phys_addr_t size, phys_addr_t align)
{
return memblock_virt_alloc_try_nid(size, align,
BOOTMEM_LOW_LIMIT,
ARCH_LOW_ADDRESS_LIMIT,
NUMA_NO_NODE);
}
static inline void * __init memblock_virt_alloc_low_nopanic(
phys_addr_t size, phys_addr_t align)
{
return memblock_virt_alloc_try_nid_nopanic(size, align,
BOOTMEM_LOW_LIMIT,
ARCH_LOW_ADDRESS_LIMIT,
NUMA_NO_NODE);
}
static inline void * __init memblock_virt_alloc_from_nopanic( static inline void * __init memblock_virt_alloc_from_nopanic(
phys_addr_t size, phys_addr_t align, phys_addr_t min_addr) phys_addr_t size, phys_addr_t align, phys_addr_t min_addr)
{ {
...@@ -238,6 +259,22 @@ static inline void * __init memblock_virt_alloc_nopanic( ...@@ -238,6 +259,22 @@ static inline void * __init memblock_virt_alloc_nopanic(
return __alloc_bootmem_nopanic(size, align, BOOTMEM_LOW_LIMIT); return __alloc_bootmem_nopanic(size, align, BOOTMEM_LOW_LIMIT);
} }
static inline void * __init memblock_virt_alloc_low(
phys_addr_t size, phys_addr_t align)
{
if (!align)
align = SMP_CACHE_BYTES;
return __alloc_bootmem_low(size, align, BOOTMEM_LOW_LIMIT);
}
static inline void * __init memblock_virt_alloc_low_nopanic(
phys_addr_t size, phys_addr_t align)
{
if (!align)
align = SMP_CACHE_BYTES;
return __alloc_bootmem_low_nopanic(size, align, BOOTMEM_LOW_LIMIT);
}
static inline void * __init memblock_virt_alloc_from_nopanic( static inline void * __init memblock_virt_alloc_from_nopanic(
phys_addr_t size, phys_addr_t align, phys_addr_t min_addr) phys_addr_t size, phys_addr_t align, phys_addr_t min_addr)
{ {
......
...@@ -360,7 +360,7 @@ enum ...@@ -360,7 +360,7 @@ enum
/* map softirq index to softirq name. update 'softirq_to_name' in /* map softirq index to softirq name. update 'softirq_to_name' in
* kernel/softirq.c when adding a new softirq. * kernel/softirq.c when adding a new softirq.
*/ */
extern char *softirq_to_name[NR_SOFTIRQS]; extern const char * const softirq_to_name[NR_SOFTIRQS];
/* softirq mask and active fields moved to irq_cpustat_t in /* softirq mask and active fields moved to irq_cpustat_t in
* asm/hardirq.h to get better cache usage. KAO * asm/hardirq.h to get better cache usage. KAO
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
struct kern_ipc_perm struct kern_ipc_perm
{ {
spinlock_t lock; spinlock_t lock;
int deleted; bool deleted;
int id; int id;
key_t key; key_t key;
kuid_t uid; kuid_t uid;
......
...@@ -21,7 +21,6 @@ struct user_namespace; ...@@ -21,7 +21,6 @@ struct user_namespace;
struct ipc_ids { struct ipc_ids {
int in_use; int in_use;
unsigned short seq; unsigned short seq;
unsigned short seq_max;
struct rw_semaphore rwsem; struct rw_semaphore rwsem;
struct idr ipcs_idr; struct idr ipcs_idr;
int next_id; int next_id;
......
...@@ -9,7 +9,7 @@ struct msg_msg { ...@@ -9,7 +9,7 @@ struct msg_msg {
struct list_head m_list; struct list_head m_list;
long m_type; long m_type;
size_t m_ts; /* message text size */ size_t m_ts; /* message text size */
struct msg_msgseg* next; struct msg_msgseg *next;
void *security; void *security;
/* the actual message follows immediately */ /* the actual message follows immediately */
}; };
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
struct shmid_kernel /* private to the kernel */ struct shmid_kernel /* private to the kernel */
{ {
struct kern_ipc_perm shm_perm; struct kern_ipc_perm shm_perm;
struct file * shm_file; struct file *shm_file;
unsigned long shm_nattch; unsigned long shm_nattch;
unsigned long shm_segsz; unsigned long shm_segsz;
time_t shm_atim; time_t shm_atim;
......
...@@ -24,7 +24,8 @@ ...@@ -24,7 +24,8 @@
* Passed to the actors * Passed to the actors
*/ */
struct splice_desc { struct splice_desc {
unsigned int len, total_len; /* current and remaining length */ size_t total_len; /* remaining length */
unsigned int len; /* current length */
unsigned int flags; /* splice flags */ unsigned int flags; /* splice flags */
/* /*
* actor() private data * actor() private data
......
...@@ -92,8 +92,6 @@ static int kernel_init(void *); ...@@ -92,8 +92,6 @@ static int kernel_init(void *);
extern void init_IRQ(void); extern void init_IRQ(void);
extern void fork_init(unsigned long); extern void fork_init(unsigned long);
extern void mca_init(void);
extern void sbus_init(void);
extern void radix_tree_init(void); extern void radix_tree_init(void);
#ifndef CONFIG_DEBUG_RODATA #ifndef CONFIG_DEBUG_RODATA
static inline void mark_rodata_ro(void) { } static inline void mark_rodata_ro(void) { }
......
...@@ -197,7 +197,7 @@ static inline int __put_compat_ipc_perm(struct ipc64_perm *p, ...@@ -197,7 +197,7 @@ static inline int __put_compat_ipc_perm(struct ipc64_perm *p,
static inline int get_compat_semid64_ds(struct semid64_ds *s64, static inline int get_compat_semid64_ds(struct semid64_ds *s64,
struct compat_semid64_ds __user *up64) struct compat_semid64_ds __user *up64)
{ {
if (!access_ok (VERIFY_READ, up64, sizeof(*up64))) if (!access_ok(VERIFY_READ, up64, sizeof(*up64)))
return -EFAULT; return -EFAULT;
return __get_compat_ipc64_perm(&s64->sem_perm, &up64->sem_perm); return __get_compat_ipc64_perm(&s64->sem_perm, &up64->sem_perm);
} }
...@@ -205,7 +205,7 @@ static inline int get_compat_semid64_ds(struct semid64_ds *s64, ...@@ -205,7 +205,7 @@ static inline int get_compat_semid64_ds(struct semid64_ds *s64,
static inline int get_compat_semid_ds(struct semid64_ds *s, static inline int get_compat_semid_ds(struct semid64_ds *s,
struct compat_semid_ds __user *up) struct compat_semid_ds __user *up)
{ {
if (!access_ok (VERIFY_READ, up, sizeof(*up))) if (!access_ok(VERIFY_READ, up, sizeof(*up)))
return -EFAULT; return -EFAULT;
return __get_compat_ipc_perm(&s->sem_perm, &up->sem_perm); return __get_compat_ipc_perm(&s->sem_perm, &up->sem_perm);
} }
...@@ -215,7 +215,7 @@ static inline int put_compat_semid64_ds(struct semid64_ds *s64, ...@@ -215,7 +215,7 @@ static inline int put_compat_semid64_ds(struct semid64_ds *s64,
{ {
int err; int err;
if (!access_ok (VERIFY_WRITE, up64, sizeof(*up64))) if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64)))
return -EFAULT; return -EFAULT;
err = __put_compat_ipc64_perm(&s64->sem_perm, &up64->sem_perm); err = __put_compat_ipc64_perm(&s64->sem_perm, &up64->sem_perm);
err |= __put_user(s64->sem_otime, &up64->sem_otime); err |= __put_user(s64->sem_otime, &up64->sem_otime);
...@@ -229,7 +229,7 @@ static inline int put_compat_semid_ds(struct semid64_ds *s, ...@@ -229,7 +229,7 @@ static inline int put_compat_semid_ds(struct semid64_ds *s,
{ {
int err; int err;
if (!access_ok (VERIFY_WRITE, up, sizeof(*up))) if (!access_ok(VERIFY_WRITE, up, sizeof(*up)))
return -EFAULT; return -EFAULT;
err = __put_compat_ipc_perm(&s->sem_perm, &up->sem_perm); err = __put_compat_ipc_perm(&s->sem_perm, &up->sem_perm);
err |= __put_user(s->sem_otime, &up->sem_otime); err |= __put_user(s->sem_otime, &up->sem_otime);
...@@ -288,11 +288,11 @@ static long do_compat_semctl(int first, int second, int third, u32 pad) ...@@ -288,11 +288,11 @@ static long do_compat_semctl(int first, int second, int third, u32 pad)
break; break;
case IPC_SET: case IPC_SET:
if (version == IPC_64) { if (version == IPC_64)
err = get_compat_semid64_ds(&s64, compat_ptr(pad)); err = get_compat_semid64_ds(&s64, compat_ptr(pad));
} else { else
err = get_compat_semid_ds(&s64, compat_ptr(pad)); err = get_compat_semid_ds(&s64, compat_ptr(pad));
}
up64 = compat_alloc_user_space(sizeof(s64)); up64 = compat_alloc_user_space(sizeof(s64));
if (copy_to_user(up64, &s64, sizeof(s64))) if (copy_to_user(up64, &s64, sizeof(s64)))
err = -EFAULT; err = -EFAULT;
...@@ -376,12 +376,12 @@ COMPAT_SYSCALL_DEFINE6(ipc, u32, call, int, first, int, second, ...@@ -376,12 +376,12 @@ COMPAT_SYSCALL_DEFINE6(ipc, u32, call, int, first, int, second,
struct compat_ipc_kludge ipck; struct compat_ipc_kludge ipck;
if (!uptr) if (!uptr)
return -EINVAL; return -EINVAL;
if (copy_from_user (&ipck, uptr, sizeof(ipck))) if (copy_from_user(&ipck, uptr, sizeof(ipck)))
return -EFAULT; return -EFAULT;
uptr = compat_ptr(ipck.msgp); uptr = compat_ptr(ipck.msgp);
fifth = ipck.msgtyp; fifth = ipck.msgtyp;
} }
return do_msgrcv(first, uptr, second, fifth, third, return do_msgrcv(first, uptr, second, (s32)fifth, third,
compat_do_msg_fill); compat_do_msg_fill);
} }
case MSGGET: case MSGGET:
...@@ -515,11 +515,11 @@ long compat_sys_msgctl(int first, int second, void __user *uptr) ...@@ -515,11 +515,11 @@ long compat_sys_msgctl(int first, int second, void __user *uptr)
break; break;
case IPC_SET: case IPC_SET:
if (version == IPC_64) { if (version == IPC_64)
err = get_compat_msqid64(&m64, uptr); err = get_compat_msqid64(&m64, uptr);
} else { else
err = get_compat_msqid(&m64, uptr); err = get_compat_msqid(&m64, uptr);
}
if (err) if (err)
break; break;
p = compat_alloc_user_space(sizeof(m64)); p = compat_alloc_user_space(sizeof(m64));
...@@ -702,11 +702,11 @@ long compat_sys_shmctl(int first, int second, void __user *uptr) ...@@ -702,11 +702,11 @@ long compat_sys_shmctl(int first, int second, void __user *uptr)
case IPC_SET: case IPC_SET:
if (version == IPC_64) { if (version == IPC_64)
err = get_compat_shmid64_ds(&s64, uptr); err = get_compat_shmid64_ds(&s64, uptr);
} else { else
err = get_compat_shmid_ds(&s64, uptr); err = get_compat_shmid_ds(&s64, uptr);
}
if (err) if (err)
break; break;
p = compat_alloc_user_space(sizeof(s64)); p = compat_alloc_user_space(sizeof(s64));
......
...@@ -64,7 +64,7 @@ asmlinkage long compat_sys_mq_open(const char __user *u_name, ...@@ -64,7 +64,7 @@ asmlinkage long compat_sys_mq_open(const char __user *u_name,
return sys_mq_open(u_name, oflag, mode, p); return sys_mq_open(u_name, oflag, mode, p);
} }
static int compat_prepare_timeout(struct timespec __user * *p, static int compat_prepare_timeout(struct timespec __user **p,
const struct compat_timespec __user *u) const struct compat_timespec __user *u)
{ {
struct timespec ts; struct timespec ts;
......
...@@ -164,21 +164,21 @@ static struct ctl_table ipc_kern_table[] = { ...@@ -164,21 +164,21 @@ static struct ctl_table ipc_kern_table[] = {
{ {
.procname = "shmmax", .procname = "shmmax",
.data = &init_ipc_ns.shm_ctlmax, .data = &init_ipc_ns.shm_ctlmax,
.maxlen = sizeof (init_ipc_ns.shm_ctlmax), .maxlen = sizeof(init_ipc_ns.shm_ctlmax),
.mode = 0644, .mode = 0644,
.proc_handler = proc_ipc_doulongvec_minmax, .proc_handler = proc_ipc_doulongvec_minmax,
}, },
{ {
.procname = "shmall", .procname = "shmall",
.data = &init_ipc_ns.shm_ctlall, .data = &init_ipc_ns.shm_ctlall,
.maxlen = sizeof (init_ipc_ns.shm_ctlall), .maxlen = sizeof(init_ipc_ns.shm_ctlall),
.mode = 0644, .mode = 0644,
.proc_handler = proc_ipc_doulongvec_minmax, .proc_handler = proc_ipc_doulongvec_minmax,
}, },
{ {
.procname = "shmmni", .procname = "shmmni",
.data = &init_ipc_ns.shm_ctlmni, .data = &init_ipc_ns.shm_ctlmni,
.maxlen = sizeof (init_ipc_ns.shm_ctlmni), .maxlen = sizeof(init_ipc_ns.shm_ctlmni),
.mode = 0644, .mode = 0644,
.proc_handler = proc_ipc_dointvec, .proc_handler = proc_ipc_dointvec,
}, },
...@@ -194,7 +194,7 @@ static struct ctl_table ipc_kern_table[] = { ...@@ -194,7 +194,7 @@ static struct ctl_table ipc_kern_table[] = {
{ {
.procname = "msgmax", .procname = "msgmax",
.data = &init_ipc_ns.msg_ctlmax, .data = &init_ipc_ns.msg_ctlmax,
.maxlen = sizeof (init_ipc_ns.msg_ctlmax), .maxlen = sizeof(init_ipc_ns.msg_ctlmax),
.mode = 0644, .mode = 0644,
.proc_handler = proc_ipc_dointvec_minmax, .proc_handler = proc_ipc_dointvec_minmax,
.extra1 = &zero, .extra1 = &zero,
...@@ -203,7 +203,7 @@ static struct ctl_table ipc_kern_table[] = { ...@@ -203,7 +203,7 @@ static struct ctl_table ipc_kern_table[] = {
{ {
.procname = "msgmni", .procname = "msgmni",
.data = &init_ipc_ns.msg_ctlmni, .data = &init_ipc_ns.msg_ctlmni,
.maxlen = sizeof (init_ipc_ns.msg_ctlmni), .maxlen = sizeof(init_ipc_ns.msg_ctlmni),
.mode = 0644, .mode = 0644,
.proc_handler = proc_ipc_callback_dointvec_minmax, .proc_handler = proc_ipc_callback_dointvec_minmax,
.extra1 = &zero, .extra1 = &zero,
...@@ -212,7 +212,7 @@ static struct ctl_table ipc_kern_table[] = { ...@@ -212,7 +212,7 @@ static struct ctl_table ipc_kern_table[] = {
{ {
.procname = "msgmnb", .procname = "msgmnb",
.data = &init_ipc_ns.msg_ctlmnb, .data = &init_ipc_ns.msg_ctlmnb,
.maxlen = sizeof (init_ipc_ns.msg_ctlmnb), .maxlen = sizeof(init_ipc_ns.msg_ctlmnb),
.mode = 0644, .mode = 0644,
.proc_handler = proc_ipc_dointvec_minmax, .proc_handler = proc_ipc_dointvec_minmax,
.extra1 = &zero, .extra1 = &zero,
...@@ -221,7 +221,7 @@ static struct ctl_table ipc_kern_table[] = { ...@@ -221,7 +221,7 @@ static struct ctl_table ipc_kern_table[] = {
{ {
.procname = "sem", .procname = "sem",
.data = &init_ipc_ns.sem_ctls, .data = &init_ipc_ns.sem_ctls,
.maxlen = 4*sizeof (int), .maxlen = 4*sizeof(int),
.mode = 0644, .mode = 0644,
.proc_handler = proc_ipc_dointvec, .proc_handler = proc_ipc_dointvec,
}, },
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Spinlocks: Mohamed Abbas (abbas.mohamed@intel.com) * Spinlocks: Mohamed Abbas (abbas.mohamed@intel.com)
* Lockless receive & send, fd based notify: * Lockless receive & send, fd based notify:
* Manfred Spraul (manfred@colorfullife.com) * Manfred Spraul (manfred@colorfullife.com)
* *
* Audit: George Wilson (ltcgcw@us.ibm.com) * Audit: George Wilson (ltcgcw@us.ibm.com)
* *
...@@ -73,7 +73,7 @@ struct mqueue_inode_info { ...@@ -73,7 +73,7 @@ struct mqueue_inode_info {
struct mq_attr attr; struct mq_attr attr;
struct sigevent notify; struct sigevent notify;
struct pid* notify_owner; struct pid *notify_owner;
struct user_namespace *notify_user_ns; struct user_namespace *notify_user_ns;
struct user_struct *user; /* user who created, for accounting */ struct user_struct *user; /* user who created, for accounting */
struct sock *notify_sock; struct sock *notify_sock;
...@@ -92,7 +92,7 @@ static void remove_notification(struct mqueue_inode_info *info); ...@@ -92,7 +92,7 @@ static void remove_notification(struct mqueue_inode_info *info);
static struct kmem_cache *mqueue_inode_cachep; static struct kmem_cache *mqueue_inode_cachep;
static struct ctl_table_header * mq_sysctl_table; static struct ctl_table_header *mq_sysctl_table;
static inline struct mqueue_inode_info *MQUEUE_I(struct inode *inode) static inline struct mqueue_inode_info *MQUEUE_I(struct inode *inode)
{ {
...@@ -466,13 +466,13 @@ static int mqueue_create(struct inode *dir, struct dentry *dentry, ...@@ -466,13 +466,13 @@ static int mqueue_create(struct inode *dir, struct dentry *dentry,
static int mqueue_unlink(struct inode *dir, struct dentry *dentry) static int mqueue_unlink(struct inode *dir, struct dentry *dentry)
{ {
struct inode *inode = dentry->d_inode; struct inode *inode = dentry->d_inode;
dir->i_ctime = dir->i_mtime = dir->i_atime = CURRENT_TIME; dir->i_ctime = dir->i_mtime = dir->i_atime = CURRENT_TIME;
dir->i_size -= DIRENT_SIZE; dir->i_size -= DIRENT_SIZE;
drop_nlink(inode); drop_nlink(inode);
dput(dentry); dput(dentry);
return 0; return 0;
} }
/* /*
...@@ -622,7 +622,7 @@ static struct ext_wait_queue *wq_get_first_waiter( ...@@ -622,7 +622,7 @@ static struct ext_wait_queue *wq_get_first_waiter(
static inline void set_cookie(struct sk_buff *skb, char code) static inline void set_cookie(struct sk_buff *skb, char code)
{ {
((char*)skb->data)[NOTIFY_COOKIE_LEN-1] = code; ((char *)skb->data)[NOTIFY_COOKIE_LEN-1] = code;
} }
/* /*
...@@ -1303,11 +1303,11 @@ SYSCALL_DEFINE2(mq_notify, mqd_t, mqdes, ...@@ -1303,11 +1303,11 @@ SYSCALL_DEFINE2(mq_notify, mqd_t, mqdes,
out_fput: out_fput:
fdput(f); fdput(f);
out: out:
if (sock) { if (sock)
netlink_detachskb(sock, nc); netlink_detachskb(sock, nc);
} else if (nc) { else if (nc)
dev_kfree_skb(nc); dev_kfree_skb(nc);
}
return ret; return ret;
} }
......
...@@ -253,8 +253,14 @@ static void expunge_all(struct msg_queue *msq, int res) ...@@ -253,8 +253,14 @@ static void expunge_all(struct msg_queue *msq, int res)
struct msg_receiver *msr, *t; struct msg_receiver *msr, *t;
list_for_each_entry_safe(msr, t, &msq->q_receivers, r_list) { list_for_each_entry_safe(msr, t, &msq->q_receivers, r_list) {
msr->r_msg = NULL; msr->r_msg = NULL; /* initialize expunge ordering */
wake_up_process(msr->r_tsk); wake_up_process(msr->r_tsk);
/*
* Ensure that the wakeup is visible before setting r_msg as
* the receiving end depends on it: either spinning on a nil,
* or dealing with -EAGAIN cases. See lockless receive part 1
* and 2 in do_msgrcv().
*/
smp_mb(); smp_mb();
msr->r_msg = ERR_PTR(res); msr->r_msg = ERR_PTR(res);
} }
...@@ -318,7 +324,7 @@ SYSCALL_DEFINE2(msgget, key_t, key, int, msgflg) ...@@ -318,7 +324,7 @@ SYSCALL_DEFINE2(msgget, key_t, key, int, msgflg)
static inline unsigned long static inline unsigned long
copy_msqid_to_user(void __user *buf, struct msqid64_ds *in, int version) copy_msqid_to_user(void __user *buf, struct msqid64_ds *in, int version)
{ {
switch(version) { switch (version) {
case IPC_64: case IPC_64:
return copy_to_user(buf, in, sizeof(*in)); return copy_to_user(buf, in, sizeof(*in));
case IPC_OLD: case IPC_OLD:
...@@ -363,7 +369,7 @@ copy_msqid_to_user(void __user *buf, struct msqid64_ds *in, int version) ...@@ -363,7 +369,7 @@ copy_msqid_to_user(void __user *buf, struct msqid64_ds *in, int version)
static inline unsigned long static inline unsigned long
copy_msqid_from_user(struct msqid64_ds *out, void __user *buf, int version) copy_msqid_from_user(struct msqid64_ds *out, void __user *buf, int version)
{ {
switch(version) { switch (version) {
case IPC_64: case IPC_64:
if (copy_from_user(out, buf, sizeof(*out))) if (copy_from_user(out, buf, sizeof(*out)))
return -EFAULT; return -EFAULT;
...@@ -375,9 +381,9 @@ copy_msqid_from_user(struct msqid64_ds *out, void __user *buf, int version) ...@@ -375,9 +381,9 @@ copy_msqid_from_user(struct msqid64_ds *out, void __user *buf, int version)
if (copy_from_user(&tbuf_old, buf, sizeof(tbuf_old))) if (copy_from_user(&tbuf_old, buf, sizeof(tbuf_old)))
return -EFAULT; return -EFAULT;
out->msg_perm.uid = tbuf_old.msg_perm.uid; out->msg_perm.uid = tbuf_old.msg_perm.uid;
out->msg_perm.gid = tbuf_old.msg_perm.gid; out->msg_perm.gid = tbuf_old.msg_perm.gid;
out->msg_perm.mode = tbuf_old.msg_perm.mode; out->msg_perm.mode = tbuf_old.msg_perm.mode;
if (tbuf_old.msg_qbytes == 0) if (tbuf_old.msg_qbytes == 0)
out->msg_qbytes = tbuf_old.msg_lqbytes; out->msg_qbytes = tbuf_old.msg_lqbytes;
...@@ -606,13 +612,13 @@ SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf) ...@@ -606,13 +612,13 @@ SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf)
static int testmsg(struct msg_msg *msg, long type, int mode) static int testmsg(struct msg_msg *msg, long type, int mode)
{ {
switch(mode) switch (mode)
{ {
case SEARCH_ANY: case SEARCH_ANY:
case SEARCH_NUMBER: case SEARCH_NUMBER:
return 1; return 1;
case SEARCH_LESSEQUAL: case SEARCH_LESSEQUAL:
if (msg->m_type <=type) if (msg->m_type <= type)
return 1; return 1;
break; break;
case SEARCH_EQUAL: case SEARCH_EQUAL:
...@@ -638,15 +644,22 @@ static inline int pipelined_send(struct msg_queue *msq, struct msg_msg *msg) ...@@ -638,15 +644,22 @@ static inline int pipelined_send(struct msg_queue *msq, struct msg_msg *msg)
list_del(&msr->r_list); list_del(&msr->r_list);
if (msr->r_maxsize < msg->m_ts) { if (msr->r_maxsize < msg->m_ts) {
/* initialize pipelined send ordering */
msr->r_msg = NULL; msr->r_msg = NULL;
wake_up_process(msr->r_tsk); wake_up_process(msr->r_tsk);
smp_mb(); smp_mb(); /* see barrier comment below */
msr->r_msg = ERR_PTR(-E2BIG); msr->r_msg = ERR_PTR(-E2BIG);
} else { } else {
msr->r_msg = NULL; msr->r_msg = NULL;
msq->q_lrpid = task_pid_vnr(msr->r_tsk); msq->q_lrpid = task_pid_vnr(msr->r_tsk);
msq->q_rtime = get_seconds(); msq->q_rtime = get_seconds();
wake_up_process(msr->r_tsk); wake_up_process(msr->r_tsk);
/*
* Ensure that the wakeup is visible before
* setting r_msg, as the receiving end depends
* on it. See lockless receive part 1 and 2 in
* do_msgrcv().
*/
smp_mb(); smp_mb();
msr->r_msg = msg; msr->r_msg = msg;
...@@ -654,6 +667,7 @@ static inline int pipelined_send(struct msg_queue *msq, struct msg_msg *msg) ...@@ -654,6 +667,7 @@ static inline int pipelined_send(struct msg_queue *msq, struct msg_msg *msg)
} }
} }
} }
return 0; return 0;
} }
...@@ -696,7 +710,7 @@ long do_msgsnd(int msqid, long mtype, void __user *mtext, ...@@ -696,7 +710,7 @@ long do_msgsnd(int msqid, long mtype, void __user *mtext,
goto out_unlock0; goto out_unlock0;
/* raced with RMID? */ /* raced with RMID? */
if (msq->q_perm.deleted) { if (!ipc_valid_object(&msq->q_perm)) {
err = -EIDRM; err = -EIDRM;
goto out_unlock0; goto out_unlock0;
} }
...@@ -716,6 +730,7 @@ long do_msgsnd(int msqid, long mtype, void __user *mtext, ...@@ -716,6 +730,7 @@ long do_msgsnd(int msqid, long mtype, void __user *mtext,
goto out_unlock0; goto out_unlock0;
} }
/* enqueue the sender and prepare to block */
ss_add(msq, &s); ss_add(msq, &s);
if (!ipc_rcu_getref(msq)) { if (!ipc_rcu_getref(msq)) {
...@@ -731,7 +746,8 @@ long do_msgsnd(int msqid, long mtype, void __user *mtext, ...@@ -731,7 +746,8 @@ long do_msgsnd(int msqid, long mtype, void __user *mtext,
ipc_lock_object(&msq->q_perm); ipc_lock_object(&msq->q_perm);
ipc_rcu_putref(msq, ipc_rcu_free); ipc_rcu_putref(msq, ipc_rcu_free);
if (msq->q_perm.deleted) { /* raced with RMID? */
if (!ipc_valid_object(&msq->q_perm)) {
err = -EIDRM; err = -EIDRM;
goto out_unlock0; goto out_unlock0;
} }
...@@ -909,7 +925,7 @@ long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msgfl ...@@ -909,7 +925,7 @@ long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msgfl
ipc_lock_object(&msq->q_perm); ipc_lock_object(&msq->q_perm);
/* raced with RMID? */ /* raced with RMID? */
if (msq->q_perm.deleted) { if (!ipc_valid_object(&msq->q_perm)) {
msg = ERR_PTR(-EIDRM); msg = ERR_PTR(-EIDRM);
goto out_unlock0; goto out_unlock0;
} }
...@@ -983,7 +999,7 @@ long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msgfl ...@@ -983,7 +999,7 @@ long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msgfl
* wake_up_process(). There is a race with exit(), see * wake_up_process(). There is a race with exit(), see
* ipc/mqueue.c for the details. * ipc/mqueue.c for the details.
*/ */
msg = (struct msg_msg*)msr_d.r_msg; msg = (struct msg_msg *)msr_d.r_msg;
while (msg == NULL) { while (msg == NULL) {
cpu_relax(); cpu_relax();
msg = (struct msg_msg *)msr_d.r_msg; msg = (struct msg_msg *)msr_d.r_msg;
...@@ -1004,7 +1020,7 @@ long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msgfl ...@@ -1004,7 +1020,7 @@ long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msgfl
/* Lockless receive, part 4: /* Lockless receive, part 4:
* Repeat test after acquiring the spinlock. * Repeat test after acquiring the spinlock.
*/ */
msg = (struct msg_msg*)msr_d.r_msg; msg = (struct msg_msg *)msr_d.r_msg;
if (msg != ERR_PTR(-EAGAIN)) if (msg != ERR_PTR(-EAGAIN))
goto out_unlock0; goto out_unlock0;
......
This diff is collapsed.
...@@ -67,7 +67,7 @@ static const struct vm_operations_struct shm_vm_ops; ...@@ -67,7 +67,7 @@ static const struct vm_operations_struct shm_vm_ops;
static int newseg(struct ipc_namespace *, struct ipc_params *); static int newseg(struct ipc_namespace *, struct ipc_params *);
static void shm_open(struct vm_area_struct *vma); static void shm_open(struct vm_area_struct *vma);
static void shm_close(struct vm_area_struct *vma); static void shm_close(struct vm_area_struct *vma);
static void shm_destroy (struct ipc_namespace *ns, struct shmid_kernel *shp); static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp);
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
static int sysvipc_shm_proc_show(struct seq_file *s, void *it); static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
#endif #endif
...@@ -91,7 +91,7 @@ static void do_shm_rmid(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp) ...@@ -91,7 +91,7 @@ static void do_shm_rmid(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp)
struct shmid_kernel *shp; struct shmid_kernel *shp;
shp = container_of(ipcp, struct shmid_kernel, shm_perm); shp = container_of(ipcp, struct shmid_kernel, shm_perm);
if (shp->shm_nattch){ if (shp->shm_nattch) {
shp->shm_perm.mode |= SHM_DEST; shp->shm_perm.mode |= SHM_DEST;
/* Do not find it any more */ /* Do not find it any more */
shp->shm_perm.key = IPC_PRIVATE; shp->shm_perm.key = IPC_PRIVATE;
...@@ -116,7 +116,7 @@ static int __init ipc_ns_init(void) ...@@ -116,7 +116,7 @@ static int __init ipc_ns_init(void)
pure_initcall(ipc_ns_init); pure_initcall(ipc_ns_init);
void __init shm_init (void) void __init shm_init(void)
{ {
ipc_init_proc_interface("sysvipc/shm", ipc_init_proc_interface("sysvipc/shm",
#if BITS_PER_LONG <= 32 #if BITS_PER_LONG <= 32
...@@ -248,7 +248,7 @@ static bool shm_may_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp) ...@@ -248,7 +248,7 @@ static bool shm_may_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp)
*/ */
static void shm_close(struct vm_area_struct *vma) static void shm_close(struct vm_area_struct *vma)
{ {
struct file * file = vma->vm_file; struct file *file = vma->vm_file;
struct shm_file_data *sfd = shm_file_data(file); struct shm_file_data *sfd = shm_file_data(file);
struct shmid_kernel *shp; struct shmid_kernel *shp;
struct ipc_namespace *ns = sfd->ns; struct ipc_namespace *ns = sfd->ns;
...@@ -379,7 +379,7 @@ static struct mempolicy *shm_get_policy(struct vm_area_struct *vma, ...@@ -379,7 +379,7 @@ static struct mempolicy *shm_get_policy(struct vm_area_struct *vma,
} }
#endif #endif
static int shm_mmap(struct file * file, struct vm_area_struct * vma) static int shm_mmap(struct file *file, struct vm_area_struct *vma)
{ {
struct shm_file_data *sfd = shm_file_data(file); struct shm_file_data *sfd = shm_file_data(file);
int ret; int ret;
...@@ -477,7 +477,6 @@ static const struct vm_operations_struct shm_vm_ops = { ...@@ -477,7 +477,6 @@ static const struct vm_operations_struct shm_vm_ops = {
* *
* Called with shm_ids.rwsem held as a writer. * Called with shm_ids.rwsem held as a writer.
*/ */
static int newseg(struct ipc_namespace *ns, struct ipc_params *params) static int newseg(struct ipc_namespace *ns, struct ipc_params *params)
{ {
key_t key = params->key; key_t key = params->key;
...@@ -486,7 +485,7 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params) ...@@ -486,7 +485,7 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params)
int error; int error;
struct shmid_kernel *shp; struct shmid_kernel *shp;
size_t numpages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; size_t numpages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
struct file * file; struct file *file;
char name[13]; char name[13];
int id; int id;
vm_flags_t acctflag = 0; vm_flags_t acctflag = 0;
...@@ -512,7 +511,7 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params) ...@@ -512,7 +511,7 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params)
return error; return error;
} }
sprintf (name, "SYSV%08x", key); sprintf(name, "SYSV%08x", key);
if (shmflg & SHM_HUGETLB) { if (shmflg & SHM_HUGETLB) {
struct hstate *hs; struct hstate *hs;
size_t hugesize; size_t hugesize;
...@@ -533,7 +532,7 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params) ...@@ -533,7 +532,7 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params)
} else { } else {
/* /*
* Do not allow no accounting for OVERCOMMIT_NEVER, even * Do not allow no accounting for OVERCOMMIT_NEVER, even
* if it's asked for. * if it's asked for.
*/ */
if ((shmflg & SHM_NORESERVE) && if ((shmflg & SHM_NORESERVE) &&
sysctl_overcommit_memory != OVERCOMMIT_NEVER) sysctl_overcommit_memory != OVERCOMMIT_NEVER)
...@@ -628,7 +627,7 @@ SYSCALL_DEFINE3(shmget, key_t, key, size_t, size, int, shmflg) ...@@ -628,7 +627,7 @@ SYSCALL_DEFINE3(shmget, key_t, key, size_t, size, int, shmflg)
static inline unsigned long copy_shmid_to_user(void __user *buf, struct shmid64_ds *in, int version) static inline unsigned long copy_shmid_to_user(void __user *buf, struct shmid64_ds *in, int version)
{ {
switch(version) { switch (version) {
case IPC_64: case IPC_64:
return copy_to_user(buf, in, sizeof(*in)); return copy_to_user(buf, in, sizeof(*in));
case IPC_OLD: case IPC_OLD:
...@@ -655,7 +654,7 @@ static inline unsigned long copy_shmid_to_user(void __user *buf, struct shmid64_ ...@@ -655,7 +654,7 @@ static inline unsigned long copy_shmid_to_user(void __user *buf, struct shmid64_
static inline unsigned long static inline unsigned long
copy_shmid_from_user(struct shmid64_ds *out, void __user *buf, int version) copy_shmid_from_user(struct shmid64_ds *out, void __user *buf, int version)
{ {
switch(version) { switch (version) {
case IPC_64: case IPC_64:
if (copy_from_user(out, buf, sizeof(*out))) if (copy_from_user(out, buf, sizeof(*out)))
return -EFAULT; return -EFAULT;
...@@ -680,14 +679,14 @@ copy_shmid_from_user(struct shmid64_ds *out, void __user *buf, int version) ...@@ -680,14 +679,14 @@ copy_shmid_from_user(struct shmid64_ds *out, void __user *buf, int version)
static inline unsigned long copy_shminfo_to_user(void __user *buf, struct shminfo64 *in, int version) static inline unsigned long copy_shminfo_to_user(void __user *buf, struct shminfo64 *in, int version)
{ {
switch(version) { switch (version) {
case IPC_64: case IPC_64:
return copy_to_user(buf, in, sizeof(*in)); return copy_to_user(buf, in, sizeof(*in));
case IPC_OLD: case IPC_OLD:
{ {
struct shminfo out; struct shminfo out;
if(in->shmmax > INT_MAX) if (in->shmmax > INT_MAX)
out.shmmax = INT_MAX; out.shmmax = INT_MAX;
else else
out.shmmax = (int)in->shmmax; out.shmmax = (int)in->shmmax;
...@@ -846,14 +845,14 @@ static int shmctl_nolock(struct ipc_namespace *ns, int shmid, ...@@ -846,14 +845,14 @@ static int shmctl_nolock(struct ipc_namespace *ns, int shmid,
shminfo.shmall = ns->shm_ctlall; shminfo.shmall = ns->shm_ctlall;
shminfo.shmmin = SHMMIN; shminfo.shmmin = SHMMIN;
if(copy_shminfo_to_user (buf, &shminfo, version)) if (copy_shminfo_to_user(buf, &shminfo, version))
return -EFAULT; return -EFAULT;
down_read(&shm_ids(ns).rwsem); down_read(&shm_ids(ns).rwsem);
err = ipc_get_maxid(&shm_ids(ns)); err = ipc_get_maxid(&shm_ids(ns));
up_read(&shm_ids(ns).rwsem); up_read(&shm_ids(ns).rwsem);
if(err<0) if (err < 0)
err = 0; err = 0;
goto out; goto out;
} }
...@@ -864,7 +863,7 @@ static int shmctl_nolock(struct ipc_namespace *ns, int shmid, ...@@ -864,7 +863,7 @@ static int shmctl_nolock(struct ipc_namespace *ns, int shmid,
memset(&shm_info, 0, sizeof(shm_info)); memset(&shm_info, 0, sizeof(shm_info));
down_read(&shm_ids(ns).rwsem); down_read(&shm_ids(ns).rwsem);
shm_info.used_ids = shm_ids(ns).in_use; shm_info.used_ids = shm_ids(ns).in_use;
shm_get_stat (ns, &shm_info.shm_rss, &shm_info.shm_swp); shm_get_stat(ns, &shm_info.shm_rss, &shm_info.shm_swp);
shm_info.shm_tot = ns->shm_tot; shm_info.shm_tot = ns->shm_tot;
shm_info.swap_attempts = 0; shm_info.swap_attempts = 0;
shm_info.swap_successes = 0; shm_info.swap_successes = 0;
...@@ -975,6 +974,13 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf) ...@@ -975,6 +974,13 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
goto out_unlock1; goto out_unlock1;
ipc_lock_object(&shp->shm_perm); ipc_lock_object(&shp->shm_perm);
/* check if shm_destroy() is tearing down shp */
if (!ipc_valid_object(&shp->shm_perm)) {
err = -EIDRM;
goto out_unlock0;
}
if (!ns_capable(ns->user_ns, CAP_IPC_LOCK)) { if (!ns_capable(ns->user_ns, CAP_IPC_LOCK)) {
kuid_t euid = current_euid(); kuid_t euid = current_euid();
if (!uid_eq(euid, shp->shm_perm.uid) && if (!uid_eq(euid, shp->shm_perm.uid) &&
...@@ -989,13 +995,6 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf) ...@@ -989,13 +995,6 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
} }
shm_file = shp->shm_file; shm_file = shp->shm_file;
/* check if shm_destroy() is tearing down shp */
if (shm_file == NULL) {
err = -EIDRM;
goto out_unlock0;
}
if (is_file_hugepages(shm_file)) if (is_file_hugepages(shm_file))
goto out_unlock0; goto out_unlock0;
...@@ -1047,7 +1046,7 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr, ...@@ -1047,7 +1046,7 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr,
struct shmid_kernel *shp; struct shmid_kernel *shp;
unsigned long addr; unsigned long addr;
unsigned long size; unsigned long size;
struct file * file; struct file *file;
int err; int err;
unsigned long flags; unsigned long flags;
unsigned long prot; unsigned long prot;
...@@ -1116,7 +1115,7 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr, ...@@ -1116,7 +1115,7 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr,
ipc_lock_object(&shp->shm_perm); ipc_lock_object(&shp->shm_perm);
/* check if shm_destroy() is tearing down shp */ /* check if shm_destroy() is tearing down shp */
if (shp->shm_file == NULL) { if (!ipc_valid_object(&shp->shm_perm)) {
ipc_unlock_object(&shp->shm_perm); ipc_unlock_object(&shp->shm_perm);
err = -EIDRM; err = -EIDRM;
goto out_unlock; goto out_unlock;
......
This diff is collapsed.
...@@ -15,9 +15,9 @@ ...@@ -15,9 +15,9 @@
#define SEQ_MULTIPLIER (IPCMNI) #define SEQ_MULTIPLIER (IPCMNI)
void sem_init (void); void sem_init(void);
void msg_init (void); void msg_init(void);
void shm_init (void); void shm_init(void);
struct ipc_namespace; struct ipc_namespace;
...@@ -100,6 +100,7 @@ void __init ipc_init_proc_interface(const char *path, const char *header, ...@@ -100,6 +100,7 @@ void __init ipc_init_proc_interface(const char *path, const char *header,
#define ipcid_to_idx(id) ((id) % SEQ_MULTIPLIER) #define ipcid_to_idx(id) ((id) % SEQ_MULTIPLIER)
#define ipcid_to_seqx(id) ((id) / SEQ_MULTIPLIER) #define ipcid_to_seqx(id) ((id) / SEQ_MULTIPLIER)
#define IPCID_SEQ_MAX min_t(int, INT_MAX/SEQ_MULTIPLIER, USHRT_MAX)
/* must be called with ids->rwsem acquired for writing */ /* must be called with ids->rwsem acquired for writing */
int ipc_addid(struct ipc_ids *, struct kern_ipc_perm *, int); int ipc_addid(struct ipc_ids *, struct kern_ipc_perm *, int);
...@@ -116,8 +117,8 @@ int ipcperms(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp, short flg); ...@@ -116,8 +117,8 @@ int ipcperms(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp, short flg);
/* for rare, potentially huge allocations. /* for rare, potentially huge allocations.
* both function can sleep * both function can sleep
*/ */
void* ipc_alloc(int size); void *ipc_alloc(int size);
void ipc_free(void* ptr, int size); void ipc_free(void *ptr, int size);
/* /*
* For allocation that need to be freed by RCU. * For allocation that need to be freed by RCU.
...@@ -125,7 +126,7 @@ void ipc_free(void* ptr, int size); ...@@ -125,7 +126,7 @@ void ipc_free(void* ptr, int size);
* getref increases the refcount, the putref call that reduces the recount * getref increases the refcount, the putref call that reduces the recount
* to 0 schedules the rcu destruction. Caller must guarantee locking. * to 0 schedules the rcu destruction. Caller must guarantee locking.
*/ */
void* ipc_rcu_alloc(int size); void *ipc_rcu_alloc(int size);
int ipc_rcu_getref(void *ptr); int ipc_rcu_getref(void *ptr);
void ipc_rcu_putref(void *ptr, void (*func)(struct rcu_head *head)); void ipc_rcu_putref(void *ptr, void (*func)(struct rcu_head *head));
void ipc_rcu_free(struct rcu_head *head); void ipc_rcu_free(struct rcu_head *head);
...@@ -144,7 +145,7 @@ struct kern_ipc_perm *ipcctl_pre_down_nolock(struct ipc_namespace *ns, ...@@ -144,7 +145,7 @@ struct kern_ipc_perm *ipcctl_pre_down_nolock(struct ipc_namespace *ns,
/* On IA-64, we always use the "64-bit version" of the IPC structures. */ /* On IA-64, we always use the "64-bit version" of the IPC structures. */
# define ipc_parse_version(cmd) IPC_64 # define ipc_parse_version(cmd) IPC_64
#else #else
int ipc_parse_version (int *cmd); int ipc_parse_version(int *cmd);
#endif #endif
extern void free_msg(struct msg_msg *msg); extern void free_msg(struct msg_msg *msg);
...@@ -185,6 +186,19 @@ static inline void ipc_unlock(struct kern_ipc_perm *perm) ...@@ -185,6 +186,19 @@ static inline void ipc_unlock(struct kern_ipc_perm *perm)
rcu_read_unlock(); rcu_read_unlock();
} }
/*
* ipc_valid_object() - helper to sort out IPC_RMID races for codepaths
* where the respective ipc_ids.rwsem is not being held down.
* Checks whether the ipc object is still around or if it's gone already, as
* ipc_rmid() may have already freed the ID while the ipc lock was spinning.
* Needs to be called with kern_ipc_perm.lock held -- exception made for one
* checkpoint case at sys_semtimedop() as noted in code commentary.
*/
static inline bool ipc_valid_object(struct kern_ipc_perm *perm)
{
return !perm->deleted;
}
struct kern_ipc_perm *ipc_obtain_object_check(struct ipc_ids *ids, int id); struct kern_ipc_perm *ipc_obtain_object_check(struct ipc_ids *ids, int id);
int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids, int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids,
struct ipc_ops *ops, struct ipc_params *params); struct ipc_ops *ops, struct ipc_params *params);
......
...@@ -1537,7 +1537,7 @@ void vmcoreinfo_append_str(const char *fmt, ...) ...@@ -1537,7 +1537,7 @@ void vmcoreinfo_append_str(const char *fmt, ...)
size_t r; size_t r;
va_start(args, fmt); va_start(args, fmt);
r = vsnprintf(buf, sizeof(buf), fmt, args); r = vscnprintf(buf, sizeof(buf), fmt, args);
va_end(args); va_end(args);
r = min(r, vmcoreinfo_max_size - vmcoreinfo_size); r = min(r, vmcoreinfo_max_size - vmcoreinfo_size);
......
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
* Rewritten. Old one was good in 2.2, but in 2.3 it was immoral. --ANK (990903) * Rewritten. Old one was good in 2.2, but in 2.3 it was immoral. --ANK (990903)
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/export.h> #include <linux/export.h>
#include <linux/kernel_stat.h> #include <linux/kernel_stat.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
...@@ -54,7 +56,7 @@ static struct softirq_action softirq_vec[NR_SOFTIRQS] __cacheline_aligned_in_smp ...@@ -54,7 +56,7 @@ static struct softirq_action softirq_vec[NR_SOFTIRQS] __cacheline_aligned_in_smp
DEFINE_PER_CPU(struct task_struct *, ksoftirqd); DEFINE_PER_CPU(struct task_struct *, ksoftirqd);
char *softirq_to_name[NR_SOFTIRQS] = { const char * const softirq_to_name[NR_SOFTIRQS] = {
"HI", "TIMER", "NET_TX", "NET_RX", "BLOCK", "BLOCK_IOPOLL", "HI", "TIMER", "NET_TX", "NET_RX", "BLOCK", "BLOCK_IOPOLL",
"TASKLET", "SCHED", "HRTIMER", "RCU" "TASKLET", "SCHED", "HRTIMER", "RCU"
}; };
...@@ -136,7 +138,6 @@ void _local_bh_enable(void) ...@@ -136,7 +138,6 @@ void _local_bh_enable(void)
WARN_ON_ONCE(in_irq()); WARN_ON_ONCE(in_irq());
__local_bh_enable(SOFTIRQ_DISABLE_OFFSET); __local_bh_enable(SOFTIRQ_DISABLE_OFFSET);
} }
EXPORT_SYMBOL(_local_bh_enable); EXPORT_SYMBOL(_local_bh_enable);
void __local_bh_enable_ip(unsigned long ip, unsigned int cnt) void __local_bh_enable_ip(unsigned long ip, unsigned int cnt)
...@@ -153,7 +154,7 @@ void __local_bh_enable_ip(unsigned long ip, unsigned int cnt) ...@@ -153,7 +154,7 @@ void __local_bh_enable_ip(unsigned long ip, unsigned int cnt)
/* /*
* Keep preemption disabled until we are done with * Keep preemption disabled until we are done with
* softirq processing: * softirq processing:
*/ */
preempt_count_sub(cnt - 1); preempt_count_sub(cnt - 1);
if (unlikely(!in_interrupt() && local_softirq_pending())) { if (unlikely(!in_interrupt() && local_softirq_pending())) {
...@@ -229,6 +230,7 @@ asmlinkage void __do_softirq(void) ...@@ -229,6 +230,7 @@ asmlinkage void __do_softirq(void)
struct softirq_action *h; struct softirq_action *h;
bool in_hardirq; bool in_hardirq;
__u32 pending; __u32 pending;
int softirq_bit;
int cpu; int cpu;
/* /*
...@@ -253,30 +255,30 @@ asmlinkage void __do_softirq(void) ...@@ -253,30 +255,30 @@ asmlinkage void __do_softirq(void)
h = softirq_vec; h = softirq_vec;
do { while ((softirq_bit = ffs(pending))) {
if (pending & 1) { unsigned int vec_nr;
unsigned int vec_nr = h - softirq_vec; int prev_count;
int prev_count = preempt_count();
kstat_incr_softirqs_this_cpu(vec_nr);
trace_softirq_entry(vec_nr);
h->action(h);
trace_softirq_exit(vec_nr);
if (unlikely(prev_count != preempt_count())) {
printk(KERN_ERR "huh, entered softirq %u %s %p"
"with preempt_count %08x,"
" exited with %08x?\n", vec_nr,
softirq_to_name[vec_nr], h->action,
prev_count, preempt_count());
preempt_count_set(prev_count);
}
rcu_bh_qs(cpu); h += softirq_bit - 1;
vec_nr = h - softirq_vec;
prev_count = preempt_count();
kstat_incr_softirqs_this_cpu(vec_nr);
trace_softirq_entry(vec_nr);
h->action(h);
trace_softirq_exit(vec_nr);
if (unlikely(prev_count != preempt_count())) {
pr_err("huh, entered softirq %u %s %p with preempt_count %08x, exited with %08x?\n",
vec_nr, softirq_to_name[vec_nr], h->action,
prev_count, preempt_count());
preempt_count_set(prev_count);
} }
rcu_bh_qs(cpu);
h++; h++;
pending >>= 1; pending >>= softirq_bit;
} while (pending); }
local_irq_disable(); local_irq_disable();
...@@ -433,8 +435,7 @@ void open_softirq(int nr, void (*action)(struct softirq_action *)) ...@@ -433,8 +435,7 @@ void open_softirq(int nr, void (*action)(struct softirq_action *))
/* /*
* Tasklets * Tasklets
*/ */
struct tasklet_head struct tasklet_head {
{
struct tasklet_struct *head; struct tasklet_struct *head;
struct tasklet_struct **tail; struct tasklet_struct **tail;
}; };
...@@ -453,7 +454,6 @@ void __tasklet_schedule(struct tasklet_struct *t) ...@@ -453,7 +454,6 @@ void __tasklet_schedule(struct tasklet_struct *t)
raise_softirq_irqoff(TASKLET_SOFTIRQ); raise_softirq_irqoff(TASKLET_SOFTIRQ);
local_irq_restore(flags); local_irq_restore(flags);
} }
EXPORT_SYMBOL(__tasklet_schedule); EXPORT_SYMBOL(__tasklet_schedule);
void __tasklet_hi_schedule(struct tasklet_struct *t) void __tasklet_hi_schedule(struct tasklet_struct *t)
...@@ -467,7 +467,6 @@ void __tasklet_hi_schedule(struct tasklet_struct *t) ...@@ -467,7 +467,6 @@ void __tasklet_hi_schedule(struct tasklet_struct *t)
raise_softirq_irqoff(HI_SOFTIRQ); raise_softirq_irqoff(HI_SOFTIRQ);
local_irq_restore(flags); local_irq_restore(flags);
} }
EXPORT_SYMBOL(__tasklet_hi_schedule); EXPORT_SYMBOL(__tasklet_hi_schedule);
void __tasklet_hi_schedule_first(struct tasklet_struct *t) void __tasklet_hi_schedule_first(struct tasklet_struct *t)
...@@ -478,7 +477,6 @@ void __tasklet_hi_schedule_first(struct tasklet_struct *t) ...@@ -478,7 +477,6 @@ void __tasklet_hi_schedule_first(struct tasklet_struct *t)
__this_cpu_write(tasklet_hi_vec.head, t); __this_cpu_write(tasklet_hi_vec.head, t);
__raise_softirq_irqoff(HI_SOFTIRQ); __raise_softirq_irqoff(HI_SOFTIRQ);
} }
EXPORT_SYMBOL(__tasklet_hi_schedule_first); EXPORT_SYMBOL(__tasklet_hi_schedule_first);
static void tasklet_action(struct softirq_action *a) static void tasklet_action(struct softirq_action *a)
...@@ -498,7 +496,8 @@ static void tasklet_action(struct softirq_action *a) ...@@ -498,7 +496,8 @@ static void tasklet_action(struct softirq_action *a)
if (tasklet_trylock(t)) { if (tasklet_trylock(t)) {
if (!atomic_read(&t->count)) { if (!atomic_read(&t->count)) {
if (!test_and_clear_bit(TASKLET_STATE_SCHED, &t->state)) if (!test_and_clear_bit(TASKLET_STATE_SCHED,
&t->state))
BUG(); BUG();
t->func(t->data); t->func(t->data);
tasklet_unlock(t); tasklet_unlock(t);
...@@ -533,7 +532,8 @@ static void tasklet_hi_action(struct softirq_action *a) ...@@ -533,7 +532,8 @@ static void tasklet_hi_action(struct softirq_action *a)
if (tasklet_trylock(t)) { if (tasklet_trylock(t)) {
if (!atomic_read(&t->count)) { if (!atomic_read(&t->count)) {
if (!test_and_clear_bit(TASKLET_STATE_SCHED, &t->state)) if (!test_and_clear_bit(TASKLET_STATE_SCHED,
&t->state))
BUG(); BUG();
t->func(t->data); t->func(t->data);
tasklet_unlock(t); tasklet_unlock(t);
...@@ -551,7 +551,6 @@ static void tasklet_hi_action(struct softirq_action *a) ...@@ -551,7 +551,6 @@ static void tasklet_hi_action(struct softirq_action *a)
} }
} }
void tasklet_init(struct tasklet_struct *t, void tasklet_init(struct tasklet_struct *t,
void (*func)(unsigned long), unsigned long data) void (*func)(unsigned long), unsigned long data)
{ {
...@@ -561,13 +560,12 @@ void tasklet_init(struct tasklet_struct *t, ...@@ -561,13 +560,12 @@ void tasklet_init(struct tasklet_struct *t,
t->func = func; t->func = func;
t->data = data; t->data = data;
} }
EXPORT_SYMBOL(tasklet_init); EXPORT_SYMBOL(tasklet_init);
void tasklet_kill(struct tasklet_struct *t) void tasklet_kill(struct tasklet_struct *t)
{ {
if (in_interrupt()) if (in_interrupt())
printk("Attempt to kill tasklet from interrupt\n"); pr_notice("Attempt to kill tasklet from interrupt\n");
while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) { while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) {
do { do {
...@@ -577,7 +575,6 @@ void tasklet_kill(struct tasklet_struct *t) ...@@ -577,7 +575,6 @@ void tasklet_kill(struct tasklet_struct *t)
tasklet_unlock_wait(t); tasklet_unlock_wait(t);
clear_bit(TASKLET_STATE_SCHED, &t->state); clear_bit(TASKLET_STATE_SCHED, &t->state);
} }
EXPORT_SYMBOL(tasklet_kill); EXPORT_SYMBOL(tasklet_kill);
/* /*
...@@ -727,9 +724,8 @@ static void takeover_tasklets(unsigned int cpu) ...@@ -727,9 +724,8 @@ static void takeover_tasklets(unsigned int cpu)
} }
#endif /* CONFIG_HOTPLUG_CPU */ #endif /* CONFIG_HOTPLUG_CPU */
static int cpu_callback(struct notifier_block *nfb, static int cpu_callback(struct notifier_block *nfb, unsigned long action,
unsigned long action, void *hcpu)
void *hcpu)
{ {
switch (action) { switch (action) {
#ifdef CONFIG_HOTPLUG_CPU #ifdef CONFIG_HOTPLUG_CPU
......
...@@ -268,14 +268,12 @@ static int ddebug_tokenize(char *buf, char *words[], int maxwords) ...@@ -268,14 +268,12 @@ static int ddebug_tokenize(char *buf, char *words[], int maxwords)
*/ */
static inline int parse_lineno(const char *str, unsigned int *val) static inline int parse_lineno(const char *str, unsigned int *val)
{ {
char *end = NULL;
BUG_ON(str == NULL); BUG_ON(str == NULL);
if (*str == '\0') { if (*str == '\0') {
*val = 0; *val = 0;
return 0; return 0;
} }
*val = simple_strtoul(str, &end, 10); if (kstrtouint(str, 10, val) < 0) {
if (end == NULL || end == str || *end != '\0') {
pr_err("bad line-number: %s\n", str); pr_err("bad line-number: %s\n", str);
return -EINVAL; return -EINVAL;
} }
...@@ -348,14 +346,14 @@ static int ddebug_parse_query(char *words[], int nwords, ...@@ -348,14 +346,14 @@ static int ddebug_parse_query(char *words[], int nwords,
} }
if (last) if (last)
*last++ = '\0'; *last++ = '\0';
if (parse_lineno(first, &query->first_lineno) < 0) { if (parse_lineno(first, &query->first_lineno) < 0)
pr_err("line-number is <0\n");
return -EINVAL; return -EINVAL;
}
if (last) { if (last) {
/* range <first>-<last> */ /* range <first>-<last> */
if (parse_lineno(last, &query->last_lineno) if (parse_lineno(last, &query->last_lineno) < 0)
< query->first_lineno) { return -EINVAL;
if (query->last_lineno < query->first_lineno) {
pr_err("last-line:%d < 1st-line:%d\n", pr_err("last-line:%d < 1st-line:%d\n",
query->last_lineno, query->last_lineno,
query->first_lineno); query->first_lineno);
......
...@@ -172,7 +172,7 @@ int __init swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose) ...@@ -172,7 +172,7 @@ int __init swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose)
/* /*
* Get the overflow emergency buffer * Get the overflow emergency buffer
*/ */
v_overflow_buffer = memblock_virt_alloc_nopanic( v_overflow_buffer = memblock_virt_alloc_low_nopanic(
PAGE_ALIGN(io_tlb_overflow), PAGE_ALIGN(io_tlb_overflow),
PAGE_SIZE); PAGE_SIZE);
if (!v_overflow_buffer) if (!v_overflow_buffer)
...@@ -220,7 +220,7 @@ swiotlb_init(int verbose) ...@@ -220,7 +220,7 @@ swiotlb_init(int verbose)
bytes = io_tlb_nslabs << IO_TLB_SHIFT; bytes = io_tlb_nslabs << IO_TLB_SHIFT;
/* Get IO TLB memory from the low pages */ /* Get IO TLB memory from the low pages */
vstart = memblock_virt_alloc_nopanic(PAGE_ALIGN(bytes), PAGE_SIZE); vstart = memblock_virt_alloc_low_nopanic(PAGE_ALIGN(bytes), PAGE_SIZE);
if (vstart && !swiotlb_init_with_tbl(vstart, io_tlb_nslabs, verbose)) if (vstart && !swiotlb_init_with_tbl(vstart, io_tlb_nslabs, verbose))
return; return;
......
...@@ -984,9 +984,6 @@ static phys_addr_t __init memblock_alloc_base_nid(phys_addr_t size, ...@@ -984,9 +984,6 @@ static phys_addr_t __init memblock_alloc_base_nid(phys_addr_t size,
if (!align) if (!align)
align = SMP_CACHE_BYTES; align = SMP_CACHE_BYTES;
/* align @size to avoid excessive fragmentation on reserved array */
size = round_up(size, align);
found = memblock_find_in_range_node(size, align, 0, max_addr, nid); found = memblock_find_in_range_node(size, align, 0, max_addr, nid);
if (found && !memblock_reserve(found, size)) if (found && !memblock_reserve(found, size))
return found; return found;
...@@ -1080,9 +1077,6 @@ static void * __init memblock_virt_alloc_internal( ...@@ -1080,9 +1077,6 @@ static void * __init memblock_virt_alloc_internal(
if (!align) if (!align)
align = SMP_CACHE_BYTES; align = SMP_CACHE_BYTES;
/* align @size to avoid excessive fragmentation on reserved array */
size = round_up(size, align);
again: again:
alloc = memblock_find_in_range_node(size, align, min_addr, max_addr, alloc = memblock_find_in_range_node(size, align, min_addr, max_addr,
nid); nid);
......
...@@ -1548,8 +1548,6 @@ static struct page *alloc_misplaced_dst_page(struct page *page, ...@@ -1548,8 +1548,6 @@ static struct page *alloc_misplaced_dst_page(struct page *page,
__GFP_NOMEMALLOC | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NORETRY |
__GFP_NOWARN) & __GFP_NOWARN) &
~GFP_IOFS, 0); ~GFP_IOFS, 0);
if (newpage)
page_cpupid_xchg_last(newpage, page_cpupid_last(page));
return newpage; return newpage;
} }
......
...@@ -202,4 +202,4 @@ static int __init mm_sysfs_init(void) ...@@ -202,4 +202,4 @@ static int __init mm_sysfs_init(void)
return 0; return 0;
} }
pure_initcall(mm_sysfs_init); postcore_initcall(mm_sysfs_init);
...@@ -220,12 +220,12 @@ int is_vmalloc_or_module_addr(const void *x) ...@@ -220,12 +220,12 @@ int is_vmalloc_or_module_addr(const void *x)
} }
/* /*
* Walk a vmap address to the physical pfn it maps to. * Walk a vmap address to the struct page it maps.
*/ */
unsigned long vmalloc_to_pfn(const void *vmalloc_addr) struct page *vmalloc_to_page(const void *vmalloc_addr)
{ {
unsigned long addr = (unsigned long) vmalloc_addr; unsigned long addr = (unsigned long) vmalloc_addr;
unsigned long pfn = 0; struct page *page = NULL;
pgd_t *pgd = pgd_offset_k(addr); pgd_t *pgd = pgd_offset_k(addr);
/* /*
...@@ -244,23 +244,23 @@ unsigned long vmalloc_to_pfn(const void *vmalloc_addr) ...@@ -244,23 +244,23 @@ unsigned long vmalloc_to_pfn(const void *vmalloc_addr)
ptep = pte_offset_map(pmd, addr); ptep = pte_offset_map(pmd, addr);
pte = *ptep; pte = *ptep;
if (pte_present(pte)) if (pte_present(pte))
pfn = pte_pfn(pte); page = pte_page(pte);
pte_unmap(ptep); pte_unmap(ptep);
} }
} }
} }
return pfn; return page;
} }
EXPORT_SYMBOL(vmalloc_to_pfn); EXPORT_SYMBOL(vmalloc_to_page);
/* /*
* Map a vmalloc()-space virtual address to the struct page. * Map a vmalloc()-space virtual address to the physical page frame number.
*/ */
struct page *vmalloc_to_page(const void *vmalloc_addr) unsigned long vmalloc_to_pfn(const void *vmalloc_addr)
{ {
return pfn_to_page(vmalloc_to_pfn(vmalloc_addr)); return page_to_pfn(vmalloc_to_page(vmalloc_addr));
} }
EXPORT_SYMBOL(vmalloc_to_page); EXPORT_SYMBOL(vmalloc_to_pfn);
/*** Global kva allocator ***/ /*** Global kva allocator ***/
......
...@@ -2665,6 +2665,15 @@ sub process { ...@@ -2665,6 +2665,15 @@ sub process {
$herecurr); $herecurr);
} }
# check for function declarations without arguments like "int foo()"
if ($line =~ /(\b$Type\s+$Ident)\s*\(\s*\)/) {
if (ERROR("FUNCTION_WITHOUT_ARGS",
"Bad function definition - $1() should probably be $1(void)\n" . $herecurr) &&
$fix) {
$fixed[$linenr - 1] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/;
}
}
# check for uses of DEFINE_PCI_DEVICE_TABLE # check for uses of DEFINE_PCI_DEVICE_TABLE
if ($line =~ /\bDEFINE_PCI_DEVICE_TABLE\s*\(\s*(\w+)\s*\)\s*=/) { if ($line =~ /\bDEFINE_PCI_DEVICE_TABLE\s*\(\s*(\w+)\s*\)\s*=/) {
if (WARN("DEFINE_PCI_DEVICE_TABLE", if (WARN("DEFINE_PCI_DEVICE_TABLE",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment