diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-07-21 14:18:31 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-07-21 14:18:31 -0400 |
commit | 80d6191ea7e96017ab607843c63a215d5f2f8a58 (patch) | |
tree | 4309b338fae5a22ae25d63524d5f7ad37a1b8004 | |
parent | 9a3c4145af32125c5ee39c0272662b47307a8323 (diff) | |
parent | 9f86745722d95bc7f855069bd82285bd10dc97ff (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 fixes from Martin Schwidefsky:
"A couple of last minute bug fixes for 3.16, including a fix for ptrace
to close a hole which allowed a user space program to write to the
kernel address space"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux:
s390: fix restore of invalid floating-point-control
s390/zcrypt: improve device probing for zcrypt adapter cards
s390/ptrace: fix PSW mask check
s390/MSI: Use standard mask and unmask funtions
s390/3270: correct size detection with the read-partition command
s390: require mvcos facility, not tod clock steering facility
-rw-r--r-- | arch/s390/include/asm/switch_to.h | 4 | ||||
-rw-r--r-- | arch/s390/kernel/head.S | 6 | ||||
-rw-r--r-- | arch/s390/kernel/ptrace.c | 12 | ||||
-rw-r--r-- | arch/s390/pci/pci.c | 49 | ||||
-rw-r--r-- | drivers/s390/char/raw3270.c | 1 | ||||
-rw-r--r-- | drivers/s390/crypto/ap_bus.c | 9 |
6 files changed, 28 insertions, 53 deletions
diff --git a/arch/s390/include/asm/switch_to.h b/arch/s390/include/asm/switch_to.h index df38c70cd59e..18ea9e3f8142 100644 --- a/arch/s390/include/asm/switch_to.h +++ b/arch/s390/include/asm/switch_to.h | |||
@@ -51,8 +51,8 @@ static inline int restore_fp_ctl(u32 *fpc) | |||
51 | return 0; | 51 | return 0; |
52 | 52 | ||
53 | asm volatile( | 53 | asm volatile( |
54 | "0: lfpc %1\n" | 54 | " lfpc %1\n" |
55 | " la %0,0\n" | 55 | "0: la %0,0\n" |
56 | "1:\n" | 56 | "1:\n" |
57 | EX_TABLE(0b,1b) | 57 | EX_TABLE(0b,1b) |
58 | : "=d" (rc) : "Q" (*fpc), "0" (-EINVAL)); | 58 | : "=d" (rc) : "Q" (*fpc), "0" (-EINVAL)); |
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S index 7ba7d6784510..e88d35d74950 100644 --- a/arch/s390/kernel/head.S +++ b/arch/s390/kernel/head.S | |||
@@ -437,11 +437,11 @@ ENTRY(startup_kdump) | |||
437 | 437 | ||
438 | #if defined(CONFIG_64BIT) | 438 | #if defined(CONFIG_64BIT) |
439 | #if defined(CONFIG_MARCH_ZEC12) | 439 | #if defined(CONFIG_MARCH_ZEC12) |
440 | .long 3, 0xc100efea, 0xf46ce800, 0x00400000 | 440 | .long 3, 0xc100eff2, 0xf46ce800, 0x00400000 |
441 | #elif defined(CONFIG_MARCH_Z196) | 441 | #elif defined(CONFIG_MARCH_Z196) |
442 | .long 2, 0xc100efea, 0xf46c0000 | 442 | .long 2, 0xc100eff2, 0xf46c0000 |
443 | #elif defined(CONFIG_MARCH_Z10) | 443 | #elif defined(CONFIG_MARCH_Z10) |
444 | .long 2, 0xc100efea, 0xf0680000 | 444 | .long 2, 0xc100eff2, 0xf0680000 |
445 | #elif defined(CONFIG_MARCH_Z9_109) | 445 | #elif defined(CONFIG_MARCH_Z9_109) |
446 | .long 1, 0xc100efc2 | 446 | .long 1, 0xc100efc2 |
447 | #elif defined(CONFIG_MARCH_Z990) | 447 | #elif defined(CONFIG_MARCH_Z990) |
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 2d716734b5b1..5dc7ad9e2fbf 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c | |||
@@ -334,9 +334,14 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data) | |||
334 | unsigned long mask = PSW_MASK_USER; | 334 | unsigned long mask = PSW_MASK_USER; |
335 | 335 | ||
336 | mask |= is_ri_task(child) ? PSW_MASK_RI : 0; | 336 | mask |= is_ri_task(child) ? PSW_MASK_RI : 0; |
337 | if ((data & ~mask) != PSW_USER_BITS) | 337 | if ((data ^ PSW_USER_BITS) & ~mask) |
338 | /* Invalid psw mask. */ | ||
339 | return -EINVAL; | ||
340 | if ((data & PSW_MASK_ASC) == PSW_ASC_HOME) | ||
341 | /* Invalid address-space-control bits */ | ||
338 | return -EINVAL; | 342 | return -EINVAL; |
339 | if ((data & PSW_MASK_EA) && !(data & PSW_MASK_BA)) | 343 | if ((data & PSW_MASK_EA) && !(data & PSW_MASK_BA)) |
344 | /* Invalid addressing mode bits */ | ||
340 | return -EINVAL; | 345 | return -EINVAL; |
341 | } | 346 | } |
342 | *(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr) = data; | 347 | *(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr) = data; |
@@ -672,9 +677,12 @@ static int __poke_user_compat(struct task_struct *child, | |||
672 | 677 | ||
673 | mask |= is_ri_task(child) ? PSW32_MASK_RI : 0; | 678 | mask |= is_ri_task(child) ? PSW32_MASK_RI : 0; |
674 | /* Build a 64 bit psw mask from 31 bit mask. */ | 679 | /* Build a 64 bit psw mask from 31 bit mask. */ |
675 | if ((tmp & ~mask) != PSW32_USER_BITS) | 680 | if ((tmp ^ PSW32_USER_BITS) & ~mask) |
676 | /* Invalid psw mask. */ | 681 | /* Invalid psw mask. */ |
677 | return -EINVAL; | 682 | return -EINVAL; |
683 | if ((data & PSW32_MASK_ASC) == PSW32_ASC_HOME) | ||
684 | /* Invalid address-space-control bits */ | ||
685 | return -EINVAL; | ||
678 | regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) | | 686 | regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) | |
679 | (regs->psw.mask & PSW_MASK_BA) | | 687 | (regs->psw.mask & PSW_MASK_BA) | |
680 | (__u64)(tmp & mask) << 32; | 688 | (__u64)(tmp & mask) << 32; |
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index 9ddc51eeb8d6..30de42730b2f 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c | |||
@@ -48,13 +48,10 @@ | |||
48 | static LIST_HEAD(zpci_list); | 48 | static LIST_HEAD(zpci_list); |
49 | static DEFINE_SPINLOCK(zpci_list_lock); | 49 | static DEFINE_SPINLOCK(zpci_list_lock); |
50 | 50 | ||
51 | static void zpci_enable_irq(struct irq_data *data); | ||
52 | static void zpci_disable_irq(struct irq_data *data); | ||
53 | |||
54 | static struct irq_chip zpci_irq_chip = { | 51 | static struct irq_chip zpci_irq_chip = { |
55 | .name = "zPCI", | 52 | .name = "zPCI", |
56 | .irq_unmask = zpci_enable_irq, | 53 | .irq_unmask = unmask_msi_irq, |
57 | .irq_mask = zpci_disable_irq, | 54 | .irq_mask = mask_msi_irq, |
58 | }; | 55 | }; |
59 | 56 | ||
60 | static DECLARE_BITMAP(zpci_domain, ZPCI_NR_DEVICES); | 57 | static DECLARE_BITMAP(zpci_domain, ZPCI_NR_DEVICES); |
@@ -244,43 +241,6 @@ static int zpci_cfg_store(struct zpci_dev *zdev, int offset, u32 val, u8 len) | |||
244 | return rc; | 241 | return rc; |
245 | } | 242 | } |
246 | 243 | ||
247 | static int zpci_msi_set_mask_bits(struct msi_desc *msi, u32 mask, u32 flag) | ||
248 | { | ||
249 | int offset, pos; | ||
250 | u32 mask_bits; | ||
251 | |||
252 | if (msi->msi_attrib.is_msix) { | ||
253 | offset = msi->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + | ||
254 | PCI_MSIX_ENTRY_VECTOR_CTRL; | ||
255 | msi->masked = readl(msi->mask_base + offset); | ||
256 | writel(flag, msi->mask_base + offset); | ||
257 | } else if (msi->msi_attrib.maskbit) { | ||
258 | pos = (long) msi->mask_base; | ||
259 | pci_read_config_dword(msi->dev, pos, &mask_bits); | ||
260 | mask_bits &= ~(mask); | ||
261 | mask_bits |= flag & mask; | ||
262 | pci_write_config_dword(msi->dev, pos, mask_bits); | ||
263 | } else | ||
264 | return 0; | ||
265 | |||
266 | msi->msi_attrib.maskbit = !!flag; | ||
267 | return 1; | ||
268 | } | ||
269 | |||
270 | static void zpci_enable_irq(struct irq_data *data) | ||
271 | { | ||
272 | struct msi_desc *msi = irq_get_msi_desc(data->irq); | ||
273 | |||
274 | zpci_msi_set_mask_bits(msi, 1, 0); | ||
275 | } | ||
276 | |||
277 | static void zpci_disable_irq(struct irq_data *data) | ||
278 | { | ||
279 | struct msi_desc *msi = irq_get_msi_desc(data->irq); | ||
280 | |||
281 | zpci_msi_set_mask_bits(msi, 1, 1); | ||
282 | } | ||
283 | |||
284 | void pcibios_fixup_bus(struct pci_bus *bus) | 244 | void pcibios_fixup_bus(struct pci_bus *bus) |
285 | { | 245 | { |
286 | } | 246 | } |
@@ -487,7 +447,10 @@ void arch_teardown_msi_irqs(struct pci_dev *pdev) | |||
487 | 447 | ||
488 | /* Release MSI interrupts */ | 448 | /* Release MSI interrupts */ |
489 | list_for_each_entry(msi, &pdev->msi_list, list) { | 449 | list_for_each_entry(msi, &pdev->msi_list, list) { |
490 | zpci_msi_set_mask_bits(msi, 1, 1); | 450 | if (msi->msi_attrib.is_msix) |
451 | default_msix_mask_irq(msi, 1); | ||
452 | else | ||
453 | default_msi_mask_irq(msi, 1, 1); | ||
491 | irq_set_msi_desc(msi->irq, NULL); | 454 | irq_set_msi_desc(msi->irq, NULL); |
492 | irq_free_desc(msi->irq); | 455 | irq_free_desc(msi->irq); |
493 | msi->msg.address_lo = 0; | 456 | msi->msg.address_lo = 0; |
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c index 15b3459f8656..220acb4cbee5 100644 --- a/drivers/s390/char/raw3270.c +++ b/drivers/s390/char/raw3270.c | |||
@@ -633,7 +633,6 @@ raw3270_reset_device_cb(struct raw3270_request *rq, void *data) | |||
633 | } else | 633 | } else |
634 | raw3270_writesf_readpart(rp); | 634 | raw3270_writesf_readpart(rp); |
635 | memset(&rp->init_reset, 0, sizeof(rp->init_reset)); | 635 | memset(&rp->init_reset, 0, sizeof(rp->init_reset)); |
636 | memset(&rp->init_data, 0, sizeof(rp->init_data)); | ||
637 | } | 636 | } |
638 | 637 | ||
639 | static int | 638 | static int |
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 69ef4f8cfac8..4038437ff033 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c | |||
@@ -901,10 +901,15 @@ static int ap_device_probe(struct device *dev) | |||
901 | int rc; | 901 | int rc; |
902 | 902 | ||
903 | ap_dev->drv = ap_drv; | 903 | ap_dev->drv = ap_drv; |
904 | |||
905 | spin_lock_bh(&ap_device_list_lock); | ||
906 | list_add(&ap_dev->list, &ap_device_list); | ||
907 | spin_unlock_bh(&ap_device_list_lock); | ||
908 | |||
904 | rc = ap_drv->probe ? ap_drv->probe(ap_dev) : -ENODEV; | 909 | rc = ap_drv->probe ? ap_drv->probe(ap_dev) : -ENODEV; |
905 | if (!rc) { | 910 | if (rc) { |
906 | spin_lock_bh(&ap_device_list_lock); | 911 | spin_lock_bh(&ap_device_list_lock); |
907 | list_add(&ap_dev->list, &ap_device_list); | 912 | list_del_init(&ap_dev->list); |
908 | spin_unlock_bh(&ap_device_list_lock); | 913 | spin_unlock_bh(&ap_device_list_lock); |
909 | } | 914 | } |
910 | return rc; | 915 | return rc; |