From 2c190da477c9ab167f5bb37414d99ef2063b388a Mon Sep 17 00:00:00 2001 From: Jan Glauber Date: Tue, 15 Mar 2011 17:08:19 +0100 Subject: [S390] remove redundant stack check option Newer gcc versions offer an architecture-independent option to check the stack size and warn if it reaches a certain limit. This option already existed for s390 by using -mwarn-dynamicstack. Since one stack check option is enough remove the s390 specific stack check but keep the option that warns about dynamic stack usage because that is not covered by the generic option. Signed-off-by: Jan Glauber Signed-off-by: Martin Schwidefsky --- arch/s390/Kconfig | 20 +++++--------------- arch/s390/Makefile | 3 +-- 2 files changed, 6 insertions(+), 17 deletions(-) diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 636bcb81d068..271a02f821c0 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -341,26 +341,16 @@ config STACK_GUARD The minimum size for the stack guard should be 256 for 31 bit and 512 for 64 bit. -config WARN_STACK +config WARN_DYNAMIC_STACK def_bool n - prompt "Emit compiler warnings for function with broken stack usage" + prompt "Emit compiler warnings for function with dynamic stack usage" help - This option enables the compiler options -mwarn-framesize and - -mwarn-dynamicstack. If the compiler supports these options it - will generate warnings for function which either use alloca or - create a stack frame bigger than CONFIG_WARN_STACK_SIZE. + This option enables the compiler option -mwarn-dynamicstack. If the + compiler supports this options generates warnings for functions + that dynamically allocate stack space using alloca. Say N if you are unsure. -config WARN_STACK_SIZE - int "Maximum frame size considered safe (128-2048)" - range 128 2048 - depends on WARN_STACK - default "2048" - help - This allows you to specify the maximum frame size a function may - have without the compiler complaining about it. - config ARCH_POPULATES_NODE_MAP def_bool y diff --git a/arch/s390/Makefile b/arch/s390/Makefile index d5b8a6ade525..27a0b5df5ead 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile @@ -80,8 +80,7 @@ endif endif ifeq ($(call cc-option-yn,-mwarn-dynamicstack),y) -cflags-$(CONFIG_WARN_STACK) += -mwarn-dynamicstack -cflags-$(CONFIG_WARN_STACK) += -mwarn-framesize=$(CONFIG_WARN_STACK_SIZE) +cflags-$(CONFIG_WARN_DYNAMIC_STACK) += -mwarn-dynamicstack endif KBUILD_CFLAGS += -mbackchain -msoft-float $(cflags-y) -- cgit v1.2.3 From ee5894fb0f128476dc9afb2ed50cab1427dfe0c3 Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Tue, 15 Mar 2011 17:08:20 +0100 Subject: [S390] remove superfluous check from do_IRQ Don't check for the int_type if an adapter interrupt is presented. Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/cio.c | 6 +----- drivers/s390/cio/cio.h | 2 -- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 430f875006f2..f3147542e52e 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -630,11 +630,7 @@ void __irq_entry do_IRQ(struct pt_regs *regs) irb = (struct irb *)&S390_lowcore.irb; do { kstat_cpu(smp_processor_id()).irqs[IO_INTERRUPT]++; - /* - * Non I/O-subchannel thin interrupts are processed differently - */ - if (tpi_info->adapter_IO == 1 && - tpi_info->int_type == IO_INTERRUPT_TYPE) { + if (tpi_info->adapter_IO) { do_adapter_IO(tpi_info->isc); continue; } diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h index bf7f80f5a330..7a9032d01fb8 100644 --- a/drivers/s390/cio/cio.h +++ b/drivers/s390/cio/cio.h @@ -105,8 +105,6 @@ struct subchannel { struct schib_config config; } __attribute__ ((aligned(8))); -#define IO_INTERRUPT_TYPE 0 /* I/O interrupt type */ - #define to_subchannel(n) container_of(n, struct subchannel, dev) extern int cio_validate_subchannel (struct subchannel *, struct subchannel_id); -- cgit v1.2.3 From d54cddb620fa493968111f479029dcd910fcb921 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 15 Mar 2011 17:08:21 +0100 Subject: [S390] dasd: get rid of compile warning Get rid of this: drivers/s390/block/dasd_eckd.c: In function 'dasd_eckd_build_cp_tpm_track.clone.8': drivers/s390/block/dasd_eckd.c:2589:34: warning: 'len_to_track_end' may be used uninitialized in this function Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- drivers/s390/block/dasd_eckd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index a9fe23d5bd0f..379d8592bc6e 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c @@ -2648,6 +2648,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track( dasd_sfree_request(cqr, startdev); return ERR_PTR(-EAGAIN); } + len_to_track_end = 0; /* * A tidaw can address 4k of memory, but must not cross page boundaries * We can let the block layer handle this by setting -- cgit v1.2.3 From 305b1523250faf9675919def94906775992ce52d Mon Sep 17 00:00:00 2001 From: Jan Glauber Date: Tue, 15 Mar 2011 17:08:22 +0100 Subject: [S390] Write protect module text and RO data Implement write protection for kernel modules text and read-only data sections by implementing set_memory_[ro|rw] on s390. Since s390 has no execute bit in the pte's NX is not supported. set_memory_[ro|rw] will only work on normal pages and not on large pages, so in case a large page should be modified bail out with a warning. Signed-off-by: Jan Glauber Signed-off-by: Martin Schwidefsky --- arch/s390/Kconfig.debug | 3 +++ arch/s390/include/asm/cacheflush.h | 4 +++ arch/s390/mm/Makefile | 1 + arch/s390/mm/pageattr.c | 55 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 63 insertions(+) create mode 100644 arch/s390/mm/pageattr.c diff --git a/arch/s390/Kconfig.debug b/arch/s390/Kconfig.debug index 2b380df95606..d76cef3fef37 100644 --- a/arch/s390/Kconfig.debug +++ b/arch/s390/Kconfig.debug @@ -31,4 +31,7 @@ config DEBUG_STRICT_USER_COPY_CHECKS If unsure, or if you run an older (pre 4.4) gcc, say N. +config DEBUG_SET_MODULE_RONX + def_bool y + depends on MODULES endmenu diff --git a/arch/s390/include/asm/cacheflush.h b/arch/s390/include/asm/cacheflush.h index 7e1f77620624..43a5c78046db 100644 --- a/arch/s390/include/asm/cacheflush.h +++ b/arch/s390/include/asm/cacheflush.h @@ -8,4 +8,8 @@ void kernel_map_pages(struct page *page, int numpages, int enable); #endif +int set_memory_ro(unsigned long addr, int numpages); +int set_memory_rw(unsigned long addr, int numpages); +int set_memory_nx(unsigned long addr, int numpages); + #endif /* _S390_CACHEFLUSH_H */ diff --git a/arch/s390/mm/Makefile b/arch/s390/mm/Makefile index 6fbc6f3fbdf2..d98fe9004a52 100644 --- a/arch/s390/mm/Makefile +++ b/arch/s390/mm/Makefile @@ -6,3 +6,4 @@ obj-y := init.o fault.o extmem.o mmap.o vmem.o pgtable.o maccess.o \ page-states.o gup.o obj-$(CONFIG_CMM) += cmm.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o +obj-$(CONFIG_DEBUG_SET_MODULE_RONX) += pageattr.o diff --git a/arch/s390/mm/pageattr.c b/arch/s390/mm/pageattr.c new file mode 100644 index 000000000000..122ffbd08ce0 --- /dev/null +++ b/arch/s390/mm/pageattr.c @@ -0,0 +1,55 @@ +/* + * Copyright IBM Corp. 2011 + * Author(s): Jan Glauber + */ +#include +#include +#include +#include + +static void change_page_attr(unsigned long addr, int numpages, + pte_t (*set) (pte_t)) +{ + pte_t *ptep, pte; + pmd_t *pmdp; + pud_t *pudp; + pgd_t *pgdp; + int i; + + for (i = 0; i < numpages; i++) { + pgdp = pgd_offset(&init_mm, addr); + pudp = pud_offset(pgdp, addr); + pmdp = pmd_offset(pudp, addr); + if (pmd_huge(*pmdp)) { + WARN_ON_ONCE(1); + continue; + } + ptep = pte_offset_kernel(pmdp, addr + i * PAGE_SIZE); + + pte = *ptep; + pte = set(pte); + ptep_invalidate(&init_mm, addr + i * PAGE_SIZE, ptep); + *ptep = pte; + } +} + +int set_memory_ro(unsigned long addr, int numpages) +{ + change_page_attr(addr, numpages, pte_wrprotect); + return 0; +} +EXPORT_SYMBOL_GPL(set_memory_ro); + +int set_memory_rw(unsigned long addr, int numpages) +{ + change_page_attr(addr, numpages, pte_mkwrite); + return 0; +} +EXPORT_SYMBOL_GPL(set_memory_rw); + +/* not possible */ +int set_memory_nx(unsigned long addr, int numpages) +{ + return 0; +} +EXPORT_SYMBOL_GPL(set_memory_nx); -- cgit v1.2.3 From 9e6f9f851cfa41f42f8985e0b82a54b1b28d3465 Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Tue, 15 Mar 2011 17:08:23 +0100 Subject: [S390] cio: move orb definitions to separate header Move the data definition for the orb union to a separate header file. Also apply the curent codingstyle. Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/io_sch.h | 54 +------------------------------------- drivers/s390/cio/orb.h | 67 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 53 deletions(-) create mode 100644 drivers/s390/cio/orb.h diff --git a/drivers/s390/cio/io_sch.h b/drivers/s390/cio/io_sch.h index d024d2c21897..20e7a1b127ce 100644 --- a/drivers/s390/cio/io_sch.h +++ b/drivers/s390/cio/io_sch.h @@ -5,59 +5,7 @@ #include #include #include "css.h" - -/* - * command-mode operation request block - */ -struct cmd_orb { - u32 intparm; /* interruption parameter */ - u32 key : 4; /* flags, like key, suspend control, etc. */ - u32 spnd : 1; /* suspend control */ - u32 res1 : 1; /* reserved */ - u32 mod : 1; /* modification control */ - u32 sync : 1; /* synchronize control */ - u32 fmt : 1; /* format control */ - u32 pfch : 1; /* prefetch control */ - u32 isic : 1; /* initial-status-interruption control */ - u32 alcc : 1; /* address-limit-checking control */ - u32 ssic : 1; /* suppress-suspended-interr. control */ - u32 res2 : 1; /* reserved */ - u32 c64 : 1; /* IDAW/QDIO 64 bit control */ - u32 i2k : 1; /* IDAW 2/4kB block size control */ - u32 lpm : 8; /* logical path mask */ - u32 ils : 1; /* incorrect length */ - u32 zero : 6; /* reserved zeros */ - u32 orbx : 1; /* ORB extension control */ - u32 cpa; /* channel program address */ -} __attribute__ ((packed, aligned(4))); - -/* - * transport-mode operation request block - */ -struct tm_orb { - u32 intparm; - u32 key:4; - u32 :9; - u32 b:1; - u32 :2; - u32 lpm:8; - u32 :7; - u32 x:1; - u32 tcw; - u32 prio:8; - u32 :8; - u32 rsvpgm:8; - u32 :8; - u32 :32; - u32 :32; - u32 :32; - u32 :32; -} __attribute__ ((packed, aligned(4))); - -union orb { - struct cmd_orb cmd; - struct tm_orb tm; -} __attribute__ ((packed, aligned(4))); +#include "orb.h" struct io_subchannel_private { union orb orb; /* operation request block */ diff --git a/drivers/s390/cio/orb.h b/drivers/s390/cio/orb.h new file mode 100644 index 000000000000..45a9865c2b36 --- /dev/null +++ b/drivers/s390/cio/orb.h @@ -0,0 +1,67 @@ +/* + * Orb related data structures. + * + * Copyright IBM Corp. 2007, 2011 + * + * Author(s): Cornelia Huck + * Peter Oberparleiter + * Sebastian Ott + */ + +#ifndef S390_ORB_H +#define S390_ORB_H + +/* + * Command-mode operation request block + */ +struct cmd_orb { + u32 intparm; /* interruption parameter */ + u32 key:4; /* flags, like key, suspend control, etc. */ + u32 spnd:1; /* suspend control */ + u32 res1:1; /* reserved */ + u32 mod:1; /* modification control */ + u32 sync:1; /* synchronize control */ + u32 fmt:1; /* format control */ + u32 pfch:1; /* prefetch control */ + u32 isic:1; /* initial-status-interruption control */ + u32 alcc:1; /* address-limit-checking control */ + u32 ssic:1; /* suppress-suspended-interr. control */ + u32 res2:1; /* reserved */ + u32 c64:1; /* IDAW/QDIO 64 bit control */ + u32 i2k:1; /* IDAW 2/4kB block size control */ + u32 lpm:8; /* logical path mask */ + u32 ils:1; /* incorrect length */ + u32 zero:6; /* reserved zeros */ + u32 orbx:1; /* ORB extension control */ + u32 cpa; /* channel program address */ +} __packed __aligned(4); + +/* + * Transport-mode operation request block + */ +struct tm_orb { + u32 intparm; + u32 key:4; + u32:9; + u32 b:1; + u32:2; + u32 lpm:8; + u32:7; + u32 x:1; + u32 tcw; + u32 prio:8; + u32:8; + u32 rsvpgm:8; + u32:8; + u32:32; + u32:32; + u32:32; + u32:32; +} __packed __aligned(4); + +union orb { + struct cmd_orb cmd; + struct tm_orb tm; +} __packed __aligned(4); + +#endif /* S390_ORB_H */ -- cgit v1.2.3 From dbda8ce5407c731a0108a35db3e058d5d350dd80 Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Tue, 15 Mar 2011 17:08:24 +0100 Subject: [S390] cio: move asms to generic header The ssch and csch functions are not I/O subchannel specific, thus move them from io_sch.h to ioasm.h Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/io_sch.h | 32 -------------------------------- drivers/s390/cio/ioasm.h | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 32 deletions(-) diff --git a/drivers/s390/cio/io_sch.h b/drivers/s390/cio/io_sch.h index 20e7a1b127ce..36870d9f108a 100644 --- a/drivers/s390/cio/io_sch.h +++ b/drivers/s390/cio/io_sch.h @@ -139,23 +139,6 @@ struct ccw_device_private { void *cmb_wait; /* deferred cmb enable/disable */ }; -static inline int ssch(struct subchannel_id schid, union orb *addr) -{ - register struct subchannel_id reg1 asm("1") = schid; - int ccode = -EIO; - - asm volatile( - " ssch 0(%2)\n" - "0: ipm %0\n" - " srl %0,28\n" - "1:\n" - EX_TABLE(0b, 1b) - : "+d" (ccode) - : "d" (reg1), "a" (addr), "m" (*addr) - : "cc", "memory"); - return ccode; -} - static inline int rsch(struct subchannel_id schid) { register struct subchannel_id reg1 asm("1") = schid; @@ -171,21 +154,6 @@ static inline int rsch(struct subchannel_id schid) return ccode; } -static inline int csch(struct subchannel_id schid) -{ - register struct subchannel_id reg1 asm("1") = schid; - int ccode; - - asm volatile( - " csch\n" - " ipm %0\n" - " srl %0,28" - : "=d" (ccode) - : "d" (reg1) - : "cc"); - return ccode; -} - static inline int hsch(struct subchannel_id schid) { register struct subchannel_id reg1 asm("1") = schid; diff --git a/drivers/s390/cio/ioasm.h b/drivers/s390/cio/ioasm.h index fac06155773f..4d80fc67a06b 100644 --- a/drivers/s390/cio/ioasm.h +++ b/drivers/s390/cio/ioasm.h @@ -3,6 +3,8 @@ #include #include +#include "orb.h" +#include "cio.h" /* * TPI info structure @@ -87,6 +89,38 @@ static inline int tsch(struct subchannel_id schid, struct irb *addr) return ccode; } +static inline int ssch(struct subchannel_id schid, union orb *addr) +{ + register struct subchannel_id reg1 asm("1") = schid; + int ccode = -EIO; + + asm volatile( + " ssch 0(%2)\n" + "0: ipm %0\n" + " srl %0,28\n" + "1:\n" + EX_TABLE(0b, 1b) + : "+d" (ccode) + : "d" (reg1), "a" (addr), "m" (*addr) + : "cc", "memory"); + return ccode; +} + +static inline int csch(struct subchannel_id schid) +{ + register struct subchannel_id reg1 asm("1") = schid; + int ccode; + + asm volatile( + " csch\n" + " ipm %0\n" + " srl %0,28" + : "=d" (ccode) + : "d" (reg1) + : "cc"); + return ccode; +} + static inline int tpi(struct tpi_info *addr) { int ccode; -- cgit v1.2.3 From c513d07a2df0f7076c1707274e29737f09df3b7f Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Tue, 15 Mar 2011 17:08:25 +0100 Subject: [S390] cio: move options to io_sch_private Move the options member from struct subchannel to io_subchannel_private since it's I/O subchannel specific. Also remove the unused cio_get_options function. Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/cio.c | 37 +++++++++++-------------------------- drivers/s390/cio/cio.h | 8 -------- drivers/s390/cio/io_sch.h | 7 ++++++- 3 files changed, 17 insertions(+), 35 deletions(-) diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index f3147542e52e..cbde448f9947 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -84,29 +84,14 @@ out_unregister: arch_initcall (cio_debug_init); -int -cio_set_options (struct subchannel *sch, int flags) +int cio_set_options(struct subchannel *sch, int flags) { - sch->options.suspend = (flags & DOIO_ALLOW_SUSPEND) != 0; - sch->options.prefetch = (flags & DOIO_DENY_PREFETCH) != 0; - sch->options.inter = (flags & DOIO_SUPPRESS_INTER) != 0; - return 0; -} + struct io_subchannel_private *priv = to_io_private(sch); -/* FIXME: who wants to use this? */ -int -cio_get_options (struct subchannel *sch) -{ - int flags; - - flags = 0; - if (sch->options.suspend) - flags |= DOIO_ALLOW_SUSPEND; - if (sch->options.prefetch) - flags |= DOIO_DENY_PREFETCH; - if (sch->options.inter) - flags |= DOIO_SUPPRESS_INTER; - return flags; + priv->options.suspend = (flags & DOIO_ALLOW_SUSPEND) != 0; + priv->options.prefetch = (flags & DOIO_DENY_PREFETCH) != 0; + priv->options.inter = (flags & DOIO_SUPPRESS_INTER) != 0; + return 0; } static int @@ -139,21 +124,21 @@ cio_start_key (struct subchannel *sch, /* subchannel structure */ __u8 lpm, /* logical path mask */ __u8 key) /* storage key */ { + struct io_subchannel_private *priv = to_io_private(sch); + union orb *orb = &priv->orb; int ccode; - union orb *orb; CIO_TRACE_EVENT(5, "stIO"); CIO_TRACE_EVENT(5, dev_name(&sch->dev)); - orb = &to_io_private(sch)->orb; memset(orb, 0, sizeof(union orb)); /* sch is always under 2G. */ orb->cmd.intparm = (u32)(addr_t)sch; orb->cmd.fmt = 1; - orb->cmd.pfch = sch->options.prefetch == 0; - orb->cmd.spnd = sch->options.suspend; - orb->cmd.ssic = sch->options.suspend && sch->options.inter; + orb->cmd.pfch = priv->options.prefetch == 0; + orb->cmd.spnd = priv->options.suspend; + orb->cmd.ssic = priv->options.suspend && priv->options.inter; orb->cmd.lpm = (lpm != 0) ? lpm : sch->lpm; #ifdef CONFIG_64BIT /* diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h index 7a9032d01fb8..bdbbe7c4c1a2 100644 --- a/drivers/s390/cio/cio.h +++ b/drivers/s390/cio/cio.h @@ -84,13 +84,6 @@ struct subchannel { SUBCHANNEL_TYPE_MSG = 2, SUBCHANNEL_TYPE_ADM = 3, } st; /* subchannel type */ - - struct { - unsigned int suspend:1; /* allow suspend */ - unsigned int prefetch:1;/* deny prefetch */ - unsigned int inter:1; /* suppress intermediate interrupts */ - } __attribute__ ((packed)) options; - __u8 vpm; /* verified path mask */ __u8 lpm; /* logical path mask */ __u8 opm; /* operational path mask */ @@ -118,7 +111,6 @@ extern int cio_start (struct subchannel *, struct ccw1 *, __u8); extern int cio_start_key (struct subchannel *, struct ccw1 *, __u8, __u8); extern int cio_cancel (struct subchannel *); extern int cio_set_options (struct subchannel *, int); -extern int cio_get_options (struct subchannel *); extern int cio_update_schib(struct subchannel *sch); extern int cio_commit_config(struct subchannel *sch); diff --git a/drivers/s390/cio/io_sch.h b/drivers/s390/cio/io_sch.h index 36870d9f108a..8271a1f9860c 100644 --- a/drivers/s390/cio/io_sch.h +++ b/drivers/s390/cio/io_sch.h @@ -10,7 +10,12 @@ struct io_subchannel_private { union orb orb; /* operation request block */ struct ccw1 sense_ccw; /* static ccw for sense command */ -} __attribute__ ((aligned(8))); + struct { + unsigned int suspend:1; /* allow suspend */ + unsigned int prefetch:1;/* deny prefetch */ + unsigned int inter:1; /* suppress intermediate interrupts */ + } __packed options; +} __aligned(8); #define to_io_private(n) ((struct io_subchannel_private *)n->private) #define sch_get_cdev(n) (dev_get_drvdata(&n->dev)) -- cgit v1.2.3 From 97eb6bfcb942a59f5c8d273523d68c6a0f57a6f2 Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Tue, 15 Mar 2011 17:08:26 +0100 Subject: [S390] cio: move cdev pointer to io_subchannel_private Move the subchannels ccw device pointer from drv_data to the private data for I/O subchannels, since it is not the only drv_data for I/O subchannels. The next step will be to make io_subchannel_private the new drv_data for I/O subchannels. Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/io_sch.h | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/s390/cio/io_sch.h b/drivers/s390/cio/io_sch.h index 8271a1f9860c..23f50ba50392 100644 --- a/drivers/s390/cio/io_sch.h +++ b/drivers/s390/cio/io_sch.h @@ -10,6 +10,7 @@ struct io_subchannel_private { union orb orb; /* operation request block */ struct ccw1 sense_ccw; /* static ccw for sense command */ + struct ccw_device *cdev;/* pointer to the child ccw device */ struct { unsigned int suspend:1; /* allow suspend */ unsigned int prefetch:1;/* deny prefetch */ @@ -18,8 +19,20 @@ struct io_subchannel_private { } __aligned(8); #define to_io_private(n) ((struct io_subchannel_private *)n->private) -#define sch_get_cdev(n) (dev_get_drvdata(&n->dev)) -#define sch_set_cdev(n, c) (dev_set_drvdata(&n->dev, c)) + +static inline struct ccw_device *sch_get_cdev(struct subchannel *sch) +{ + struct io_subchannel_private *priv = to_io_private(sch); + return priv ? priv->cdev : NULL; +} + +static inline void sch_set_cdev(struct subchannel *sch, + struct ccw_device *cdev) +{ + struct io_subchannel_private *priv = to_io_private(sch); + if (priv) + priv->cdev = cdev; +} #define MAX_CIWS 8 -- cgit v1.2.3 From f92519e83e3bd509cb861a946701a26f74cb77fa Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Tue, 15 Mar 2011 17:08:27 +0100 Subject: [S390] css: move io_private to drv_data Use the subchannels drv_data to access io_subchannel_private for io subchannels. Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/device.c | 17 +++++++++++------ drivers/s390/cio/io_sch.h | 4 +++- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index b7eaff9ca19e..7582a1e35eb8 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -1030,6 +1030,7 @@ static void io_subchannel_init_fields(struct subchannel *sch) */ static int io_subchannel_probe(struct subchannel *sch) { + struct io_subchannel_private *io_priv; struct ccw_device *cdev; int rc; @@ -1073,10 +1074,11 @@ static int io_subchannel_probe(struct subchannel *sch) if (rc) goto out_schedule; /* Allocate I/O subchannel private data. */ - sch->private = kzalloc(sizeof(struct io_subchannel_private), - GFP_KERNEL | GFP_DMA); - if (!sch->private) + io_priv = kzalloc(sizeof(*io_priv), GFP_KERNEL | GFP_DMA); + if (!io_priv) goto out_schedule; + + set_io_private(sch, io_priv); css_schedule_eval(sch->schid); return 0; @@ -1090,6 +1092,7 @@ out_schedule: static int io_subchannel_remove (struct subchannel *sch) { + struct io_subchannel_private *io_priv = to_io_private(sch); struct ccw_device *cdev; cdev = sch_get_cdev(sch); @@ -1099,11 +1102,12 @@ io_subchannel_remove (struct subchannel *sch) /* Set ccw device to not operational and drop reference. */ spin_lock_irq(cdev->ccwlock); sch_set_cdev(sch, NULL); + set_io_private(sch, NULL); cdev->private->state = DEV_STATE_NOT_OPER; spin_unlock_irq(cdev->ccwlock); ccw_device_unregister(cdev); out_free: - kfree(sch->private); + kfree(io_priv); sysfs_remove_group(&sch->dev.kobj, &io_subchannel_attr_group); return 0; } @@ -1553,11 +1557,12 @@ spinlock_t * cio_get_console_lock(void) static int ccw_device_console_enable(struct ccw_device *cdev, struct subchannel *sch) { + struct io_subchannel_private *io_priv = cio_get_console_priv(); int rc; /* Attach subchannel private data. */ - sch->private = cio_get_console_priv(); - memset(sch->private, 0, sizeof(struct io_subchannel_private)); + memset(io_priv, 0, sizeof(*io_priv)); + set_io_private(sch, io_priv); io_subchannel_init_fields(sch); rc = cio_commit_config(sch); if (rc) diff --git a/drivers/s390/cio/io_sch.h b/drivers/s390/cio/io_sch.h index 23f50ba50392..ba31ad88f4f7 100644 --- a/drivers/s390/cio/io_sch.h +++ b/drivers/s390/cio/io_sch.h @@ -18,7 +18,9 @@ struct io_subchannel_private { } __packed options; } __aligned(8); -#define to_io_private(n) ((struct io_subchannel_private *)n->private) +#define to_io_private(n) ((struct io_subchannel_private *) \ + dev_get_drvdata(&(n)->dev)) +#define set_io_private(n, p) (dev_set_drvdata(&(n)->dev, p)) static inline struct ccw_device *sch_get_cdev(struct subchannel *sch) { -- cgit v1.2.3 From 85fb534e27eca3f433a7b53bb78cf208b92bf190 Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Tue, 15 Mar 2011 17:08:28 +0100 Subject: [S390] css: move chsc_private to drv_data Use the subchannels drv_data to access chsc_private for chsc subchannels. Note: Also set the drv_data prior to the cio_enable_subchannel call, since we can receive an interrupt the moment we enable the subchannel and the IRQ handler relies on this data. Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/chsc_sch.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c index 3c3f3ffe2179..09c2ea84a57f 100644 --- a/drivers/s390/cio/chsc_sch.c +++ b/drivers/s390/cio/chsc_sch.c @@ -50,7 +50,7 @@ MODULE_LICENSE("GPL"); static void chsc_subchannel_irq(struct subchannel *sch) { - struct chsc_private *private = sch->private; + struct chsc_private *private = dev_get_drvdata(&sch->dev); struct chsc_request *request = private->request; struct irb *irb = (struct irb *)&S390_lowcore.irb; @@ -80,13 +80,14 @@ static int chsc_subchannel_probe(struct subchannel *sch) private = kzalloc(sizeof(*private), GFP_KERNEL); if (!private) return -ENOMEM; + dev_set_drvdata(&sch->dev, private); ret = cio_enable_subchannel(sch, (u32)(unsigned long)sch); if (ret) { CHSC_MSG(0, "Failed to enable 0.%x.%04x: %d\n", sch->schid.ssid, sch->schid.sch_no, ret); + dev_set_drvdata(&sch->dev, NULL); kfree(private); } else { - sch->private = private; if (dev_get_uevent_suppress(&sch->dev)) { dev_set_uevent_suppress(&sch->dev, 0); kobject_uevent(&sch->dev.kobj, KOBJ_ADD); @@ -100,8 +101,8 @@ static int chsc_subchannel_remove(struct subchannel *sch) struct chsc_private *private; cio_disable_subchannel(sch); - private = sch->private; - sch->private = NULL; + private = dev_get_drvdata(&sch->dev); + dev_set_drvdata(&sch->dev, NULL); if (private->request) { complete(&private->request->completion); put_device(&sch->dev); @@ -241,7 +242,7 @@ static int chsc_async(struct chsc_async_area *chsc_area, chsc_area->header.key = PAGE_DEFAULT_KEY >> 4; while ((sch = chsc_get_next_subchannel(sch))) { spin_lock(sch->lock); - private = sch->private; + private = dev_get_drvdata(&sch->dev); if (private->request) { spin_unlock(sch->lock); ret = -EBUSY; -- cgit v1.2.3 From 085ee9db88bebaadd6d54751b0ced8db486dddfc Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Tue, 15 Mar 2011 17:08:29 +0100 Subject: [S390] css: remove subchannel private All subchannel drivers use drv_data, so get rid of the additional private pointer of struct subchannel. Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/cio.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h index bdbbe7c4c1a2..155a82bcb9e5 100644 --- a/drivers/s390/cio/cio.h +++ b/drivers/s390/cio/cio.h @@ -92,7 +92,6 @@ struct subchannel { struct chsc_ssd_info ssd_info; /* subchannel description */ struct device dev; /* entry in device tree */ struct css_driver *driver; - void *private; /* private per subchannel type data */ enum sch_todo todo; struct work_struct todo_work; struct schib_config config; -- cgit v1.2.3 From e6aed122a9185d0fe5890f02ea8efc32c355bc44 Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Tue, 15 Mar 2011 17:08:30 +0100 Subject: [S390] css_driver: remove duplicate members Remove the owner and name members of struct css_driver and convert all drivers to store this data in the embedded struct device_driver. Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/chsc_sch.c | 6 ++++-- drivers/s390/cio/css.c | 2 -- drivers/s390/cio/css.h | 4 ---- drivers/s390/cio/device.c | 6 ++++-- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c index 09c2ea84a57f..e950f1ad4dd1 100644 --- a/drivers/s390/cio/chsc_sch.c +++ b/drivers/s390/cio/chsc_sch.c @@ -148,7 +148,10 @@ static struct css_device_id chsc_subchannel_ids[] = { MODULE_DEVICE_TABLE(css, chsc_subchannel_ids); static struct css_driver chsc_subchannel_driver = { - .owner = THIS_MODULE, + .drv = { + .owner = THIS_MODULE, + .name = "chsc_subchannel", + }, .subchannel_type = chsc_subchannel_ids, .irq = chsc_subchannel_irq, .probe = chsc_subchannel_probe, @@ -158,7 +161,6 @@ static struct css_driver chsc_subchannel_driver = { .freeze = chsc_subchannel_freeze, .thaw = chsc_subchannel_restore, .restore = chsc_subchannel_restore, - .name = "chsc_subchannel", }; static int __init chsc_init_dbfs(void) diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 24d8e97355b9..51eaed0d7662 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -1233,9 +1233,7 @@ struct bus_type css_bus_type = { */ int css_driver_register(struct css_driver *cdrv) { - cdrv->drv.name = cdrv->name; cdrv->drv.bus = &css_bus_type; - cdrv->drv.owner = cdrv->owner; return driver_register(&cdrv->drv); } EXPORT_SYMBOL_GPL(css_driver_register); diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h index 7e37886de231..566dc1ac425e 100644 --- a/drivers/s390/cio/css.h +++ b/drivers/s390/cio/css.h @@ -63,7 +63,6 @@ struct subchannel; struct chp_link; /** * struct css_driver - device driver for subchannels - * @owner: owning module * @subchannel_type: subchannel type supported by this driver * @drv: embedded device driver structure * @irq: called on interrupts @@ -78,10 +77,8 @@ struct chp_link; * @thaw: undo work done in @freeze * @restore: callback for restoring after hibernation * @settle: wait for asynchronous work to finish - * @name: name of the device driver */ struct css_driver { - struct module *owner; struct css_device_id *subchannel_type; struct device_driver drv; void (*irq)(struct subchannel *); @@ -96,7 +93,6 @@ struct css_driver { int (*thaw) (struct subchannel *); int (*restore)(struct subchannel *); int (*settle)(void); - const char *name; }; #define to_cssdriver(n) container_of(n, struct css_driver, drv) diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 7582a1e35eb8..e50b12163afe 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -172,9 +172,11 @@ static int io_subchannel_settle(void) } static struct css_driver io_subchannel_driver = { - .owner = THIS_MODULE, + .drv = { + .owner = THIS_MODULE, + .name = "io_subchannel", + }, .subchannel_type = io_subchannel_ids, - .name = "io_subchannel", .irq = io_subchannel_irq, .sch_event = io_subchannel_sch_event, .chp_event = io_subchannel_chp_event, -- cgit v1.2.3 From 3041b6ab5f36ac303981e9f170ff2ae43dc9d125 Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Tue, 15 Mar 2011 17:08:31 +0100 Subject: [S390] css_bus_type: make it static Make css_bus_type static. Subchannel drivers have to use css_driver_register. Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/css.c | 4 ++-- drivers/s390/cio/css.h | 6 ------ 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 51eaed0d7662..c47b25fd3f43 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -35,6 +35,7 @@ int css_init_done = 0; int max_ssid; struct channel_subsystem *channel_subsystems[__MAX_CSSID + 1]; +static struct bus_type css_bus_type; int for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *data) @@ -1214,7 +1215,7 @@ static const struct dev_pm_ops css_pm_ops = { .restore = css_pm_restore, }; -struct bus_type css_bus_type = { +static struct bus_type css_bus_type = { .name = "css", .match = css_bus_match, .probe = css_probe, @@ -1251,4 +1252,3 @@ void css_driver_unregister(struct css_driver *cdrv) EXPORT_SYMBOL_GPL(css_driver_unregister); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(css_bus_type); diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h index 566dc1ac425e..80ebdddf7747 100644 --- a/drivers/s390/cio/css.h +++ b/drivers/s390/cio/css.h @@ -97,11 +97,6 @@ struct css_driver { #define to_cssdriver(n) container_of(n, struct css_driver, drv) -/* - * all css_drivers have the css_bus_type - */ -extern struct bus_type css_bus_type; - extern int css_driver_register(struct css_driver *); extern void css_driver_unregister(struct css_driver *); @@ -136,7 +131,6 @@ struct channel_subsystem { }; #define to_css(dev) container_of(dev, struct channel_subsystem, device) -extern struct bus_type css_bus_type; extern struct channel_subsystem *channel_subsystems[]; /* Helper functions to build lists for the slow path. */ -- cgit v1.2.3 From d7b081ac0b8eee5f2a58123235061ee1b99a4f4d Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 15 Mar 2011 17:08:32 +0100 Subject: [S390] support XZ compressed kernel Add support for XZ compressed kernel. Same as on x86 and sh. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/Kconfig | 1 + arch/s390/boot/compressed/Makefile | 6 +++++- arch/s390/boot/compressed/misc.c | 5 +++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 271a02f821c0..2508a6f31588 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -85,6 +85,7 @@ config S390 select HAVE_KERNEL_BZIP2 select HAVE_KERNEL_LZMA select HAVE_KERNEL_LZO + select HAVE_KERNEL_XZ select HAVE_GET_USER_PAGES_FAST select HAVE_ARCH_MUTEX_CPU_RELAX select ARCH_INLINE_SPIN_TRYLOCK diff --git a/arch/s390/boot/compressed/Makefile b/arch/s390/boot/compressed/Makefile index 1c999f726a58..10e22c4ec4a7 100644 --- a/arch/s390/boot/compressed/Makefile +++ b/arch/s390/boot/compressed/Makefile @@ -7,7 +7,8 @@ BITS := $(if $(CONFIG_64BIT),64,31) targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 \ - vmlinux.bin.lzma vmlinux.bin.lzo misc.o piggy.o sizes.h head$(BITS).o + vmlinux.bin.xz vmlinux.bin.lzma vmlinux.bin.lzo misc.o piggy.o \ + sizes.h head$(BITS).o KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2 KBUILD_CFLAGS += $(cflags-y) @@ -48,6 +49,7 @@ suffix-$(CONFIG_KERNEL_GZIP) := gz suffix-$(CONFIG_KERNEL_BZIP2) := bz2 suffix-$(CONFIG_KERNEL_LZMA) := lzma suffix-$(CONFIG_KERNEL_LZO) := lzo +suffix-$(CONFIG_KERNEL_XZ) := xz $(obj)/vmlinux.bin.gz: $(vmlinux.bin.all-y) $(call if_changed,gzip) @@ -57,6 +59,8 @@ $(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y) $(call if_changed,lzma) $(obj)/vmlinux.bin.lzo: $(vmlinux.bin.all-y) $(call if_changed,lzo) +$(obj)/vmlinux.bin.xz: $(vmlinux.bin.all-y) + $(call if_changed,xzkern) LDFLAGS_piggy.o := -r --format binary --oformat $(LD_BFD) -T $(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix-y) diff --git a/arch/s390/boot/compressed/misc.c b/arch/s390/boot/compressed/misc.c index 2751b3a8a66f..028f23ea81d1 100644 --- a/arch/s390/boot/compressed/misc.c +++ b/arch/s390/boot/compressed/misc.c @@ -19,6 +19,7 @@ #undef memset #undef memcpy #undef memmove +#define memmove memmove #define memzero(s, n) memset((s), 0, (n)) /* Symbols defined by linker scripts */ @@ -54,6 +55,10 @@ static unsigned long free_mem_end_ptr; #include "../../../../lib/decompress_unlzo.c" #endif +#ifdef CONFIG_KERNEL_XZ +#include "../../../../lib/decompress_unxz.c" +#endif + extern _sclp_print_early(const char *); int puts(const char *s) -- cgit v1.2.3 From 6966727db1389f4926c6fa6e87a600112a5658b9 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 15 Mar 2011 17:08:33 +0100 Subject: [S390] kexec: Disable ftrace during kexec Disable ftrace during kexec. Same as on x86/powerpc. ac4414e "powerpc/kdump: Disable ftrace during kexec". Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/machine_kexec.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c index a922d51df6bf..b09b9c62573e 100644 --- a/arch/s390/kernel/machine_kexec.c +++ b/arch/s390/kernel/machine_kexec.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -71,6 +72,7 @@ static void __machine_kexec(void *data) void machine_kexec(struct kimage *image) { + tracer_disable(); smp_send_stop(); smp_switch_to_ipl_cpu(__machine_kexec, image); } -- cgit v1.2.3