diff options
Diffstat (limited to 'arch/um')
30 files changed, 195 insertions, 269 deletions
diff --git a/arch/um/Kconfig.common b/arch/um/Kconfig.common index 0d207e7..7c8e277 100644 --- a/arch/um/Kconfig.common +++ b/arch/um/Kconfig.common @@ -55,10 +55,6 @@ config GENERIC_BUG default y depends on BUG -config GENERIC_TIME - bool - default y - config GENERIC_CLOCKEVENTS bool default y diff --git a/arch/um/Kconfig.um b/arch/um/Kconfig.um index ec2b8da..50d6aa2 100644 --- a/arch/um/Kconfig.um +++ b/arch/um/Kconfig.um @@ -120,6 +120,9 @@ config SMP If you don't know what to do, say N. +config GENERIC_HARDIRQS_NO__DO_IRQ + def_bool y + config NR_CPUS int "Maximum number of CPUs (2-32)" range 2 32 @@ -147,3 +150,6 @@ config KERNEL_STACK_ORDER This option determines the size of UML kernel stacks. They will be 1 << order pages. The default is OK unless you're running Valgrind on UML, in which case, set this to 3. + +config NO_DMA + def_bool y diff --git a/arch/um/defconfig b/arch/um/defconfig index 6bd456f..564f3de 100644 --- a/arch/um/defconfig +++ b/arch/um/defconfig @@ -566,7 +566,6 @@ CONFIG_CRC32=m # CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set CONFIG_PLIST=y -CONFIG_HAS_DMA=y # # SCSI device support diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index 6e51424..25e1965 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c @@ -210,9 +210,9 @@ void free_irqs(void) list_for_each(ele, &list) { chan = list_entry(ele, struct chan, free_list); - if (chan->input) + if (chan->input && chan->enabled) free_irq(chan->line->driver->read_irq, chan); - if (chan->output) + if (chan->output && chan->enabled) free_irq(chan->line->driver->write_irq, chan); chan->enabled = 0; } @@ -231,9 +231,9 @@ static void close_one_chan(struct chan *chan, int delay_free_irq) spin_unlock_irqrestore(&irqs_to_free_lock, flags); } else { - if (chan->input) + if (chan->input && chan->enabled) free_irq(chan->line->driver->read_irq, chan); - if (chan->output) + if (chan->output && chan->enabled) free_irq(chan->line->driver->write_irq, chan); chan->enabled = 0; } diff --git a/arch/um/drivers/harddog_kern.c b/arch/um/drivers/harddog_kern.c index cfcac1f..2d0266d 100644 --- a/arch/um/drivers/harddog_kern.c +++ b/arch/um/drivers/harddog_kern.c @@ -42,7 +42,7 @@ #include <linux/miscdevice.h> #include <linux/watchdog.h> #include <linux/reboot.h> -#include <linux/smp_lock.h> +#include <linux/mutex.h> #include <linux/init.h> #include <linux/spinlock.h> #include <asm/uaccess.h> @@ -50,6 +50,7 @@ MODULE_LICENSE("GPL"); +static DEFINE_MUTEX(harddog_mutex); static DEFINE_SPINLOCK(lock); static int timer_alive; static int harddog_in_fd = -1; @@ -66,7 +67,7 @@ static int harddog_open(struct inode *inode, struct file *file) int err = -EBUSY; char *sock = NULL; - lock_kernel(); + mutex_lock(&harddog_mutex); spin_lock(&lock); if(timer_alive) goto err; @@ -83,11 +84,11 @@ static int harddog_open(struct inode *inode, struct file *file) timer_alive = 1; spin_unlock(&lock); - unlock_kernel(); + mutex_unlock(&harddog_mutex); return nonseekable_open(inode, file); err: spin_unlock(&lock); - unlock_kernel(); + mutex_unlock(&harddog_mutex); return err; } @@ -153,9 +154,9 @@ static long harddog_ioctl(struct file *file, { long ret; - lock_kernel(); + mutex_lock(&harddog_mutex); ret = harddog_ioctl_unlocked(file, cmd, arg); - unlock_kernel(); + mutex_unlock(&harddog_mutex); return ret; } @@ -166,6 +167,7 @@ static const struct file_operations harddog_fops = { .unlocked_ioctl = harddog_ioctl, .open = harddog_open, .release = harddog_release, + .llseek = no_llseek, }; static struct miscdevice harddog_miscdev = { diff --git a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c index ae42695..f9f6a4e 100644 --- a/arch/um/drivers/hostaudio_kern.c +++ b/arch/um/drivers/hostaudio_kern.c @@ -8,6 +8,7 @@ #include "linux/slab.h" #include "linux/sound.h" #include "linux/soundcard.h" +#include "linux/mutex.h" #include "asm/uaccess.h" #include "init.h" #include "os.h" @@ -39,6 +40,11 @@ static char *mixer = HOSTAUDIO_DEV_MIXER; " This is used to specify the host mixer device to the hostaudio driver.\n"\ " The default is \"" HOSTAUDIO_DEV_MIXER "\".\n\n" +module_param(dsp, charp, 0644); +MODULE_PARM_DESC(dsp, DSP_HELP); +module_param(mixer, charp, 0644); +MODULE_PARM_DESC(mixer, MIXER_HELP); + #ifndef MODULE static int set_dsp(char *name, int *add) { @@ -55,17 +61,10 @@ static int set_mixer(char *name, int *add) } __uml_setup("mixer=", set_mixer, "mixer=<mixer device>\n" MIXER_HELP); - -#else /*MODULE*/ - -module_param(dsp, charp, 0644); -MODULE_PARM_DESC(dsp, DSP_HELP); - -module_param(mixer, charp, 0644); -MODULE_PARM_DESC(mixer, MIXER_HELP); - #endif +static DEFINE_MUTEX(hostaudio_mutex); + /* /dev/dsp file operations */ static ssize_t hostaudio_read(struct file *file, char __user *buffer, @@ -186,7 +185,9 @@ static int hostaudio_open(struct inode *inode, struct file *file) int ret; #ifdef DEBUG + kparam_block_sysfs_write(dsp); printk(KERN_DEBUG "hostaudio: open called (host: %s)\n", dsp); + kparam_unblock_sysfs_write(dsp); #endif state = kmalloc(sizeof(struct hostaudio_state), GFP_KERNEL); @@ -198,7 +199,12 @@ static int hostaudio_open(struct inode *inode, struct file *file) if (file->f_mode & FMODE_WRITE) w = 1; + kparam_block_sysfs_write(dsp); + mutex_lock(&hostaudio_mutex); ret = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0); + mutex_unlock(&hostaudio_mutex); + kparam_unblock_sysfs_write(dsp); + if (ret < 0) { kfree(state); return ret; @@ -254,11 +260,17 @@ static int hostmixer_open_mixdev(struct inode *inode, struct file *file) if (file->f_mode & FMODE_WRITE) w = 1; + kparam_block_sysfs_write(mixer); + mutex_lock(&hostaudio_mutex); ret = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0); + mutex_unlock(&hostaudio_mutex); + kparam_unblock_sysfs_write(mixer); if (ret < 0) { + kparam_block_sysfs_write(dsp); printk(KERN_ERR "hostaudio_open_mixdev failed to open '%s', " "err = %d\n", dsp, -ret); + kparam_unblock_sysfs_write(dsp); kfree(state); return ret; } @@ -314,8 +326,10 @@ MODULE_LICENSE("GPL"); static int __init hostaudio_init_module(void) { + __kernel_param_lock(); printk(KERN_INFO "UML Audio Relay (host dsp = %s, host mixer = %s)\n", dsp, mixer); + __kernel_param_unlock(); module_data.dev_audio = register_sound_dsp(&hostaudio_fops, -1); if (module_data.dev_audio < 0) { diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index de317d0..975613b 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c @@ -690,7 +690,7 @@ static void with_console(struct mc_request *req, void (*proc)(void *), static void sysrq_proc(void *arg) { char *op = arg; - handle_sysrq(*op, NULL); + handle_sysrq(*op); } void mconsole_sysrq(struct mc_request *req) @@ -843,6 +843,7 @@ static ssize_t mconsole_proc_write(struct file *file, static const struct file_operations mconsole_proc_fops = { .owner = THIS_MODULE, .write = mconsole_proc_write, + .llseek = noop_llseek, }; static int create_proc_mconsole(void) diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c index 7158393..8501e7d 100644 --- a/arch/um/drivers/mmapper_kern.c +++ b/arch/um/drivers/mmapper_kern.c @@ -93,6 +93,7 @@ static const struct file_operations mmapper_fops = { .mmap = mmapper_mmap, .open = mmapper_open, .release = mmapper_release, + .llseek = default_llseek, }; /* diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index f053726..47d0c37 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -25,11 +25,6 @@ #include "net_kern.h" #include "net_user.h" -static inline void set_ether_mac(struct net_device *dev, unsigned char *addr) -{ - memcpy(dev->dev_addr, addr, ETH_ALEN); -} - #define DRIVER_NAME "uml-netdev" static DEFINE_SPINLOCK(opened_lock); @@ -260,18 +255,6 @@ static void uml_net_tx_timeout(struct net_device *dev) netif_wake_queue(dev); } -static int uml_net_set_mac(struct net_device *dev, void *addr) -{ - struct uml_net_private *lp = netdev_priv(dev); - struct sockaddr *hwaddr = addr; - - spin_lock_irq(&lp->lock); - set_ether_mac(dev, hwaddr->sa_data); - spin_unlock_irq(&lp->lock); - - return 0; -} - static int uml_net_change_mtu(struct net_device *dev, int new_mtu) { dev->mtu = new_mtu; @@ -378,9 +361,8 @@ static const struct net_device_ops uml_netdev_ops = { .ndo_start_xmit = uml_net_start_xmit, .ndo_set_multicast_list = uml_net_set_multicast_list, .ndo_tx_timeout = uml_net_tx_timeout, - .ndo_set_mac_address = uml_net_set_mac, + .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = uml_net_change_mtu, - .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, }; @@ -478,7 +460,8 @@ static void eth_configure(int n, void *init, char *mac, ((*transport->user->init)(&lp->user, dev) != 0)) goto out_unregister; - set_ether_mac(dev, device->mac); + /* don't use eth_mac_addr, it will not work here */ + memcpy(dev->dev_addr, device->mac, ETH_ALEN); dev->mtu = transport->user->mtu; dev->netdev_ops = ¨_netdev_ops; dev->ethtool_ops = ¨_net_ethtool_ops; diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c index 4949044..981085a 100644 --- a/arch/um/drivers/random.c +++ b/arch/um/drivers/random.c @@ -100,6 +100,7 @@ static const struct file_operations rng_chrdev_ops = { .owner = THIS_MODULE, .open = rng_dev_open, .read = rng_dev_read, + .llseek = noop_llseek, }; /* rng_init shouldn't be called more than once at boot time */ diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index da992a3..ba4a98b 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -33,6 +33,7 @@ #include "linux/mm.h" #include "linux/slab.h" #include "linux/vmalloc.h" +#include "linux/mutex.h" #include "linux/blkpg.h" #include "linux/genhd.h" #include "linux/spinlock.h" @@ -99,6 +100,7 @@ static inline void ubd_set_bit(__u64 bit, unsigned char *data) #define DRIVER_NAME "uml-blkdev" static DEFINE_MUTEX(ubd_lock); +static DEFINE_MUTEX(ubd_mutex); /* replaces BKL, might not be needed */ static int ubd_open(struct block_device *bdev, fmode_t mode); static int ubd_release(struct gendisk *disk, fmode_t mode); @@ -162,6 +164,7 @@ struct ubd { struct scatterlist sg[MAX_SG]; struct request *request; int start_sg, end_sg; + sector_t rq_pos; }; #define DEFAULT_COW { \ @@ -186,6 +189,7 @@ struct ubd { .request = NULL, \ .start_sg = 0, \ .end_sg = 0, \ + .rq_pos = 0, \ } /* Protected by ubd_lock */ @@ -1098,6 +1102,7 @@ static int ubd_open(struct block_device *bdev, fmode_t mode) struct ubd *ubd_dev = disk->private_data; int err = 0; + mutex_lock(&ubd_mutex); if(ubd_dev->count == 0){ err = ubd_open_dev(ubd_dev); if(err){ @@ -1115,7 +1120,8 @@ static int ubd_open(struct block_device *bdev, fmode_t mode) if(--ubd_dev->count == 0) ubd_close_dev(ubd_dev); err = -EROFS; }*/ - out: +out: + mutex_unlock(&ubd_mutex); return err; } @@ -1123,8 +1129,10 @@ static int ubd_release(struct gendisk *disk, fmode_t mode) { struct ubd *ubd_dev = disk->private_data; + mutex_lock(&ubd_mutex); if(--ubd_dev->count == 0) ubd_close_dev(ubd_dev); + mutex_unlock(&ubd_mutex); return 0; } @@ -1223,7 +1231,6 @@ static void do_ubd_request(struct request_queue *q) { struct io_thread_req *io_req; struct request *req; - sector_t sector; int n; while(1){ @@ -1234,12 +1241,12 @@ static void do_ubd_request(struct request_queue *q) return; dev->request = req; + dev->rq_pos = blk_rq_pos(req); dev->start_sg = 0; dev->end_sg = blk_rq_map_sg(q, req, dev->sg); } req = dev->request; - sector = blk_rq_pos(req); while(dev->start_sg < dev->end_sg){ struct scatterlist *sg = &dev->sg[dev->start_sg]; @@ -1251,10 +1258,9 @@ static void do_ubd_request(struct request_queue *q) return; } prepare_request(req, io_req, - (unsigned long long)sector << 9, + (unsigned long long)dev->rq_pos << 9, sg->offset, sg->length, sg_page(sg)); - sector += sg->length >> 9; n = os_write_file(thread_fd, &io_req, sizeof(struct io_thread_req *)); if(n != sizeof(struct io_thread_req *)){ @@ -1267,6 +1273,7 @@ static void do_ubd_request(struct request_queue *q) return; } + dev->rq_pos += sg->length >> 9; dev->start_sg++; } dev->end_sg = 0; diff --git a/arch/um/include/asm/dma-mapping.h b/arch/um/include/asm/dma-mapping.h deleted file mode 100644 index b948c14..0000000 --- a/arch/um/include/asm/dma-mapping.h +++ /dev/null @@ -1,120 +0,0 @@ -#ifndef _ASM_DMA_MAPPING_H -#define _ASM_DMA_MAPPING_H - -#include <asm/scatterlist.h> - -static inline int -dma_supported(struct device *dev, u64 mask) -{ - BUG(); - return(0); -} - -static inline int -dma_set_mask(struct device *dev, u64 dma_mask) -{ - BUG(); - return(0); -} - -static inline void * -dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, - gfp_t flag) -{ - BUG(); - return((void *) 0); -} - -static inline void -dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, - dma_addr_t dma_handle) -{ - BUG(); -} - -static inline dma_addr_t -dma_map_single(struct device *dev, void *cpu_addr, size_t size, - enum dma_data_direction direction) -{ - BUG(); - return(0); -} - -static inline void -dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, - enum dma_data_direction direction) -{ - BUG(); -} - -static inline dma_addr_t -dma_map_page(struct device *dev, struct page *page, - unsigned long offset, size_t size, - enum dma_data_direction direction) -{ - BUG(); - return(0); -} - -static inline void -dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size, - enum dma_data_direction direction) -{ - BUG(); -} - -static inline int -dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, - enum dma_data_direction direction) -{ - BUG(); - return(0); -} - -static inline void -dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries, - enum dma_data_direction direction) -{ - BUG(); -} - -static inline void -dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, - enum dma_data_direction direction) -{ - BUG(); -} - -static inline void -dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems, - enum dma_data_direction direction) -{ - BUG(); -} - -#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) -#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) -#define dma_is_consistent(d, h) (1) - -static inline int -dma_get_cache_alignment(void) -{ - BUG(); - return(0); -} - -static inline void -dma_cache_sync(struct device *dev, void *vaddr, size_t size, - enum dma_data_direction direction) -{ - BUG(); -} - -static inline int -dma_mapping_error(struct device *dev, dma_addr_t dma_handle) -{ - BUG(); - return 0; -} - -#endif diff --git a/arch/um/include/asm/pgtable-3level.h b/arch/um/include/asm/pgtable-3level.h index 084de4a..0032f92 100644 --- a/arch/um/include/asm/pgtable-3level.h +++ b/arch/um/include/asm/pgtable-3level.h @@ -60,7 +60,7 @@ set_pud(pud, __pud(_PAGE_TABLE + __pa(pmd))) #ifdef CONFIG_64BIT -#define set_pud(pudptr, pudval) set_64bit((phys_t *) (pudptr), pud_val(pudval)) +#define set_pud(pudptr, pudval) set_64bit((u64 *) (pudptr), pud_val(pudval)) #else #define set_pud(pudptr, pudval) (*(pudptr) = (pudval)) #endif @@ -73,7 +73,7 @@ static inline int pgd_newpage(pgd_t pgd) static inline void pgd_mkuptodate(pgd_t pgd) { pgd_val(pgd) &= ~_PAGE_NEWPAGE; } #ifdef CONFIG_64BIT -#define set_pmd(pmdptr, pmdval) set_64bit((phys_t *) (pmdptr), pmd_val(pmdval)) +#define set_pmd(pmdptr, pmdval) set_64bit((u64 *) (pmdptr), pmd_val(pmdval)) #else #define set_pmd(pmdptr, pmdval) (*(pmdptr) = (pmdval)) #endif diff --git a/arch/um/include/asm/pgtable.h b/arch/um/include/asm/pgtable.h index a9f7251..41474fb 100644 --- a/arch/um/include/asm/pgtable.h +++ b/arch/um/include/asm/pgtable.h @@ -338,9 +338,7 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) ((pte_t *) pmd_page_vaddr(*(dir)) + pte_index(address)) #define pte_offset_map(dir, address) \ ((pte_t *)page_address(pmd_page(*(dir))) + pte_index(address)) -#define pte_offset_map_nested(dir, address) pte_offset_map(dir, address) #define pte_unmap(pte) do { } while (0) -#define pte_unmap_nested(pte) do { } while (0) struct mm_struct; extern pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr); diff --git a/arch/um/include/asm/system.h b/arch/um/include/asm/system.h index 93af1cf..68a90ec 100644 --- a/arch/um/include/asm/system.h +++ b/arch/um/include/asm/system.h @@ -8,23 +8,38 @@ extern int set_signals(int enable); extern void block_signals(void); extern void unblock_signals(void); -#define local_save_flags(flags) do { typecheck(unsigned long, flags); \ - (flags) = get_signals(); } while(0) -#define local_irq_restore(flags) do { typecheck(unsigned long, flags); \ - set_signals(flags); } while(0) - -#define local_irq_save(flags) do { local_save_flags(flags); \ - local_irq_disable(); } while(0) - -#define local_irq_enable() unblock_signals() -#define local_irq_disable() block_signals() - -#define irqs_disabled() \ -({ \ - unsigned long flags; \ - local_save_flags(flags); \ - (flags == 0); \ -}) +static inline unsigned long arch_local_save_flags(void) +{ + return get_signals(); +} + +static inline void arch_local_irq_restore(unsigned long flags) +{ + set_signals(flags); +} + +static inline void arch_local_irq_enable(void) +{ + unblock_signals(); +} + +static inline void arch_local_irq_disable(void) +{ + block_signals(); +} + +static inline unsigned long arch_local_irq_save(void) +{ + unsigned long flags; + flags = arch_local_save_flags(); + arch_local_irq_disable(); + return flags; +} + +static inline bool arch_irqs_disabled(void) +{ + return arch_local_save_flags() == 0; +} extern void *_switch_to(void *prev, void *next, void *last); #define switch_to(prev, next, last) prev = _switch_to(prev, next, last) diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h index cd40fdd..c4617ba 100644 --- a/arch/um/include/shared/os.h +++ b/arch/um/include/shared/os.h @@ -161,6 +161,9 @@ extern int os_stat_filesystem(char *path, long *bsize_out, long *spare_out); extern int os_change_dir(char *dir); extern int os_fchange_dir(int fd); +extern unsigned os_major(unsigned long long dev); +extern unsigned os_minor(unsigned long long dev); +extern unsigned long long os_makedev(unsigned major, unsigned minor); /* start_up.c */ extern void os_early_checks(void); diff --git a/arch/um/kernel/dyn.lds.S b/arch/um/kernel/dyn.lds.S index 6926801..a3cab6d 100644 --- a/arch/um/kernel/dyn.lds.S +++ b/arch/um/kernel/dyn.lds.S @@ -50,8 +50,18 @@ SECTIONS .rela.got : { *(.rela.got) } .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } - .rel.plt : { *(.rel.plt) } - .rela.plt : { *(.rela.plt) } + .rel.plt : { + *(.rel.plt) + PROVIDE_HIDDEN(__rel_iplt_start = .); + *(.rel.iplt) + PROVIDE_HIDDEN(__rel_iplt_end = .); + } + .rela.plt : { + *(.rela.plt) + PROVIDE_HIDDEN(__rela_iplt_start = .); + *(.rela.iplt) + PROVIDE_HIDDEN(__rela_iplt_end = .); + } .init : { KEEP (*(.init)) } =0x90909090 diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c index 97974c1..340268b 100644 --- a/arch/um/kernel/exec.c +++ b/arch/um/kernel/exec.c @@ -44,8 +44,9 @@ void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp) PT_REGS_SP(regs) = esp; } -static long execve1(char *file, char __user * __user *argv, - char __user *__user *env) +static long execve1(const char *file, + const char __user *const __user *argv, + const char __user *const __user *env) { long error; @@ -61,7 +62,7 @@ static long execve1(char *file, char __user * __user *argv, return error; } -long um_execve(char *file, char __user *__user *argv, char __user *__user *env) +long um_execve(const char *file, const char __user *const __user *argv, const char __user *const __user *env) { long err; @@ -71,19 +72,17 @@ long um_execve(char *file, char __user *__user *argv, char __user *__user *env) return err; } -long sys_execve(char __user *file, char __user *__user *argv, - char __user *__user *env) +long sys_execve(const char __user *file, const char __user *const __user *argv, + const char __user *const __user *env) { long error; char *filename; - lock_kernel(); filename = getname(file); error = PTR_ERR(filename); if (IS_ERR(filename)) goto out; error = execve1(filename, argv, env); putname(filename); out: - unlock_kernel(); return error; } diff --git a/arch/um/kernel/internal.h b/arch/um/kernel/internal.h index 3bda43c..5bf97db 100644 --- a/arch/um/kernel/internal.h +++ b/arch/um/kernel/internal.h @@ -1 +1 @@ -extern long um_execve(char *file, char __user *__user *argv, char __user *__user *env); +extern long um_execve(const char *file, const char __user *const __user *argv, const char __user *const __user *env); diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index a3f0b04..3f0ac9e 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c @@ -46,7 +46,7 @@ int show_interrupts(struct seq_file *p, void *v) for_each_online_cpu(j) seq_printf(p, "%10u ", kstat_irqs_cpu(i, j)); #endif - seq_printf(p, " %14s", irq_desc[i].chip->typename); + seq_printf(p, " %14s", irq_desc[i].chip->name); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) @@ -334,7 +334,7 @@ unsigned int do_IRQ(int irq, struct uml_pt_regs *regs) { struct pt_regs *old_regs = set_irq_regs((struct pt_regs *)regs); irq_enter(); - __do_IRQ(irq); + generic_handle_irq(irq); irq_exit(); set_irq_regs(old_regs); return 1; @@ -369,7 +369,7 @@ static void dummy(unsigned int irq) /* This is used for everything else than the timer. */ static struct irq_chip normal_irq_type = { - .typename = "SIGIO", + .name = "SIGIO", .release = free_irq_by_irq_and_dev, .disable = dummy, .enable = dummy, @@ -378,7 +378,7 @@ static struct irq_chip normal_irq_type = { }; static struct irq_chip SIGVTALRM_irq_type = { - .typename = "SIGVTALRM", + .name = "SIGVTALRM", .release = free_irq_by_irq_and_dev, .shutdown = dummy, /* never called */ .disable = dummy, @@ -391,17 +391,10 @@ void __init init_IRQ(void) { int i; - irq_desc[TIMER_IRQ].status = IRQ_DISABLED; - irq_desc[TIMER_IRQ].action = NULL; - irq_desc[TIMER_IRQ].depth = 1; - irq_desc[TIMER_IRQ].chip = &SIGVTALRM_irq_type; - enable_irq(TIMER_IRQ); + set_irq_chip_and_handler(TIMER_IRQ, &SIGVTALRM_irq_type, handle_edge_irq); + for (i = 1; i < NR_IRQS; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = NULL; - irq_desc[i].depth = 1; - irq_desc[i].chip = &normal_irq_type; - enable_irq(i); + set_irq_chip_and_handler(i, &normal_irq_type, handle_edge_irq); } } diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c index 836fc9b..0ae0dfc 100644 --- a/arch/um/kernel/ksyms.c +++ b/arch/um/kernel/ksyms.c @@ -58,6 +58,9 @@ EXPORT_SYMBOL(os_accept_connection); EXPORT_SYMBOL(os_rcv_fd); EXPORT_SYMBOL(run_helper); EXPORT_SYMBOL(start_thread); +EXPORT_SYMBOL(os_major); +EXPORT_SYMBOL(os_minor); +EXPORT_SYMBOL(os_makedev); EXPORT_SYMBOL(add_sigio_fd); EXPORT_SYMBOL(ignore_sigio_fd); diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c index 4845099..a5e33f2 100644 --- a/arch/um/kernel/ptrace.c +++ b/arch/um/kernel/ptrace.c @@ -7,9 +7,6 @@ #include "linux/ptrace.h" #include "linux/sched.h" #include "asm/uaccess.h" -#ifdef CONFIG_PROC_MM -#include "proc_mm.h" -#endif #include "skas_ptrace.h" @@ -45,10 +42,12 @@ void ptrace_disable(struct task_struct *child) extern int peek_user(struct task_struct * child, long addr, long data); extern int poke_user(struct task_struct * child, long addr, long data); -long arch_ptrace(struct task_struct *child, long request, long addr, long data) +long arch_ptrace(struct task_struct *child, long request, + unsigned long addr, unsigned long data) { int i, ret; - unsigned long __user *p = (void __user *)(unsigned long)data; + unsigned long __user *p = (void __user *)data; + void __user *vp = p; switch (request) { /* read word at location addr. */ @@ -110,24 +109,20 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) #endif #ifdef PTRACE_GETFPREGS case PTRACE_GETFPREGS: /* Get the child FPU state. */ - ret = get_fpregs((struct user_i387_struct __user *) data, - child); + ret = get_fpregs(vp, child); break; #endif #ifdef PTRACE_SETFPREGS case PTRACE_SETFPREGS: /* Set the child FPU state. */ - ret = set_fpregs((struct user_i387_struct __user *) data, - child); + ret = set_fpregs(vp, child); break; #endif case PTRACE_GET_THREAD_AREA: - ret = ptrace_get_thread_area(child, addr, - (struct user_desc __user *) data); + ret = ptrace_get_thread_area(child, addr, vp); break; case PTRACE_SET_THREAD_AREA: - ret = ptrace_set_thread_area(child, addr, - (struct user_desc __user *) data); + ret = ptrace_set_thread_area(child, addr, datavp); break; case PTRACE_FAULTINFO: { @@ -137,7 +132,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) * On i386, ptrace_faultinfo is smaller! */ ret = copy_to_user(p, &child->thread.arch.faultinfo, - sizeof(struct ptrace_faultinfo)); + sizeof(struct ptrace_faultinfo)) ? + -EIO : 0; break; } @@ -158,28 +154,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) break; } #endif -#ifdef CONFIG_PROC_MM - case PTRACE_SWITCH_MM: { - struct mm_struct *old = child->mm; - struct mm_struct *new = proc_mm_get_mm(data); - - if (IS_ERR(new)) { - ret = PTR_ERR(new); - break; - } - - atomic_inc(&new->mm_users); - child->mm = new; - child->active_mm = new; - mmput(old); - ret = 0; - break; - } -#endif #ifdef PTRACE_ARCH_PRCTL case PTRACE_ARCH_PRCTL: /* XXX Calls ptrace on the host - needs some SMP thinking */ - ret = arch_prctl(child, data, (void *) addr); + ret = arch_prctl(child, data, (void __user *) addr); break; #endif default: diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c index 4393173..f958cb8 100644 --- a/arch/um/kernel/syscall.c +++ b/arch/um/kernel/syscall.c @@ -51,15 +51,17 @@ long old_mmap(unsigned long addr, unsigned long len, return err; } -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) +int kernel_execve(const char *filename, + const char *const argv[], + const char *const envp[]) { mm_segment_t fs; int ret; fs = get_fs(); set_fs(KERNEL_DS); - ret = um_execve((char *)filename, (char __user *__user *)argv, - (char __user *__user *) envp); + ret = um_execve(filename, (const char __user *const __user *)argv, + (const char __user *const __user *) envp); set_fs(fs); return ret; diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c index c8b9c46..a08d9fa 100644 --- a/arch/um/kernel/time.c +++ b/arch/um/kernel/time.c @@ -102,16 +102,16 @@ static void __init setup_itimer(void) clockevents_register_device(&itimer_clockevent); } -void __init time_init(void) +void read_persistent_clock(struct timespec *ts) { - long long nsecs; - - timer_init(); + long long nsecs = os_nsecs(); - nsecs = os_nsecs(); - set_normalized_timespec(&wall_to_monotonic, -nsecs / NSEC_PER_SEC, - -nsecs % NSEC_PER_SEC); - set_normalized_timespec(&xtime, nsecs / NSEC_PER_SEC, + set_normalized_timespec(ts, nsecs / NSEC_PER_SEC, nsecs % NSEC_PER_SEC); +} + +void __init time_init(void) +{ + timer_init(); late_time_init = setup_itimer; } diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S index ec63785..fbd9940 100644 --- a/arch/um/kernel/uml.lds.S +++ b/arch/um/kernel/uml.lds.S @@ -22,7 +22,7 @@ SECTIONS _text = .; _stext = .; __init_begin = .; - INIT_TEXT_SECTION(PAGE_SIZE) + INIT_TEXT_SECTION(0) . = ALIGN(PAGE_SIZE); .text : @@ -43,6 +43,23 @@ SECTIONS __syscall_stub_end = .; } + /* + * These are needed even in a static link, even if they wind up being empty. + * Newer glibc needs these __rel{,a}_iplt_{start,end} symbols. + */ + .rel.plt : { + *(.rel.plt) + PROVIDE_HIDDEN(__rel_iplt_start = .); + *(.rel.iplt) + PROVIDE_HIDDEN(__rel_iplt_end = .); + } + .rela.plt : { + *(.rela.plt) + PROVIDE_HIDDEN(__rela_iplt_start = .); + *(.rela.iplt) + PROVIDE_HIDDEN(__rela_iplt_end = .); + } + #include "asm/common.lds.S" init.data : { INIT_DATA } diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c index b5afcfd..140e587 100644 --- a/arch/um/os-Linux/file.c +++ b/arch/um/os-Linux/file.c @@ -561,3 +561,18 @@ int os_lock_file(int fd, int excl) out: return err; } + +unsigned os_major(unsigned long long dev) +{ + return major(dev); +} + +unsigned os_minor(unsigned long long dev) +{ + return minor(dev); +} + +unsigned long long os_makedev(unsigned major, unsigned minor) +{ + return makedev(major, minor); +} diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c index dec5678..6e3359d 100644 --- a/arch/um/os-Linux/time.c +++ b/arch/um/os-Linux/time.c @@ -60,7 +60,7 @@ static inline long long timeval_to_ns(const struct timeval *tv) long long disable_timer(void) { struct itimerval time = ((struct itimerval) { { 0, 0 }, { 0, 0 } }); - int remain, max = UM_NSEC_PER_SEC / UM_HZ; + long long remain, max = UM_NSEC_PER_SEC / UM_HZ; if (setitimer(ITIMER_VIRTUAL, &time, &time) < 0) printk(UM_KERN_ERR "disable_timer - setitimer failed, " diff --git a/arch/um/os-Linux/user_syms.c b/arch/um/os-Linux/user_syms.c index 89b48a1..05f5ea8 100644 --- a/arch/um/os-Linux/user_syms.c +++ b/arch/um/os-Linux/user_syms.c @@ -103,6 +103,10 @@ EXPORT_SYMBOL_PROTO(getuid); EXPORT_SYMBOL_PROTO(fsync); EXPORT_SYMBOL_PROTO(fdatasync); +EXPORT_SYMBOL_PROTO(lstat64); +EXPORT_SYMBOL_PROTO(fstat64); +EXPORT_SYMBOL_PROTO(mknod); + /* Export symbols used by GCC for the stack protector. */ extern void __stack_smash_handler(void *) __attribute__((weak)); EXPORT_SYMBOL(__stack_smash_handler); diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c index c9b1765..d23b2d3 100644 --- a/arch/um/sys-i386/ptrace.c +++ b/arch/um/sys-i386/ptrace.c @@ -203,8 +203,8 @@ int set_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child) (unsigned long *) &fpregs); } -long subarch_ptrace(struct task_struct *child, long request, long addr, - long data) +long subarch_ptrace(struct task_struct *child, long request, + unsigned long addr, unsigned long data) { return -EIO; } diff --git a/arch/um/sys-x86_64/ptrace.c b/arch/um/sys-x86_64/ptrace.c index f3458d7..f436136 100644 --- a/arch/um/sys-x86_64/ptrace.c +++ b/arch/um/sys-x86_64/ptrace.c @@ -175,19 +175,18 @@ int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) return restore_fp_registers(userspace_pid[cpu], fpregs); } -long subarch_ptrace(struct task_struct *child, long request, long addr, - long data) +long subarch_ptrace(struct task_struct *child, long request, + unsigned long addr, unsigned long data) { int ret = -EIO; + void __user *datap = (void __user *) data; switch (request) { case PTRACE_GETFPXREGS: /* Get the child FPU state. */ - ret = get_fpregs((struct user_i387_struct __user *) data, - child); + ret = get_fpregs(datap, child); break; case PTRACE_SETFPXREGS: /* Set the child FPU state. */ - ret = set_fpregs((struct user_i387_struct __user *) data, - child); + ret = set_fpregs(datap, child); break; } |