From 7c5fa64debc23f128dc9577e27a18e6210085d71 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Tue, 16 Nov 2010 09:13:41 -0800 Subject: [PATCH] --- yaml --- r: 222161 b: refs/heads/master c: 8c05cd08a7504b855c265263e84af61aabafa329 h: refs/heads/master i: 222159: ba32f2a51c8f42da730987ff4a6c5915641fa2fd v: v3 --- [refs] | 2 +- trunk/arch/s390/Kconfig.debug | 12 ----- trunk/arch/s390/include/asm/page.h | 5 --- trunk/arch/s390/kernel/kprobes.c | 70 +++++++---------------------- trunk/arch/s390/mm/gup.c | 7 +-- trunk/drivers/pci/pci-sysfs.c | 2 +- trunk/drivers/s390/char/tape_core.c | 68 ++++------------------------ trunk/drivers/s390/char/vmlogrdr.c | 36 +++++---------- trunk/drivers/s390/cio/device.c | 11 +---- trunk/kernel/sysctl.c | 2 +- trunk/kernel/trace/Kconfig | 2 +- 11 files changed, 47 insertions(+), 170 deletions(-) diff --git a/[refs] b/[refs] index e9d9530dbdad..d61455d7ae0e 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 2ebc8ec86fe0f3f3acf9ba9b41a368f819e7807e +refs/heads/master: 8c05cd08a7504b855c265263e84af61aabafa329 diff --git a/trunk/arch/s390/Kconfig.debug b/trunk/arch/s390/Kconfig.debug index 05221b13ffb1..45e0c6199f36 100644 --- a/trunk/arch/s390/Kconfig.debug +++ b/trunk/arch/s390/Kconfig.debug @@ -6,18 +6,6 @@ config TRACE_IRQFLAGS_SUPPORT source "lib/Kconfig.debug" -config STRICT_DEVMEM - def_bool y - prompt "Filter access to /dev/mem" - ---help--- - This option restricts access to /dev/mem. If this option is - disabled, you allow userspace access to all memory, including - kernel and userspace memory. Accidental memory access is likely - to be disastrous. - Memory access is required for experts who want to debug the kernel. - - If you are unsure, say Y. - config DEBUG_STRICT_USER_COPY_CHECKS bool "Strict user copy size checks" ---help--- diff --git a/trunk/arch/s390/include/asm/page.h b/trunk/arch/s390/include/asm/page.h index 3c987e9ec8d6..a8729ea7e9ac 100644 --- a/trunk/arch/s390/include/asm/page.h +++ b/trunk/arch/s390/include/asm/page.h @@ -130,11 +130,6 @@ struct page; void arch_free_page(struct page *page, int order); void arch_alloc_page(struct page *page, int order); -static inline int devmem_is_allowed(unsigned long pfn) -{ - return 0; -} - #define HAVE_ARCH_FREE_PAGE #define HAVE_ARCH_ALLOC_PAGE diff --git a/trunk/arch/s390/kernel/kprobes.c b/trunk/arch/s390/kernel/kprobes.c index 2564793ec2b6..d60fc4398516 100644 --- a/trunk/arch/s390/kernel/kprobes.c +++ b/trunk/arch/s390/kernel/kprobes.c @@ -30,7 +30,6 @@ #include #include #include -#include DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); @@ -213,7 +212,7 @@ static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs) /* Set the PER control regs, turns on single step for this address */ __ctl_load(kprobe_per_regs, 9, 11); regs->psw.mask |= PSW_MASK_PER; - regs->psw.mask &= ~(PSW_MASK_IO | PSW_MASK_EXT); + regs->psw.mask &= ~(PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK); } static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb) @@ -240,7 +239,7 @@ static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs, __get_cpu_var(current_kprobe) = p; /* Save the interrupt and per flags */ kcb->kprobe_saved_imask = regs->psw.mask & - (PSW_MASK_PER | PSW_MASK_IO | PSW_MASK_EXT); + (PSW_MASK_PER | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK); /* Save the control regs that govern PER */ __ctl_store(kcb->kprobe_saved_ctl, 9, 11); } @@ -317,6 +316,8 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) return 1; ss_probe: + if (regs->psw.mask & (PSW_MASK_PER | PSW_MASK_IO)) + local_irq_disable(); prepare_singlestep(p, regs); kcb->kprobe_status = KPROBE_HIT_SS; return 1; @@ -349,7 +350,6 @@ static int __kprobes trampoline_probe_handler(struct kprobe *p, struct hlist_node *node, *tmp; unsigned long flags, orig_ret_address = 0; unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline; - kprobe_opcode_t *correct_ret_addr = NULL; INIT_HLIST_HEAD(&empty_rp); kretprobe_hash_lock(current, &head, &flags); @@ -372,32 +372,10 @@ static int __kprobes trampoline_probe_handler(struct kprobe *p, /* another task is sharing our hash bucket */ continue; - orig_ret_address = (unsigned long)ri->ret_addr; - - if (orig_ret_address != trampoline_address) - /* - * This is the real return address. Any other - * instances associated with this task are for - * other calls deeper on the call stack - */ - break; - } - - kretprobe_assert(ri, orig_ret_address, trampoline_address); - - correct_ret_addr = ri->ret_addr; - hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { - if (ri->task != current) - /* another task is sharing our hash bucket */ - continue; - - orig_ret_address = (unsigned long)ri->ret_addr; - - if (ri->rp && ri->rp->handler) { - ri->ret_addr = correct_ret_addr; + if (ri->rp && ri->rp->handler) ri->rp->handler(ri, regs); - } + orig_ret_address = (unsigned long)ri->ret_addr; recycle_rp_inst(ri, &empty_rp); if (orig_ret_address != trampoline_address) { @@ -409,7 +387,7 @@ static int __kprobes trampoline_probe_handler(struct kprobe *p, break; } } - + kretprobe_assert(ri, orig_ret_address, trampoline_address); regs->psw.addr = orig_ret_address | PSW_ADDR_AMODE; reset_current_kprobe(); @@ -487,6 +465,8 @@ static int __kprobes post_kprobe_handler(struct pt_regs *regs) goto out; } reset_current_kprobe(); + if (regs->psw.mask & (PSW_MASK_PER | PSW_MASK_IO)) + local_irq_enable(); out: preempt_enable_no_resched(); @@ -502,7 +482,7 @@ static int __kprobes post_kprobe_handler(struct pt_regs *regs) return 1; } -static int __kprobes kprobe_trap_handler(struct pt_regs *regs, int trapnr) +int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) { struct kprobe *cur = kprobe_running(); struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); @@ -528,6 +508,8 @@ static int __kprobes kprobe_trap_handler(struct pt_regs *regs, int trapnr) restore_previous_kprobe(kcb); else { reset_current_kprobe(); + if (regs->psw.mask & (PSW_MASK_PER | PSW_MASK_IO)) + local_irq_enable(); } preempt_enable_no_resched(); break; @@ -571,18 +553,6 @@ static int __kprobes kprobe_trap_handler(struct pt_regs *regs, int trapnr) return 0; } -int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) -{ - int ret; - - if (regs->psw.mask & (PSW_MASK_IO | PSW_MASK_EXT)) - local_irq_disable(); - ret = kprobe_trap_handler(regs, trapnr); - if (regs->psw.mask & (PSW_MASK_IO | PSW_MASK_EXT)) - local_irq_restore(regs->psw.mask & ~PSW_MASK_PER); - return ret; -} - /* * Wrapper routine to for handling exceptions. */ @@ -590,12 +560,8 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, unsigned long val, void *data) { struct die_args *args = (struct die_args *)data; - struct pt_regs *regs = args->regs; int ret = NOTIFY_DONE; - if (regs->psw.mask & (PSW_MASK_IO | PSW_MASK_EXT)) - local_irq_disable(); - switch (val) { case DIE_BPT: if (kprobe_handler(args->regs)) @@ -606,17 +572,16 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, ret = NOTIFY_STOP; break; case DIE_TRAP: - if (!preemptible() && kprobe_running() && - kprobe_trap_handler(args->regs, args->trapnr)) + /* kprobe_running() needs smp_processor_id() */ + preempt_disable(); + if (kprobe_running() && + kprobe_fault_handler(args->regs, args->trapnr)) ret = NOTIFY_STOP; + preempt_enable(); break; default: break; } - - if (regs->psw.mask & (PSW_MASK_IO | PSW_MASK_EXT)) - local_irq_restore(regs->psw.mask & ~PSW_MASK_PER); - return ret; } @@ -630,7 +595,6 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) /* setup return addr to the jprobe handler routine */ regs->psw.addr = (unsigned long)(jp->entry) | PSW_ADDR_AMODE; - regs->psw.mask &= ~(PSW_MASK_IO | PSW_MASK_EXT); /* r14 is the function return address */ kcb->jprobe_saved_r14 = (unsigned long)regs->gprs[14]; diff --git a/trunk/arch/s390/mm/gup.c b/trunk/arch/s390/mm/gup.c index 45b405ca2567..38e641cdd977 100644 --- a/trunk/arch/s390/mm/gup.c +++ b/trunk/arch/s390/mm/gup.c @@ -20,17 +20,18 @@ static inline int gup_pte_range(pmd_t *pmdp, pmd_t pmd, unsigned long addr, unsigned long end, int write, struct page **pages, int *nr) { - unsigned long mask; + unsigned long mask, result; pte_t *ptep, pte; struct page *page; - mask = (write ? _PAGE_RO : 0) | _PAGE_INVALID | _PAGE_SPECIAL; + result = write ? 0 : _PAGE_RO; + mask = result | _PAGE_INVALID | _PAGE_SPECIAL; ptep = ((pte_t *) pmd_deref(pmd)) + pte_index(addr); do { pte = *ptep; barrier(); - if ((pte_val(pte) & mask) != 0) + if ((pte_val(pte) & mask) != result) return 0; VM_BUG_ON(!pfn_valid(pte_pfn(pte))); page = pte_page(pte); diff --git a/trunk/drivers/pci/pci-sysfs.c b/trunk/drivers/pci/pci-sysfs.c index 95712a375cd5..63d5042f2079 100644 --- a/trunk/drivers/pci/pci-sysfs.c +++ b/trunk/drivers/pci/pci-sysfs.c @@ -715,7 +715,7 @@ int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma, nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; start = vma->vm_pgoff; size = ((pci_resource_len(pdev, resno) - 1) >> PAGE_SHIFT) + 1; - pci_start = (mmap_api == PCI_MMAP_SYSFS) ? + pci_start = (mmap_api == PCI_MMAP_PROCFS) ? pci_resource_start(pdev, resno) >> PAGE_SHIFT : 0; if (start >= pci_start && start < pci_start + size && start + nr <= pci_start + size) diff --git a/trunk/drivers/s390/char/tape_core.c b/trunk/drivers/s390/char/tape_core.c index b3a3e8e8656e..6c408670e08d 100644 --- a/trunk/drivers/s390/char/tape_core.c +++ b/trunk/drivers/s390/char/tape_core.c @@ -209,79 +209,29 @@ tape_state_set(struct tape_device *device, enum tape_state newstate) wake_up(&device->state_change_wq); } -struct tape_med_state_work_data { - struct tape_device *device; - enum tape_medium_state state; - struct work_struct work; -}; - -static void -tape_med_state_work_handler(struct work_struct *work) -{ - static char env_state_loaded[] = "MEDIUM_STATE=LOADED"; - static char env_state_unloaded[] = "MEDIUM_STATE=UNLOADED"; - struct tape_med_state_work_data *p = - container_of(work, struct tape_med_state_work_data, work); - struct tape_device *device = p->device; - char *envp[] = { NULL, NULL }; - - switch (p->state) { - case MS_UNLOADED: - pr_info("%s: The tape cartridge has been successfully " - "unloaded\n", dev_name(&device->cdev->dev)); - envp[0] = env_state_unloaded; - kobject_uevent_env(&device->cdev->dev.kobj, KOBJ_CHANGE, envp); - break; - case MS_LOADED: - pr_info("%s: A tape cartridge has been mounted\n", - dev_name(&device->cdev->dev)); - envp[0] = env_state_loaded; - kobject_uevent_env(&device->cdev->dev.kobj, KOBJ_CHANGE, envp); - break; - default: - break; - } - tape_put_device(device); - kfree(p); -} - -static void -tape_med_state_work(struct tape_device *device, enum tape_medium_state state) -{ - struct tape_med_state_work_data *p; - - p = kzalloc(sizeof(*p), GFP_ATOMIC); - if (p) { - INIT_WORK(&p->work, tape_med_state_work_handler); - p->device = tape_get_device(device); - p->state = state; - schedule_work(&p->work); - } -} - void tape_med_state_set(struct tape_device *device, enum tape_medium_state newstate) { - enum tape_medium_state oldstate; - - oldstate = device->medium_state; - if (oldstate == newstate) + if (device->medium_state == newstate) return; - device->medium_state = newstate; switch(newstate){ case MS_UNLOADED: device->tape_generic_status |= GMT_DR_OPEN(~0); - if (oldstate == MS_LOADED) - tape_med_state_work(device, MS_UNLOADED); + if (device->medium_state == MS_LOADED) + pr_info("%s: The tape cartridge has been successfully " + "unloaded\n", dev_name(&device->cdev->dev)); break; case MS_LOADED: device->tape_generic_status &= ~GMT_DR_OPEN(~0); - if (oldstate == MS_UNLOADED) - tape_med_state_work(device, MS_LOADED); + if (device->medium_state == MS_UNLOADED) + pr_info("%s: A tape cartridge has been mounted\n", + dev_name(&device->cdev->dev)); break; default: + // print nothing break; } + device->medium_state = newstate; wake_up(&device->state_change_wq); } diff --git a/trunk/drivers/s390/char/vmlogrdr.c b/trunk/drivers/s390/char/vmlogrdr.c index 1cc726b98ec8..9f661426e4a1 100644 --- a/trunk/drivers/s390/char/vmlogrdr.c +++ b/trunk/drivers/s390/char/vmlogrdr.c @@ -249,25 +249,27 @@ static int vmlogrdr_recording(struct vmlogrdr_priv_t * logptr, char cp_command[80]; char cp_response[160]; char *onoff, *qid_string; - int rc; - onoff = ((action == 1) ? "ON" : "OFF"); + memset(cp_command, 0x00, sizeof(cp_command)); + memset(cp_response, 0x00, sizeof(cp_response)); + + onoff = ((action == 1) ? "ON" : "OFF"); qid_string = ((recording_class_AB == 1) ? " QID * " : ""); - /* + /* * The recording commands needs to be called with option QID * for guests that have previlege classes A or B. * Purging has to be done as separate step, because recording * can't be switched on as long as records are on the queue. * Doing both at the same time doesn't work. */ - if (purge && (action == 1)) { - memset(cp_command, 0x00, sizeof(cp_command)); - memset(cp_response, 0x00, sizeof(cp_response)); + + if (purge) { snprintf(cp_command, sizeof(cp_command), "RECORDING %s PURGE %s", logptr->recording_name, qid_string); + cpcmd(cp_command, cp_response, sizeof(cp_response), NULL); } @@ -277,33 +279,19 @@ static int vmlogrdr_recording(struct vmlogrdr_priv_t * logptr, logptr->recording_name, onoff, qid_string); + cpcmd(cp_command, cp_response, sizeof(cp_response), NULL); /* The recording command will usually answer with 'Command complete' * on success, but when the specific service was never connected * before then there might be an additional informational message * 'HCPCRC8072I Recording entry not found' before the - * 'Command complete'. So I use strstr rather then the strncmp. + * 'Command complete'. So I use strstr rather then the strncmp. */ if (strstr(cp_response,"Command complete")) - rc = 0; + return 0; else - rc = -EIO; - /* - * If we turn recording off, we have to purge any remaining records - * afterwards, as a large number of queued records may impact z/VM - * performance. - */ - if (purge && (action == 0)) { - memset(cp_command, 0x00, sizeof(cp_command)); - memset(cp_response, 0x00, sizeof(cp_response)); - snprintf(cp_command, sizeof(cp_command), - "RECORDING %s PURGE %s", - logptr->recording_name, - qid_string); - cpcmd(cp_command, cp_response, sizeof(cp_response), NULL); - } + return -EIO; - return rc; } diff --git a/trunk/drivers/s390/cio/device.c b/trunk/drivers/s390/cio/device.c index e8391b89eff4..2ff8a22d4257 100644 --- a/trunk/drivers/s390/cio/device.c +++ b/trunk/drivers/s390/cio/device.c @@ -1455,16 +1455,7 @@ static int io_subchannel_sch_event(struct subchannel *sch, int process) break; case IO_SCH_UNREG_ATTACH: case IO_SCH_UNREG: - if (!cdev) - break; - if (cdev->private->state == DEV_STATE_SENSE_ID) { - /* - * Note: delayed work triggered by this event - * and repeated calls to sch_event are synchronized - * by the above check for work_pending(cdev). - */ - dev_fsm_event(cdev, DEV_EVENT_NOTOPER); - } else + if (cdev) ccw_device_set_notoper(cdev); break; case IO_SCH_NOP: diff --git a/trunk/kernel/sysctl.c b/trunk/kernel/sysctl.c index 5abfa1518554..b65bf634035e 100644 --- a/trunk/kernel/sysctl.c +++ b/trunk/kernel/sysctl.c @@ -702,6 +702,7 @@ static struct ctl_table kern_table[] = { .extra1 = &zero, .extra2 = &ten_thousand, }, +#endif { .procname = "dmesg_restrict", .data = &dmesg_restrict, @@ -711,7 +712,6 @@ static struct ctl_table kern_table[] = { .extra1 = &zero, .extra2 = &one, }, -#endif { .procname = "ngroups_max", .data = &ngroups_max, diff --git a/trunk/kernel/trace/Kconfig b/trunk/kernel/trace/Kconfig index ea37e2ff4164..e04b8bcdef88 100644 --- a/trunk/kernel/trace/Kconfig +++ b/trunk/kernel/trace/Kconfig @@ -126,7 +126,7 @@ if FTRACE config FUNCTION_TRACER bool "Kernel Function Tracer" depends on HAVE_FUNCTION_TRACER - select FRAME_POINTER if !ARM_UNWIND && !S390 + select FRAME_POINTER if (!ARM_UNWIND) select KALLSYMS select GENERIC_TRACER select CONTEXT_SWITCH_TRACER