Commit dc8a64ee authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux

Pull s390 fixes from Martin Schwidefsky:
 - A proper fix for the locking issue in the dasd driver
 - Wire up the new preadv2 nad pwritev2 system calls
 - Add the mark_rodata_ro function and set DEBUG_RODATA=y
 - A few more bug fixes.

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux:
  s390: wire up preadv2/pwritev2 syscalls
  s390/pci: PCI function group 0 is valid for clp_query_pci_fn
  s390/crypto: provide correct file mode at device register.
  s390/mm: handle PTE-mapped tail pages in fast gup
  s390: add DEBUG_RODATA support
  s390: disable postinit-readonly for now
  s390/dasd: reorder lcu and device lock
  s390/cpum_sf: Fix cpu hotplug notifier transitions
  s390/cpum_cf: Fix missing cpu hotplug notifier transition
parents c05c2ec9 3358999a
...@@ -59,6 +59,9 @@ config PCI_QUIRKS ...@@ -59,6 +59,9 @@ config PCI_QUIRKS
config ARCH_SUPPORTS_UPROBES config ARCH_SUPPORTS_UPROBES
def_bool y def_bool y
config DEBUG_RODATA
def_bool y
config S390 config S390
def_bool y def_bool y
select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
......
...@@ -669,11 +669,13 @@ static const struct file_operations prng_tdes_fops = { ...@@ -669,11 +669,13 @@ static const struct file_operations prng_tdes_fops = {
static struct miscdevice prng_sha512_dev = { static struct miscdevice prng_sha512_dev = {
.name = "prandom", .name = "prandom",
.minor = MISC_DYNAMIC_MINOR, .minor = MISC_DYNAMIC_MINOR,
.mode = 0644,
.fops = &prng_sha512_fops, .fops = &prng_sha512_fops,
}; };
static struct miscdevice prng_tdes_dev = { static struct miscdevice prng_tdes_dev = {
.name = "prandom", .name = "prandom",
.minor = MISC_DYNAMIC_MINOR, .minor = MISC_DYNAMIC_MINOR,
.mode = 0644,
.fops = &prng_tdes_fops, .fops = &prng_tdes_fops,
}; };
......
...@@ -15,4 +15,7 @@ ...@@ -15,4 +15,7 @@
#define __read_mostly __attribute__((__section__(".data..read_mostly"))) #define __read_mostly __attribute__((__section__(".data..read_mostly")))
/* Read-only memory is marked before mark_rodata_ro() is called. */
#define __ro_after_init __read_mostly
#endif #endif
...@@ -311,7 +311,9 @@ ...@@ -311,7 +311,9 @@
#define __NR_shutdown 373 #define __NR_shutdown 373
#define __NR_mlock2 374 #define __NR_mlock2 374
#define __NR_copy_file_range 375 #define __NR_copy_file_range 375
#define NR_syscalls 376 #define __NR_preadv2 376
#define __NR_pwritev2 377
#define NR_syscalls 378
/* /*
* There are some system calls that are not present on 64 bit, some * There are some system calls that are not present on 64 bit, some
......
...@@ -670,6 +670,7 @@ static int cpumf_pmu_notifier(struct notifier_block *self, unsigned long action, ...@@ -670,6 +670,7 @@ static int cpumf_pmu_notifier(struct notifier_block *self, unsigned long action,
switch (action & ~CPU_TASKS_FROZEN) { switch (action & ~CPU_TASKS_FROZEN) {
case CPU_ONLINE: case CPU_ONLINE:
case CPU_DOWN_FAILED:
flags = PMC_INIT; flags = PMC_INIT;
smp_call_function_single(cpu, setup_pmc_cpu, &flags, 1); smp_call_function_single(cpu, setup_pmc_cpu, &flags, 1);
break; break;
......
...@@ -1521,7 +1521,7 @@ static int cpumf_pmu_notifier(struct notifier_block *self, ...@@ -1521,7 +1521,7 @@ static int cpumf_pmu_notifier(struct notifier_block *self,
switch (action & ~CPU_TASKS_FROZEN) { switch (action & ~CPU_TASKS_FROZEN) {
case CPU_ONLINE: case CPU_ONLINE:
case CPU_ONLINE_FROZEN: case CPU_DOWN_FAILED:
flags = PMC_INIT; flags = PMC_INIT;
smp_call_function_single(cpu, setup_pmc_cpu, &flags, 1); smp_call_function_single(cpu, setup_pmc_cpu, &flags, 1);
break; break;
......
...@@ -384,3 +384,5 @@ SYSCALL(sys_recvmsg,compat_sys_recvmsg) ...@@ -384,3 +384,5 @@ SYSCALL(sys_recvmsg,compat_sys_recvmsg)
SYSCALL(sys_shutdown,sys_shutdown) SYSCALL(sys_shutdown,sys_shutdown)
SYSCALL(sys_mlock2,compat_sys_mlock2) SYSCALL(sys_mlock2,compat_sys_mlock2)
SYSCALL(sys_copy_file_range,compat_sys_copy_file_range) /* 375 */ SYSCALL(sys_copy_file_range,compat_sys_copy_file_range) /* 375 */
SYSCALL(sys_preadv2,compat_sys_preadv2)
SYSCALL(sys_pwritev2,compat_sys_pwritev2)
...@@ -20,9 +20,9 @@ ...@@ -20,9 +20,9 @@
static inline int gup_pte_range(pmd_t *pmdp, pmd_t pmd, unsigned long addr, 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 end, int write, struct page **pages, int *nr)
{ {
struct page *head, *page;
unsigned long mask; unsigned long mask;
pte_t *ptep, pte; pte_t *ptep, pte;
struct page *page;
mask = (write ? _PAGE_PROTECT : 0) | _PAGE_INVALID | _PAGE_SPECIAL; mask = (write ? _PAGE_PROTECT : 0) | _PAGE_INVALID | _PAGE_SPECIAL;
...@@ -37,12 +37,14 @@ static inline int gup_pte_range(pmd_t *pmdp, pmd_t pmd, unsigned long addr, ...@@ -37,12 +37,14 @@ static inline int gup_pte_range(pmd_t *pmdp, pmd_t pmd, unsigned long addr,
return 0; return 0;
VM_BUG_ON(!pfn_valid(pte_pfn(pte))); VM_BUG_ON(!pfn_valid(pte_pfn(pte)));
page = pte_page(pte); page = pte_page(pte);
if (!page_cache_get_speculative(page)) head = compound_head(page);
if (!page_cache_get_speculative(head))
return 0; return 0;
if (unlikely(pte_val(pte) != pte_val(*ptep))) { if (unlikely(pte_val(pte) != pte_val(*ptep))) {
put_page(page); put_page(head);
return 0; return 0;
} }
VM_BUG_ON_PAGE(compound_head(page) != head, page);
pages[*nr] = page; pages[*nr] = page;
(*nr)++; (*nr)++;
......
...@@ -108,6 +108,13 @@ void __init paging_init(void) ...@@ -108,6 +108,13 @@ void __init paging_init(void)
free_area_init_nodes(max_zone_pfns); free_area_init_nodes(max_zone_pfns);
} }
void mark_rodata_ro(void)
{
/* Text and rodata are already protected. Nothing to do here. */
pr_info("Write protecting the kernel read-only data: %luk\n",
((unsigned long)&_eshared - (unsigned long)&_stext) >> 10);
}
void __init mem_init(void) void __init mem_init(void)
{ {
if (MACHINE_HAS_TLB_LC) if (MACHINE_HAS_TLB_LC)
...@@ -126,9 +133,6 @@ void __init mem_init(void) ...@@ -126,9 +133,6 @@ void __init mem_init(void)
setup_zero_pages(); /* Setup zeroed pages. */ setup_zero_pages(); /* Setup zeroed pages. */
mem_init_print_info(NULL); mem_init_print_info(NULL);
printk("Write protected kernel read-only data: %#lx - %#lx\n",
(unsigned long)&_stext,
PFN_ALIGN((unsigned long)&_eshared) - 1);
} }
void free_initmem(void) void free_initmem(void)
......
...@@ -176,8 +176,7 @@ static int clp_query_pci_fn(struct zpci_dev *zdev, u32 fh) ...@@ -176,8 +176,7 @@ static int clp_query_pci_fn(struct zpci_dev *zdev, u32 fh)
rc = clp_store_query_pci_fn(zdev, &rrb->response); rc = clp_store_query_pci_fn(zdev, &rrb->response);
if (rc) if (rc)
goto out; goto out;
if (rrb->response.pfgid) rc = clp_query_pci_fngrp(zdev, rrb->response.pfgid);
rc = clp_query_pci_fngrp(zdev, rrb->response.pfgid);
} else { } else {
zpci_err("Q PCI FN:\n"); zpci_err("Q PCI FN:\n");
zpci_err_clp(rrb->response.hdr.rsp, rc); zpci_err_clp(rrb->response.hdr.rsp, rc);
......
This diff is collapsed.
...@@ -1682,6 +1682,8 @@ dasd_eckd_check_characteristics(struct dasd_device *device) ...@@ -1682,6 +1682,8 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
/* setup work queue for validate server*/ /* setup work queue for validate server*/
INIT_WORK(&device->kick_validate, dasd_eckd_do_validate_server); INIT_WORK(&device->kick_validate, dasd_eckd_do_validate_server);
/* setup work queue for summary unit check */
INIT_WORK(&device->suc_work, dasd_alias_handle_summary_unit_check);
if (!ccw_device_is_pathgroup(device->cdev)) { if (!ccw_device_is_pathgroup(device->cdev)) {
dev_warn(&device->cdev->dev, dev_warn(&device->cdev->dev,
...@@ -2549,14 +2551,6 @@ static void dasd_eckd_check_for_device_change(struct dasd_device *device, ...@@ -2549,14 +2551,6 @@ static void dasd_eckd_check_for_device_change(struct dasd_device *device,
device->state == DASD_STATE_ONLINE && device->state == DASD_STATE_ONLINE &&
!test_bit(DASD_FLAG_OFFLINE, &device->flags) && !test_bit(DASD_FLAG_OFFLINE, &device->flags) &&
!test_bit(DASD_FLAG_SUSPENDED, &device->flags)) { !test_bit(DASD_FLAG_SUSPENDED, &device->flags)) {
/*
* the state change could be caused by an alias
* reassignment remove device from alias handling
* to prevent new requests from being scheduled on
* the wrong alias device
*/
dasd_alias_remove_device(device);
/* schedule worker to reload device */ /* schedule worker to reload device */
dasd_reload_device(device); dasd_reload_device(device);
} }
...@@ -2571,7 +2565,27 @@ static void dasd_eckd_check_for_device_change(struct dasd_device *device, ...@@ -2571,7 +2565,27 @@ static void dasd_eckd_check_for_device_change(struct dasd_device *device,
/* summary unit check */ /* summary unit check */
if ((sense[27] & DASD_SENSE_BIT_0) && (sense[7] == 0x0D) && if ((sense[27] & DASD_SENSE_BIT_0) && (sense[7] == 0x0D) &&
(scsw_dstat(&irb->scsw) & DEV_STAT_UNIT_CHECK)) { (scsw_dstat(&irb->scsw) & DEV_STAT_UNIT_CHECK)) {
dasd_alias_handle_summary_unit_check(device, irb); if (test_and_set_bit(DASD_FLAG_SUC, &device->flags)) {
DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"eckd suc: device already notified");
return;
}
sense = dasd_get_sense(irb);
if (!sense) {
DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"eckd suc: no reason code available");
clear_bit(DASD_FLAG_SUC, &device->flags);
return;
}
private->suc_reason = sense[8];
DBF_DEV_EVENT(DBF_NOTICE, device, "%s %x",
"eckd handle summary unit check: reason",
private->suc_reason);
dasd_get_device(device);
if (!schedule_work(&device->suc_work))
dasd_put_device(device);
return; return;
} }
...@@ -4495,6 +4509,12 @@ static int dasd_eckd_reload_device(struct dasd_device *device) ...@@ -4495,6 +4509,12 @@ static int dasd_eckd_reload_device(struct dasd_device *device)
struct dasd_uid uid; struct dasd_uid uid;
unsigned long flags; unsigned long flags;
/*
* remove device from alias handling to prevent new requests
* from being scheduled on the wrong alias device
*/
dasd_alias_remove_device(device);
spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
old_base = private->uid.base_unit_addr; old_base = private->uid.base_unit_addr;
spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
......
...@@ -525,6 +525,7 @@ struct dasd_eckd_private { ...@@ -525,6 +525,7 @@ struct dasd_eckd_private {
int count; int count;
u32 fcx_max_data; u32 fcx_max_data;
char suc_reason;
}; };
...@@ -534,7 +535,7 @@ void dasd_alias_disconnect_device_from_lcu(struct dasd_device *); ...@@ -534,7 +535,7 @@ void dasd_alias_disconnect_device_from_lcu(struct dasd_device *);
int dasd_alias_add_device(struct dasd_device *); int dasd_alias_add_device(struct dasd_device *);
int dasd_alias_remove_device(struct dasd_device *); int dasd_alias_remove_device(struct dasd_device *);
struct dasd_device *dasd_alias_get_start_dev(struct dasd_device *); struct dasd_device *dasd_alias_get_start_dev(struct dasd_device *);
void dasd_alias_handle_summary_unit_check(struct dasd_device *, struct irb *); void dasd_alias_handle_summary_unit_check(struct work_struct *);
void dasd_eckd_reset_ccw_to_base_io(struct dasd_ccw_req *); void dasd_eckd_reset_ccw_to_base_io(struct dasd_ccw_req *);
void dasd_alias_lcu_setup_complete(struct dasd_device *); void dasd_alias_lcu_setup_complete(struct dasd_device *);
void dasd_alias_wait_for_lcu_setup(struct dasd_device *); void dasd_alias_wait_for_lcu_setup(struct dasd_device *);
......
...@@ -470,6 +470,7 @@ struct dasd_device { ...@@ -470,6 +470,7 @@ struct dasd_device {
struct work_struct restore_device; struct work_struct restore_device;
struct work_struct reload_device; struct work_struct reload_device;
struct work_struct kick_validate; struct work_struct kick_validate;
struct work_struct suc_work;
struct timer_list timer; struct timer_list timer;
debug_info_t *debug_area; debug_info_t *debug_area;
...@@ -542,6 +543,7 @@ struct dasd_attention_data { ...@@ -542,6 +543,7 @@ struct dasd_attention_data {
#define DASD_FLAG_SAFE_OFFLINE_RUNNING 11 /* safe offline running */ #define DASD_FLAG_SAFE_OFFLINE_RUNNING 11 /* safe offline running */
#define DASD_FLAG_ABORTALL 12 /* Abort all noretry requests */ #define DASD_FLAG_ABORTALL 12 /* Abort all noretry requests */
#define DASD_FLAG_PATH_VERIFY 13 /* Path verification worker running */ #define DASD_FLAG_PATH_VERIFY 13 /* Path verification worker running */
#define DASD_FLAG_SUC 14 /* unhandled summary unit check */
#define DASD_SLEEPON_START_TAG ((void *) 1) #define DASD_SLEEPON_START_TAG ((void *) 1)
#define DASD_SLEEPON_END_TAG ((void *) 2) #define DASD_SLEEPON_END_TAG ((void *) 2)
......
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