Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 fixes from Martin Schwidefsky: "Just a bunch of bugfixes" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: s390/mm: provide emtpy check_pgt_cache() function s390/uaccess: fix page table walk s390/3270: fix minor_start issue s390/uaccess: fix clear_user_pt() s390/scm_blk: fix error return code in scm_blk_init() s390/scm_block: fix printk format string drivers/Kconfig: add several missing GENERIC_HARDIRQS dependencies
This commit is contained in:
commit
17eb3d8fbe
8 changed files with 81 additions and 45 deletions
|
@ -344,6 +344,7 @@ extern unsigned long MODULES_END;
|
||||||
#define _REGION3_ENTRY_CO 0x100 /* change-recording override */
|
#define _REGION3_ENTRY_CO 0x100 /* change-recording override */
|
||||||
|
|
||||||
/* Bits in the segment table entry */
|
/* Bits in the segment table entry */
|
||||||
|
#define _SEGMENT_ENTRY_ORIGIN_LARGE ~0xfffffUL /* large page address */
|
||||||
#define _SEGMENT_ENTRY_ORIGIN ~0x7ffUL/* segment table origin */
|
#define _SEGMENT_ENTRY_ORIGIN ~0x7ffUL/* segment table origin */
|
||||||
#define _SEGMENT_ENTRY_RO 0x200 /* page protection bit */
|
#define _SEGMENT_ENTRY_RO 0x200 /* page protection bit */
|
||||||
#define _SEGMENT_ENTRY_INV 0x20 /* invalid segment table entry */
|
#define _SEGMENT_ENTRY_INV 0x20 /* invalid segment table entry */
|
||||||
|
@ -1531,7 +1532,8 @@ extern int s390_enable_sie(void);
|
||||||
/*
|
/*
|
||||||
* No page table caches to initialise
|
* No page table caches to initialise
|
||||||
*/
|
*/
|
||||||
#define pgtable_cache_init() do { } while (0)
|
static inline void pgtable_cache_init(void) { }
|
||||||
|
static inline void check_pgt_cache(void) { }
|
||||||
|
|
||||||
#include <asm-generic/pgtable.h>
|
#include <asm-generic/pgtable.h>
|
||||||
|
|
||||||
|
|
|
@ -77,42 +77,69 @@ static size_t copy_in_kernel(size_t count, void __user *to,
|
||||||
* >= -4095 (IS_ERR_VALUE(x) returns true), a fault has occured and the address
|
* >= -4095 (IS_ERR_VALUE(x) returns true), a fault has occured and the address
|
||||||
* contains the (negative) exception code.
|
* contains the (negative) exception code.
|
||||||
*/
|
*/
|
||||||
static __always_inline unsigned long follow_table(struct mm_struct *mm,
|
#ifdef CONFIG_64BIT
|
||||||
unsigned long addr, int write)
|
static unsigned long follow_table(struct mm_struct *mm,
|
||||||
|
unsigned long address, int write)
|
||||||
{
|
{
|
||||||
pgd_t *pgd;
|
unsigned long *table = (unsigned long *)__pa(mm->pgd);
|
||||||
pud_t *pud;
|
|
||||||
pmd_t *pmd;
|
|
||||||
pte_t *ptep;
|
|
||||||
|
|
||||||
pgd = pgd_offset(mm, addr);
|
switch (mm->context.asce_bits & _ASCE_TYPE_MASK) {
|
||||||
if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
|
case _ASCE_TYPE_REGION1:
|
||||||
return -0x3aUL;
|
table = table + ((address >> 53) & 0x7ff);
|
||||||
|
if (unlikely(*table & _REGION_ENTRY_INV))
|
||||||
pud = pud_offset(pgd, addr);
|
return -0x39UL;
|
||||||
if (pud_none(*pud) || unlikely(pud_bad(*pud)))
|
table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN);
|
||||||
return -0x3bUL;
|
case _ASCE_TYPE_REGION2:
|
||||||
|
table = table + ((address >> 42) & 0x7ff);
|
||||||
pmd = pmd_offset(pud, addr);
|
if (unlikely(*table & _REGION_ENTRY_INV))
|
||||||
if (pmd_none(*pmd))
|
return -0x3aUL;
|
||||||
return -0x10UL;
|
table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN);
|
||||||
if (pmd_large(*pmd)) {
|
case _ASCE_TYPE_REGION3:
|
||||||
if (write && (pmd_val(*pmd) & _SEGMENT_ENTRY_RO))
|
table = table + ((address >> 31) & 0x7ff);
|
||||||
return -0x04UL;
|
if (unlikely(*table & _REGION_ENTRY_INV))
|
||||||
return (pmd_val(*pmd) & HPAGE_MASK) + (addr & ~HPAGE_MASK);
|
return -0x3bUL;
|
||||||
|
table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN);
|
||||||
|
case _ASCE_TYPE_SEGMENT:
|
||||||
|
table = table + ((address >> 20) & 0x7ff);
|
||||||
|
if (unlikely(*table & _SEGMENT_ENTRY_INV))
|
||||||
|
return -0x10UL;
|
||||||
|
if (unlikely(*table & _SEGMENT_ENTRY_LARGE)) {
|
||||||
|
if (write && (*table & _SEGMENT_ENTRY_RO))
|
||||||
|
return -0x04UL;
|
||||||
|
return (*table & _SEGMENT_ENTRY_ORIGIN_LARGE) +
|
||||||
|
(address & ~_SEGMENT_ENTRY_ORIGIN_LARGE);
|
||||||
|
}
|
||||||
|
table = (unsigned long *)(*table & _SEGMENT_ENTRY_ORIGIN);
|
||||||
}
|
}
|
||||||
if (unlikely(pmd_bad(*pmd)))
|
table = table + ((address >> 12) & 0xff);
|
||||||
return -0x10UL;
|
if (unlikely(*table & _PAGE_INVALID))
|
||||||
|
|
||||||
ptep = pte_offset_map(pmd, addr);
|
|
||||||
if (!pte_present(*ptep))
|
|
||||||
return -0x11UL;
|
return -0x11UL;
|
||||||
if (write && (!pte_write(*ptep) || !pte_dirty(*ptep)))
|
if (write && (*table & _PAGE_RO))
|
||||||
return -0x04UL;
|
return -0x04UL;
|
||||||
|
return (*table & PAGE_MASK) + (address & ~PAGE_MASK);
|
||||||
return (pte_val(*ptep) & PAGE_MASK) + (addr & ~PAGE_MASK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else /* CONFIG_64BIT */
|
||||||
|
|
||||||
|
static unsigned long follow_table(struct mm_struct *mm,
|
||||||
|
unsigned long address, int write)
|
||||||
|
{
|
||||||
|
unsigned long *table = (unsigned long *)__pa(mm->pgd);
|
||||||
|
|
||||||
|
table = table + ((address >> 20) & 0x7ff);
|
||||||
|
if (unlikely(*table & _SEGMENT_ENTRY_INV))
|
||||||
|
return -0x10UL;
|
||||||
|
table = (unsigned long *)(*table & _SEGMENT_ENTRY_ORIGIN);
|
||||||
|
table = table + ((address >> 12) & 0xff);
|
||||||
|
if (unlikely(*table & _PAGE_INVALID))
|
||||||
|
return -0x11UL;
|
||||||
|
if (write && (*table & _PAGE_RO))
|
||||||
|
return -0x04UL;
|
||||||
|
return (*table & PAGE_MASK) + (address & ~PAGE_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_64BIT */
|
||||||
|
|
||||||
static __always_inline size_t __user_copy_pt(unsigned long uaddr, void *kptr,
|
static __always_inline size_t __user_copy_pt(unsigned long uaddr, void *kptr,
|
||||||
size_t n, int write_user)
|
size_t n, int write_user)
|
||||||
{
|
{
|
||||||
|
@ -197,7 +224,7 @@ size_t copy_to_user_pt(size_t n, void __user *to, const void *from)
|
||||||
|
|
||||||
static size_t clear_user_pt(size_t n, void __user *to)
|
static size_t clear_user_pt(size_t n, void __user *to)
|
||||||
{
|
{
|
||||||
void *zpage = &empty_zero_page;
|
void *zpage = (void *) empty_zero_page;
|
||||||
long done, size, ret;
|
long done, size, ret;
|
||||||
|
|
||||||
done = 0;
|
done = 0;
|
||||||
|
|
|
@ -83,6 +83,7 @@ config INTEL_IOP_ADMA
|
||||||
|
|
||||||
config DW_DMAC
|
config DW_DMAC
|
||||||
tristate "Synopsys DesignWare AHB DMA support"
|
tristate "Synopsys DesignWare AHB DMA support"
|
||||||
|
depends on GENERIC_HARDIRQS
|
||||||
select DMA_ENGINE
|
select DMA_ENGINE
|
||||||
default y if CPU_AT32AP7000
|
default y if CPU_AT32AP7000
|
||||||
help
|
help
|
||||||
|
|
|
@ -204,7 +204,7 @@ config VIDEO_SAMSUNG_EXYNOS_GSC
|
||||||
|
|
||||||
config VIDEO_SH_VEU
|
config VIDEO_SH_VEU
|
||||||
tristate "SuperH VEU mem2mem video processing driver"
|
tristate "SuperH VEU mem2mem video processing driver"
|
||||||
depends on VIDEO_DEV && VIDEO_V4L2
|
depends on VIDEO_DEV && VIDEO_V4L2 && GENERIC_HARDIRQS
|
||||||
select VIDEOBUF2_DMA_CONTIG
|
select VIDEOBUF2_DMA_CONTIG
|
||||||
select V4L2_MEM2MEM_DEV
|
select V4L2_MEM2MEM_DEV
|
||||||
help
|
help
|
||||||
|
|
|
@ -307,7 +307,7 @@ static void scm_blk_handle_error(struct scm_request *scmrq)
|
||||||
case EQC_WR_PROHIBIT:
|
case EQC_WR_PROHIBIT:
|
||||||
spin_lock_irqsave(&bdev->lock, flags);
|
spin_lock_irqsave(&bdev->lock, flags);
|
||||||
if (bdev->state != SCM_WR_PROHIBIT)
|
if (bdev->state != SCM_WR_PROHIBIT)
|
||||||
pr_info("%lu: Write access to the SCM increment is suspended\n",
|
pr_info("%lx: Write access to the SCM increment is suspended\n",
|
||||||
(unsigned long) bdev->scmdev->address);
|
(unsigned long) bdev->scmdev->address);
|
||||||
bdev->state = SCM_WR_PROHIBIT;
|
bdev->state = SCM_WR_PROHIBIT;
|
||||||
spin_unlock_irqrestore(&bdev->lock, flags);
|
spin_unlock_irqrestore(&bdev->lock, flags);
|
||||||
|
@ -445,7 +445,7 @@ void scm_blk_set_available(struct scm_blk_dev *bdev)
|
||||||
|
|
||||||
spin_lock_irqsave(&bdev->lock, flags);
|
spin_lock_irqsave(&bdev->lock, flags);
|
||||||
if (bdev->state == SCM_WR_PROHIBIT)
|
if (bdev->state == SCM_WR_PROHIBIT)
|
||||||
pr_info("%lu: Write access to the SCM increment is restored\n",
|
pr_info("%lx: Write access to the SCM increment is restored\n",
|
||||||
(unsigned long) bdev->scmdev->address);
|
(unsigned long) bdev->scmdev->address);
|
||||||
bdev->state = SCM_OPER;
|
bdev->state = SCM_OPER;
|
||||||
spin_unlock_irqrestore(&bdev->lock, flags);
|
spin_unlock_irqrestore(&bdev->lock, flags);
|
||||||
|
@ -463,12 +463,15 @@ static int __init scm_blk_init(void)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
scm_major = ret;
|
scm_major = ret;
|
||||||
if (scm_alloc_rqs(nr_requests))
|
ret = scm_alloc_rqs(nr_requests);
|
||||||
|
if (ret)
|
||||||
goto out_unreg;
|
goto out_unreg;
|
||||||
|
|
||||||
scm_debug = debug_register("scm_log", 16, 1, 16);
|
scm_debug = debug_register("scm_log", 16, 1, 16);
|
||||||
if (!scm_debug)
|
if (!scm_debug) {
|
||||||
|
ret = -ENOMEM;
|
||||||
goto out_free;
|
goto out_free;
|
||||||
|
}
|
||||||
|
|
||||||
debug_register_view(scm_debug, &debug_hex_ascii_view);
|
debug_register_view(scm_debug, &debug_hex_ascii_view);
|
||||||
debug_set_level(scm_debug, 2);
|
debug_set_level(scm_debug, 2);
|
||||||
|
|
|
@ -19,7 +19,7 @@ static void scm_notify(struct scm_device *scmdev, enum scm_event event)
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case SCM_CHANGE:
|
case SCM_CHANGE:
|
||||||
pr_info("%lu: The capabilities of the SCM increment changed\n",
|
pr_info("%lx: The capabilities of the SCM increment changed\n",
|
||||||
(unsigned long) scmdev->address);
|
(unsigned long) scmdev->address);
|
||||||
SCM_LOG(2, "State changed");
|
SCM_LOG(2, "State changed");
|
||||||
SCM_LOG_STATE(2, scmdev);
|
SCM_LOG_STATE(2, scmdev);
|
||||||
|
|
|
@ -915,7 +915,7 @@ static int tty3270_install(struct tty_driver *driver, struct tty_struct *tty)
|
||||||
int i, rc;
|
int i, rc;
|
||||||
|
|
||||||
/* Check if the tty3270 is already there. */
|
/* Check if the tty3270 is already there. */
|
||||||
view = raw3270_find_view(&tty3270_fn, tty->index);
|
view = raw3270_find_view(&tty3270_fn, tty->index + RAW3270_FIRSTMINOR);
|
||||||
if (!IS_ERR(view)) {
|
if (!IS_ERR(view)) {
|
||||||
tp = container_of(view, struct tty3270, view);
|
tp = container_of(view, struct tty3270, view);
|
||||||
tty->driver_data = tp;
|
tty->driver_data = tp;
|
||||||
|
@ -927,15 +927,16 @@ static int tty3270_install(struct tty_driver *driver, struct tty_struct *tty)
|
||||||
tp->inattr = TF_INPUT;
|
tp->inattr = TF_INPUT;
|
||||||
return tty_port_install(&tp->port, driver, tty);
|
return tty_port_install(&tp->port, driver, tty);
|
||||||
}
|
}
|
||||||
if (tty3270_max_index < tty->index)
|
if (tty3270_max_index < tty->index + 1)
|
||||||
tty3270_max_index = tty->index;
|
tty3270_max_index = tty->index + 1;
|
||||||
|
|
||||||
/* Allocate tty3270 structure on first open. */
|
/* Allocate tty3270 structure on first open. */
|
||||||
tp = tty3270_alloc_view();
|
tp = tty3270_alloc_view();
|
||||||
if (IS_ERR(tp))
|
if (IS_ERR(tp))
|
||||||
return PTR_ERR(tp);
|
return PTR_ERR(tp);
|
||||||
|
|
||||||
rc = raw3270_add_view(&tp->view, &tty3270_fn, tty->index);
|
rc = raw3270_add_view(&tp->view, &tty3270_fn,
|
||||||
|
tty->index + RAW3270_FIRSTMINOR);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
tty3270_free_view(tp);
|
tty3270_free_view(tp);
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -1846,12 +1847,12 @@ static const struct tty_operations tty3270_ops = {
|
||||||
|
|
||||||
void tty3270_create_cb(int minor)
|
void tty3270_create_cb(int minor)
|
||||||
{
|
{
|
||||||
tty_register_device(tty3270_driver, minor, NULL);
|
tty_register_device(tty3270_driver, minor - RAW3270_FIRSTMINOR, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tty3270_destroy_cb(int minor)
|
void tty3270_destroy_cb(int minor)
|
||||||
{
|
{
|
||||||
tty_unregister_device(tty3270_driver, minor);
|
tty_unregister_device(tty3270_driver, minor - RAW3270_FIRSTMINOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct raw3270_notifier tty3270_notifier =
|
struct raw3270_notifier tty3270_notifier =
|
||||||
|
@ -1884,7 +1885,8 @@ static int __init tty3270_init(void)
|
||||||
driver->driver_name = "tty3270";
|
driver->driver_name = "tty3270";
|
||||||
driver->name = "3270/tty";
|
driver->name = "3270/tty";
|
||||||
driver->major = IBM_TTY3270_MAJOR;
|
driver->major = IBM_TTY3270_MAJOR;
|
||||||
driver->minor_start = 0;
|
driver->minor_start = RAW3270_FIRSTMINOR;
|
||||||
|
driver->name_base = RAW3270_FIRSTMINOR;
|
||||||
driver->type = TTY_DRIVER_TYPE_SYSTEM;
|
driver->type = TTY_DRIVER_TYPE_SYSTEM;
|
||||||
driver->subtype = SYSTEM_TYPE_TTY;
|
driver->subtype = SYSTEM_TYPE_TTY;
|
||||||
driver->init_termios = tty_std_termios;
|
driver->init_termios = tty_std_termios;
|
||||||
|
|
|
@ -55,6 +55,7 @@ comment "SPI Master Controller Drivers"
|
||||||
|
|
||||||
config SPI_ALTERA
|
config SPI_ALTERA
|
||||||
tristate "Altera SPI Controller"
|
tristate "Altera SPI Controller"
|
||||||
|
depends on GENERIC_HARDIRQS
|
||||||
select SPI_BITBANG
|
select SPI_BITBANG
|
||||||
help
|
help
|
||||||
This is the driver for the Altera SPI Controller.
|
This is the driver for the Altera SPI Controller.
|
||||||
|
@ -310,7 +311,7 @@ config SPI_PXA2XX_DMA
|
||||||
|
|
||||||
config SPI_PXA2XX
|
config SPI_PXA2XX
|
||||||
tristate "PXA2xx SSP SPI master"
|
tristate "PXA2xx SSP SPI master"
|
||||||
depends on ARCH_PXA || PCI || ACPI
|
depends on (ARCH_PXA || PCI || ACPI) && GENERIC_HARDIRQS
|
||||||
select PXA_SSP if ARCH_PXA
|
select PXA_SSP if ARCH_PXA
|
||||||
help
|
help
|
||||||
This enables using a PXA2xx or Sodaville SSP port as a SPI master
|
This enables using a PXA2xx or Sodaville SSP port as a SPI master
|
||||||
|
|
Loading…
Add table
Reference in a new issue