diff options
-rw-r--r-- | Documentation/DocBook/Makefile | 2 | ||||
-rw-r--r-- | Documentation/DocBook/uio-howto.tmpl | 90 | ||||
-rw-r--r-- | drivers/base/core.c | 4 | ||||
-rw-r--r-- | drivers/base/power/Makefile | 3 | ||||
-rw-r--r-- | drivers/base/power/main.c | 8 | ||||
-rw-r--r-- | drivers/base/power/power.h | 28 | ||||
-rw-r--r-- | drivers/char/Kconfig | 2 | ||||
-rw-r--r-- | fs/exec.c | 6 | ||||
-rw-r--r-- | fs/sysfs/file.c | 6 | ||||
-rw-r--r-- | include/linux/sched.h | 4 | ||||
-rw-r--r-- | kernel/sched.c | 5 | ||||
-rw-r--r-- | kernel/sched_debug.c | 8 | ||||
-rw-r--r-- | kernel/sched_stats.h | 3 | ||||
-rw-r--r-- | kernel/time/tick-sched.c | 2 | ||||
-rw-r--r-- | lib/kobject.c | 4 | ||||
-rw-r--r-- | mm/page_alloc.c | 1 | ||||
-rw-r--r-- | mm/shmem.c | 5 |
17 files changed, 91 insertions, 90 deletions
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile index 054a7ecf64c..4953bc25872 100644 --- a/Documentation/DocBook/Makefile +++ b/Documentation/DocBook/Makefile @@ -11,7 +11,7 @@ DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.xml \ procfs-guide.xml writing_usb_driver.xml \ kernel-api.xml filesystems.xml lsm.xml usb.xml \ gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \ - genericirq.xml s390-drivers.xml + genericirq.xml s390-drivers.xml uio-howto.xml ### # The build process is as follows (targets): diff --git a/Documentation/DocBook/uio-howto.tmpl b/Documentation/DocBook/uio-howto.tmpl index c119484258b..fdd7f4f887b 100644 --- a/Documentation/DocBook/uio-howto.tmpl +++ b/Documentation/DocBook/uio-howto.tmpl @@ -30,6 +30,12 @@ <revhistory> <revision> + <revnumber>0.4</revnumber> + <date>2007-11-26</date> + <authorinitials>hjk</authorinitials> + <revremark>Removed section about uio_dummy.</revremark> + </revision> + <revision> <revnumber>0.3</revnumber> <date>2007-04-29</date> <authorinitials>hjk</authorinitials> @@ -94,6 +100,26 @@ interested in translating it, please email me user space. This simplifies development and reduces the risk of serious bugs within a kernel module. </para> + <para> + Please note that UIO is not an universal driver interface. Devices + that are already handled well by other kernel subsystems (like + networking or serial or USB) are no candidates for an UIO driver. + Hardware that is ideally suited for an UIO driver fulfills all of + the following: + </para> +<itemizedlist> +<listitem> + <para>The device has memory that can be mapped. The device can be + controlled completely by writing to this memory.</para> +</listitem> +<listitem> + <para>The device usually generates interrupts.</para> +</listitem> +<listitem> + <para>The device does not fit into one of the standard kernel + subsystems.</para> +</listitem> +</itemizedlist> </sect1> <sect1 id="thanks"> @@ -174,8 +200,9 @@ interested in translating it, please email me For cards that don't generate interrupts but need to be polled, there is the possibility to set up a timer that triggers the interrupt handler at configurable time intervals. - See <filename>drivers/uio/uio_dummy.c</filename> for an - example of this technique. + This interrupt simulation is done by calling + <function>uio_event_notify()</function> + from the timer's event handler. </para> <para> @@ -263,63 +290,11 @@ offset = N * getpagesize(); </sect1> </chapter> -<chapter id="using-uio_dummy" xreflabel="Using uio_dummy"> -<?dbhtml filename="using-uio_dummy.html"?> -<title>Using uio_dummy</title> - <para> - Well, there is no real use for uio_dummy. Its only purpose is - to test most parts of the UIO system (everything except - hardware interrupts), and to serve as an example for the - kernel module that you will have to write yourself. - </para> - -<sect1 id="what_uio_dummy_does"> -<title>What uio_dummy does</title> - <para> - The kernel module <filename>uio_dummy.ko</filename> creates a - device that uses a timer to generate periodic interrupts. The - interrupt handler does nothing but increment a counter. The - driver adds two custom attributes, <varname>count</varname> - and <varname>freq</varname>, that appear under - <filename>/sys/devices/platform/uio_dummy/</filename>. - </para> - - <para> - The attribute <varname>count</varname> can be read and - written. The associated file - <filename>/sys/devices/platform/uio_dummy/count</filename> - appears as a normal text file and contains the total number of - timer interrupts. If you look at it (e.g. using - <function>cat</function>), you'll notice it is slowly counting - up. - </para> - - <para> - The attribute <varname>freq</varname> can be read and written. - The content of - <filename>/sys/devices/platform/uio_dummy/freq</filename> - represents the number of system timer ticks between two timer - interrupts. The default value of <varname>freq</varname> is - the value of the kernel variable <varname>HZ</varname>, which - gives you an interval of one second. Lower values will - increase the frequency. Try the following: - </para> -<programlisting format="linespecific"> -cd /sys/devices/platform/uio_dummy/ -echo 100 > freq -</programlisting> - <para> - Use <function>cat count</function> to see how the interrupt - frequency changes. - </para> -</sect1> -</chapter> - <chapter id="custom_kernel_module" xreflabel="Writing your own kernel module"> <?dbhtml filename="custom_kernel_module.html"?> <title>Writing your own kernel module</title> <para> - Please have a look at <filename>uio_dummy.c</filename> as an + Please have a look at <filename>uio_cif.c</filename> as an example. The following paragraphs explain the different sections of this file. </para> @@ -354,9 +329,8 @@ See the description below for details. interrupt, it's your modules task to determine the irq number during initialization. If you don't have a hardware generated interrupt but want to trigger the interrupt handler in some other way, set -<varname>irq</varname> to <varname>UIO_IRQ_CUSTOM</varname>. The -uio_dummy module does this as it triggers the event mechanism in a timer -routine. If you had no interrupt at all, you could set +<varname>irq</varname> to <varname>UIO_IRQ_CUSTOM</varname>. +If you had no interrupt at all, you could set <varname>irq</varname> to <varname>UIO_IRQ_NONE</varname>, though this rarely makes sense. </para></listitem> diff --git a/drivers/base/core.c b/drivers/base/core.c index 3f4d6aa1399..2683eac30c6 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -770,9 +770,10 @@ int device_add(struct device *dev) error = device_add_attrs(dev); if (error) goto AttrsError; - error = device_pm_add(dev); + error = dpm_sysfs_add(dev); if (error) goto PMError; + device_pm_add(dev); error = bus_add_device(dev); if (error) goto BusError; @@ -797,6 +798,7 @@ int device_add(struct device *dev) return error; BusError: device_pm_remove(dev); + dpm_sysfs_remove(dev); PMError: if (dev->bus) blocking_notifier_call_chain(&dev->bus->bus_notifier, diff --git a/drivers/base/power/Makefile b/drivers/base/power/Makefile index a803733c839..44504e6618f 100644 --- a/drivers/base/power/Makefile +++ b/drivers/base/power/Makefile @@ -1,5 +1,6 @@ obj-y := shutdown.o -obj-$(CONFIG_PM_SLEEP) += main.o sysfs.o +obj-$(CONFIG_PM) += sysfs.o +obj-$(CONFIG_PM_SLEEP) += main.o obj-$(CONFIG_PM_TRACE) += trace.o ifeq ($(CONFIG_DEBUG_DRIVER),y) diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 0ab4ab21f56..691ffb64cc3 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -38,20 +38,14 @@ static DEFINE_MUTEX(dpm_list_mtx); int (*platform_enable_wakeup)(struct device *dev, int is_on); -int device_pm_add(struct device *dev) +void device_pm_add(struct device *dev) { - int error; - pr_debug("PM: Adding info for %s:%s\n", dev->bus ? dev->bus->name : "No Bus", kobject_name(&dev->kobj)); mutex_lock(&dpm_list_mtx); list_add_tail(&dev->power.entry, &dpm_active); - error = dpm_sysfs_add(dev); - if (error) - list_del(&dev->power.entry); mutex_unlock(&dpm_list_mtx); - return error; } void device_pm_remove(struct device *dev) diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h index 5c4efd493fa..379da4e958e 100644 --- a/drivers/base/power/power.h +++ b/drivers/base/power/power.h @@ -13,14 +13,29 @@ extern void device_shutdown(void); extern struct list_head dpm_active; /* The active device list */ -static inline struct device * to_device(struct list_head * entry) +static inline struct device *to_device(struct list_head *entry) { return container_of(entry, struct device, power.entry); } -extern int device_pm_add(struct device *); +extern void device_pm_add(struct device *); extern void device_pm_remove(struct device *); +#else /* CONFIG_PM_SLEEP */ + + +static inline void device_pm_add(struct device *dev) +{ +} + +static inline void device_pm_remove(struct device *dev) +{ +} + +#endif + +#ifdef CONFIG_PM + /* * sysfs.c */ @@ -28,16 +43,15 @@ extern void device_pm_remove(struct device *); extern int dpm_sysfs_add(struct device *); extern void dpm_sysfs_remove(struct device *); -#else /* CONFIG_PM_SLEEP */ - +#else /* CONFIG_PM */ -static inline int device_pm_add(struct device * dev) +static inline int dpm_sysfs_add(struct device *dev) { return 0; } -static inline void device_pm_remove(struct device * dev) -{ +static inline void dpm_sysfs_remove(struct device *dev) +{ } #endif diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index bf18d757b87..a509b8d7978 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -457,7 +457,7 @@ config LEGACY_PTYS config LEGACY_PTY_COUNT int "Maximum number of legacy PTY in use" depends on LEGACY_PTYS - range 1 256 + range 0 256 default "256" ---help--- The maximum number of legacy PTYs that can be used at any one time. diff --git a/fs/exec.c b/fs/exec.c index 4ccaaa4b13b..282240afe99 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1780,6 +1780,12 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs) but keep the previous behaviour for now. */ if (!ispipe && !S_ISREG(inode->i_mode)) goto close_fail; + /* + * Dont allow local users get cute and trick others to coredump + * into their pre-created files: + */ + if (inode->i_uid != current->fsuid) + goto close_fail; if (!file->f_op) goto close_fail; if (!file->f_op->write) diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 27d1785b764..4045bdcc4b3 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c @@ -119,7 +119,11 @@ static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer sysfs_put_active_two(attr_sd); - BUG_ON(count > (ssize_t)PAGE_SIZE); + /* + * The code works fine with PAGE_SIZE return but it's likely to + * indicate truncated result or overflow in normal use cases. + */ + BUG_ON(count >= (ssize_t)PAGE_SIZE); if (count >= 0) { buffer->needs_read_fill = 0; buffer->count = count; diff --git a/include/linux/sched.h b/include/linux/sched.h index ee800e7a70d..ac3d496fbd2 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -282,6 +282,10 @@ static inline void touch_all_softlockup_watchdogs(void) /* Attach to any functions which should be ignored in wchan output. */ #define __sched __attribute__((__section__(".sched.text"))) + +/* Linker adds these: start and end of __sched functions */ +extern char __sched_text_start[], __sched_text_end[]; + /* Is this address in the __sched functions? */ extern int in_sched_functions(unsigned long addr); diff --git a/kernel/sched.c b/kernel/sched.c index 38933cafea8..98dcdf272db 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -5466,7 +5466,7 @@ sd_alloc_ctl_domain_table(struct sched_domain *sd) return table; } -static ctl_table * sd_alloc_ctl_cpu_table(int cpu) +static ctl_table *sd_alloc_ctl_cpu_table(int cpu) { struct ctl_table *entry, *table; struct sched_domain *sd; @@ -6708,9 +6708,6 @@ void __init sched_init_smp(void) int in_sched_functions(unsigned long addr) { - /* Linker adds these: start and end of __sched functions */ - extern char __sched_text_start[], __sched_text_end[]; - return in_lock_functions(addr) || (addr >= (unsigned long)__sched_text_start && addr < (unsigned long)__sched_text_end); diff --git a/kernel/sched_debug.c b/kernel/sched_debug.c index 5d0d623a546..d30467b47dd 100644 --- a/kernel/sched_debug.c +++ b/kernel/sched_debug.c @@ -327,10 +327,12 @@ void proc_sched_show_task(struct task_struct *p, struct seq_file *m) avg_atom = -1LL; avg_per_cpu = p->se.sum_exec_runtime; - if (p->se.nr_migrations) - avg_per_cpu = div64_64(avg_per_cpu, p->se.nr_migrations); - else + if (p->se.nr_migrations) { + avg_per_cpu = div64_64(avg_per_cpu, + p->se.nr_migrations); + } else { avg_per_cpu = -1LL; + } __PN(avg_atom); __PN(avg_per_cpu); diff --git a/kernel/sched_stats.h b/kernel/sched_stats.h index 630178e53bb..5b32433e7ee 100644 --- a/kernel/sched_stats.h +++ b/kernel/sched_stats.h @@ -52,7 +52,8 @@ static int show_schedstat(struct seq_file *seq, void *v) sd->lb_nobusyq[itype], sd->lb_nobusyg[itype]); } - seq_printf(seq, " %u %u %u %u %u %u %u %u %u %u %u %u\n", + seq_printf(seq, + " %u %u %u %u %u %u %u %u %u %u %u %u\n", sd->alb_count, sd->alb_failed, sd->alb_pushed, sd->sbe_count, sd->sbe_balanced, sd->sbe_pushed, sd->sbf_count, sd->sbf_balanced, sd->sbf_pushed, diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 27a2338deb4..cb89fa8db11 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -133,6 +133,8 @@ void tick_nohz_update_jiffies(void) if (!ts->tick_stopped) return; + touch_softlockup_watchdog(); + cpu_clear(cpu, nohz_cpu_mask); now = ktime_get(); diff --git a/lib/kobject.c b/lib/kobject.c index a7e3bf4d3c7..b52e9f4ef37 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -313,8 +313,8 @@ int kobject_rename(struct kobject * kobj, const char *new_name) struct kobject *temp_kobj; temp_kobj = kset_find_obj(kobj->kset, new_name); if (temp_kobj) { - printk(KERN_WARNING "kobject '%s' can not be renamed " - "to '%s' as '%s' is already in existance.\n", + printk(KERN_WARNING "kobject '%s' cannot be renamed " + "to '%s' as '%s' is already in existence.\n", kobject_name(kobj), new_name, new_name); kobject_put(temp_kobj); return -EINVAL; diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 12376ae3f73..4ffed1cd158 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -305,7 +305,6 @@ static inline void prep_zero_page(struct page *page, int order, gfp_t gfp_flags) { int i; - VM_BUG_ON((gfp_flags & (__GFP_WAIT | __GFP_HIGHMEM)) == __GFP_HIGHMEM); /* * clear_highpage() will use KM_USER0, so it's a bug to use __GFP_ZERO * and __GFP_HIGHMEM from hard or soft interrupt context. diff --git a/mm/shmem.c b/mm/shmem.c index 253d205914b..51b3d6ccdda 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -1072,7 +1072,7 @@ shmem_alloc_page(gfp_t gfp, struct shmem_inode_info *info, pvma.vm_policy = mpol_shared_policy_lookup(&info->policy, idx); pvma.vm_pgoff = idx; pvma.vm_end = PAGE_SIZE; - page = alloc_page_vma(gfp | __GFP_ZERO, &pvma, 0); + page = alloc_page_vma(gfp, &pvma, 0); mpol_free(pvma.vm_policy); return page; } @@ -1093,7 +1093,7 @@ shmem_swapin(struct shmem_inode_info *info,swp_entry_t entry,unsigned long idx) static inline struct page * shmem_alloc_page(gfp_t gfp,struct shmem_inode_info *info, unsigned long idx) { - return alloc_page(gfp | __GFP_ZERO); + return alloc_page(gfp); } #endif @@ -1306,6 +1306,7 @@ repeat: info->alloced++; spin_unlock(&info->lock); + clear_highpage(filepage); flush_dcache_page(filepage); SetPageUptodate(filepage); } |