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
This commit is contained in:
commit
80d6191ea7
6 changed files with 28 additions and 53 deletions
|
@ -51,8 +51,8 @@ static inline int restore_fp_ctl(u32 *fpc)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
asm volatile(
|
asm volatile(
|
||||||
"0: lfpc %1\n"
|
" lfpc %1\n"
|
||||||
" la %0,0\n"
|
"0: la %0,0\n"
|
||||||
"1:\n"
|
"1:\n"
|
||||||
EX_TABLE(0b,1b)
|
EX_TABLE(0b,1b)
|
||||||
: "=d" (rc) : "Q" (*fpc), "0" (-EINVAL));
|
: "=d" (rc) : "Q" (*fpc), "0" (-EINVAL));
|
||||||
|
|
|
@ -437,11 +437,11 @@ ENTRY(startup_kdump)
|
||||||
|
|
||||||
#if defined(CONFIG_64BIT)
|
#if defined(CONFIG_64BIT)
|
||||||
#if defined(CONFIG_MARCH_ZEC12)
|
#if defined(CONFIG_MARCH_ZEC12)
|
||||||
.long 3, 0xc100efea, 0xf46ce800, 0x00400000
|
.long 3, 0xc100eff2, 0xf46ce800, 0x00400000
|
||||||
#elif defined(CONFIG_MARCH_Z196)
|
#elif defined(CONFIG_MARCH_Z196)
|
||||||
.long 2, 0xc100efea, 0xf46c0000
|
.long 2, 0xc100eff2, 0xf46c0000
|
||||||
#elif defined(CONFIG_MARCH_Z10)
|
#elif defined(CONFIG_MARCH_Z10)
|
||||||
.long 2, 0xc100efea, 0xf0680000
|
.long 2, 0xc100eff2, 0xf0680000
|
||||||
#elif defined(CONFIG_MARCH_Z9_109)
|
#elif defined(CONFIG_MARCH_Z9_109)
|
||||||
.long 1, 0xc100efc2
|
.long 1, 0xc100efc2
|
||||||
#elif defined(CONFIG_MARCH_Z990)
|
#elif defined(CONFIG_MARCH_Z990)
|
||||||
|
|
|
@ -334,9 +334,14 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data)
|
||||||
unsigned long mask = PSW_MASK_USER;
|
unsigned long mask = PSW_MASK_USER;
|
||||||
|
|
||||||
mask |= is_ri_task(child) ? PSW_MASK_RI : 0;
|
mask |= is_ri_task(child) ? PSW_MASK_RI : 0;
|
||||||
if ((data & ~mask) != PSW_USER_BITS)
|
if ((data ^ PSW_USER_BITS) & ~mask)
|
||||||
|
/* Invalid psw mask. */
|
||||||
|
return -EINVAL;
|
||||||
|
if ((data & PSW_MASK_ASC) == PSW_ASC_HOME)
|
||||||
|
/* Invalid address-space-control bits */
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if ((data & PSW_MASK_EA) && !(data & PSW_MASK_BA))
|
if ((data & PSW_MASK_EA) && !(data & PSW_MASK_BA))
|
||||||
|
/* Invalid addressing mode bits */
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
*(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr) = data;
|
*(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr) = data;
|
||||||
|
@ -672,9 +677,12 @@ static int __poke_user_compat(struct task_struct *child,
|
||||||
|
|
||||||
mask |= is_ri_task(child) ? PSW32_MASK_RI : 0;
|
mask |= is_ri_task(child) ? PSW32_MASK_RI : 0;
|
||||||
/* Build a 64 bit psw mask from 31 bit mask. */
|
/* Build a 64 bit psw mask from 31 bit mask. */
|
||||||
if ((tmp & ~mask) != PSW32_USER_BITS)
|
if ((tmp ^ PSW32_USER_BITS) & ~mask)
|
||||||
/* Invalid psw mask. */
|
/* Invalid psw mask. */
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
if ((data & PSW32_MASK_ASC) == PSW32_ASC_HOME)
|
||||||
|
/* Invalid address-space-control bits */
|
||||||
|
return -EINVAL;
|
||||||
regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) |
|
regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) |
|
||||||
(regs->psw.mask & PSW_MASK_BA) |
|
(regs->psw.mask & PSW_MASK_BA) |
|
||||||
(__u64)(tmp & mask) << 32;
|
(__u64)(tmp & mask) << 32;
|
||||||
|
|
|
@ -48,13 +48,10 @@
|
||||||
static LIST_HEAD(zpci_list);
|
static LIST_HEAD(zpci_list);
|
||||||
static DEFINE_SPINLOCK(zpci_list_lock);
|
static DEFINE_SPINLOCK(zpci_list_lock);
|
||||||
|
|
||||||
static void zpci_enable_irq(struct irq_data *data);
|
|
||||||
static void zpci_disable_irq(struct irq_data *data);
|
|
||||||
|
|
||||||
static struct irq_chip zpci_irq_chip = {
|
static struct irq_chip zpci_irq_chip = {
|
||||||
.name = "zPCI",
|
.name = "zPCI",
|
||||||
.irq_unmask = zpci_enable_irq,
|
.irq_unmask = unmask_msi_irq,
|
||||||
.irq_mask = zpci_disable_irq,
|
.irq_mask = mask_msi_irq,
|
||||||
};
|
};
|
||||||
|
|
||||||
static DECLARE_BITMAP(zpci_domain, ZPCI_NR_DEVICES);
|
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)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int zpci_msi_set_mask_bits(struct msi_desc *msi, u32 mask, u32 flag)
|
|
||||||
{
|
|
||||||
int offset, pos;
|
|
||||||
u32 mask_bits;
|
|
||||||
|
|
||||||
if (msi->msi_attrib.is_msix) {
|
|
||||||
offset = msi->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
|
|
||||||
PCI_MSIX_ENTRY_VECTOR_CTRL;
|
|
||||||
msi->masked = readl(msi->mask_base + offset);
|
|
||||||
writel(flag, msi->mask_base + offset);
|
|
||||||
} else if (msi->msi_attrib.maskbit) {
|
|
||||||
pos = (long) msi->mask_base;
|
|
||||||
pci_read_config_dword(msi->dev, pos, &mask_bits);
|
|
||||||
mask_bits &= ~(mask);
|
|
||||||
mask_bits |= flag & mask;
|
|
||||||
pci_write_config_dword(msi->dev, pos, mask_bits);
|
|
||||||
} else
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
msi->msi_attrib.maskbit = !!flag;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void zpci_enable_irq(struct irq_data *data)
|
|
||||||
{
|
|
||||||
struct msi_desc *msi = irq_get_msi_desc(data->irq);
|
|
||||||
|
|
||||||
zpci_msi_set_mask_bits(msi, 1, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void zpci_disable_irq(struct irq_data *data)
|
|
||||||
{
|
|
||||||
struct msi_desc *msi = irq_get_msi_desc(data->irq);
|
|
||||||
|
|
||||||
zpci_msi_set_mask_bits(msi, 1, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void pcibios_fixup_bus(struct pci_bus *bus)
|
void pcibios_fixup_bus(struct pci_bus *bus)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -487,7 +447,10 @@ void arch_teardown_msi_irqs(struct pci_dev *pdev)
|
||||||
|
|
||||||
/* Release MSI interrupts */
|
/* Release MSI interrupts */
|
||||||
list_for_each_entry(msi, &pdev->msi_list, list) {
|
list_for_each_entry(msi, &pdev->msi_list, list) {
|
||||||
zpci_msi_set_mask_bits(msi, 1, 1);
|
if (msi->msi_attrib.is_msix)
|
||||||
|
default_msix_mask_irq(msi, 1);
|
||||||
|
else
|
||||||
|
default_msi_mask_irq(msi, 1, 1);
|
||||||
irq_set_msi_desc(msi->irq, NULL);
|
irq_set_msi_desc(msi->irq, NULL);
|
||||||
irq_free_desc(msi->irq);
|
irq_free_desc(msi->irq);
|
||||||
msi->msg.address_lo = 0;
|
msi->msg.address_lo = 0;
|
||||||
|
|
|
@ -633,7 +633,6 @@ raw3270_reset_device_cb(struct raw3270_request *rq, void *data)
|
||||||
} else
|
} else
|
||||||
raw3270_writesf_readpart(rp);
|
raw3270_writesf_readpart(rp);
|
||||||
memset(&rp->init_reset, 0, sizeof(rp->init_reset));
|
memset(&rp->init_reset, 0, sizeof(rp->init_reset));
|
||||||
memset(&rp->init_data, 0, sizeof(rp->init_data));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
|
@ -901,10 +901,15 @@ static int ap_device_probe(struct device *dev)
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
ap_dev->drv = ap_drv;
|
ap_dev->drv = ap_drv;
|
||||||
|
|
||||||
|
spin_lock_bh(&ap_device_list_lock);
|
||||||
|
list_add(&ap_dev->list, &ap_device_list);
|
||||||
|
spin_unlock_bh(&ap_device_list_lock);
|
||||||
|
|
||||||
rc = ap_drv->probe ? ap_drv->probe(ap_dev) : -ENODEV;
|
rc = ap_drv->probe ? ap_drv->probe(ap_dev) : -ENODEV;
|
||||||
if (!rc) {
|
if (rc) {
|
||||||
spin_lock_bh(&ap_device_list_lock);
|
spin_lock_bh(&ap_device_list_lock);
|
||||||
list_add(&ap_dev->list, &ap_device_list);
|
list_del_init(&ap_dev->list);
|
||||||
spin_unlock_bh(&ap_device_list_lock);
|
spin_unlock_bh(&ap_device_list_lock);
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
|
|
Loading…
Add table
Reference in a new issue