Commit c27b9a2e authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6

* 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6:
  [S390] fix boot failures with compressed kernels
  [S390] fix broken proc interface for sclp_async
  [S390] sclp: avoid 64 bit division
  [S390] dasd: check tsb validity
  [S390] dasd: fix alignment of transport mode recovery TCW
  [S390] system.h: Fix compile error for 1 and 2 byte cmpxchg
  [S390] smp: fix lowcore allocation
  [S390] zcore: CPU registers are not saved under LPAR
parents 20dba459 06c0dd72
...@@ -24,8 +24,8 @@ ...@@ -24,8 +24,8 @@
/* Symbols defined by linker scripts */ /* Symbols defined by linker scripts */
extern char input_data[]; extern char input_data[];
extern int input_len; extern int input_len;
extern int _text; extern char _text, _end;
extern int _end; extern char _bss, _ebss;
static void error(char *m); static void error(char *m);
...@@ -129,12 +129,12 @@ unsigned long decompress_kernel(void) ...@@ -129,12 +129,12 @@ unsigned long decompress_kernel(void)
unsigned long output_addr; unsigned long output_addr;
unsigned char *output; unsigned char *output;
check_ipl_parmblock((void *) 0, (unsigned long) output + SZ__bss_start);
memset(&_bss, 0, &_ebss - &_bss);
free_mem_ptr = (unsigned long)&_end; free_mem_ptr = (unsigned long)&_end;
free_mem_end_ptr = free_mem_ptr + HEAP_SIZE; free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
output = (unsigned char *) ((free_mem_end_ptr + 4095UL) & -4096UL); output = (unsigned char *) ((free_mem_end_ptr + 4095UL) & -4096UL);
check_ipl_parmblock((void *) 0, (unsigned long) output + SZ__bss_start);
#ifdef CONFIG_BLK_DEV_INITRD #ifdef CONFIG_BLK_DEV_INITRD
/* /*
* Move the initrd right behind the end of the decompressed * Move the initrd right behind the end of the decompressed
......
...@@ -110,6 +110,7 @@ extern void pfault_fini(void); ...@@ -110,6 +110,7 @@ extern void pfault_fini(void);
#endif /* CONFIG_PFAULT */ #endif /* CONFIG_PFAULT */
extern void cmma_init(void); extern void cmma_init(void);
extern int memcpy_real(void *, void *, size_t);
#define finish_arch_switch(prev) do { \ #define finish_arch_switch(prev) do { \
set_fs(current->thread.mm_segment); \ set_fs(current->thread.mm_segment); \
...@@ -218,8 +219,8 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) ...@@ -218,8 +219,8 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
" l %0,%2\n" " l %0,%2\n"
"0: nr %0,%5\n" "0: nr %0,%5\n"
" lr %1,%0\n" " lr %1,%0\n"
" or %0,%2\n" " or %0,%3\n"
" or %1,%3\n" " or %1,%4\n"
" cs %0,%1,%2\n" " cs %0,%1,%2\n"
" jnl 1f\n" " jnl 1f\n"
" xr %1,%0\n" " xr %1,%0\n"
...@@ -239,8 +240,8 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) ...@@ -239,8 +240,8 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
" l %0,%2\n" " l %0,%2\n"
"0: nr %0,%5\n" "0: nr %0,%5\n"
" lr %1,%0\n" " lr %1,%0\n"
" or %0,%2\n" " or %0,%3\n"
" or %1,%3\n" " or %1,%4\n"
" cs %0,%1,%2\n" " cs %0,%1,%2\n"
" jnl 1f\n" " jnl 1f\n"
" xr %1,%0\n" " xr %1,%0\n"
......
...@@ -517,7 +517,10 @@ startup: ...@@ -517,7 +517,10 @@ startup:
lhi %r1,2 # mode 2 = esame (dump) lhi %r1,2 # mode 2 = esame (dump)
sigp %r1,%r0,0x12 # switch to esame mode sigp %r1,%r0,0x12 # switch to esame mode
sam64 # switch to 64 bit mode sam64 # switch to 64 bit mode
larl %r13,4f
lmh %r0,%r15,0(%r13) # clear high-order half
jg startup_continue jg startup_continue
4: .fill 16,4,0x0
#else #else
mvi __LC_AR_MODE_ID,0 # set ESA flag (mode 0) mvi __LC_AR_MODE_ID,0 # set ESA flag (mode 0)
l %r13,4f-.LPG0(%r13) l %r13,4f-.LPG0(%r13)
......
...@@ -21,7 +21,6 @@ startup_continue: ...@@ -21,7 +21,6 @@ startup_continue:
larl %r1,sched_clock_base_cc larl %r1,sched_clock_base_cc
mvc 0(8,%r1),__LC_LAST_UPDATE_CLOCK mvc 0(8,%r1),__LC_LAST_UPDATE_CLOCK
larl %r13,.LPG1 # get base larl %r13,.LPG1 # get base
lmh %r0,%r15,.Lzero64-.LPG1(%r13) # clear high-order half
lctlg %c0,%c15,.Lctl-.LPG1(%r13) # load control registers lctlg %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
lg %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area lg %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area
# move IPL device to lowcore # move IPL device to lowcore
...@@ -67,7 +66,6 @@ startup_continue: ...@@ -67,7 +66,6 @@ startup_continue:
.L4malign:.quad 0xffffffffffc00000 .L4malign:.quad 0xffffffffffc00000
.Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8 .Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8
.Lnop: .long 0x07000700 .Lnop: .long 0x07000700
.Lzero64:.fill 16,4,0x0
.Lparmaddr: .Lparmaddr:
.quad PARMAREA .quad PARMAREA
.align 64 .align 64
......
...@@ -401,7 +401,7 @@ setup_lowcore(void) ...@@ -401,7 +401,7 @@ setup_lowcore(void)
* Setup lowcore for boot cpu * Setup lowcore for boot cpu
*/ */
BUILD_BUG_ON(sizeof(struct _lowcore) != LC_PAGES * 4096); BUILD_BUG_ON(sizeof(struct _lowcore) != LC_PAGES * 4096);
lc = __alloc_bootmem(LC_PAGES * PAGE_SIZE, LC_PAGES * PAGE_SIZE, 0); lc = __alloc_bootmem_low(LC_PAGES * PAGE_SIZE, LC_PAGES * PAGE_SIZE, 0);
lc->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY; lc->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
lc->restart_psw.addr = lc->restart_psw.addr =
PSW_ADDR_AMODE | (unsigned long) restart_int_handler; PSW_ADDR_AMODE | (unsigned long) restart_int_handler;
...@@ -433,7 +433,7 @@ setup_lowcore(void) ...@@ -433,7 +433,7 @@ setup_lowcore(void)
#ifndef CONFIG_64BIT #ifndef CONFIG_64BIT
if (MACHINE_HAS_IEEE) { if (MACHINE_HAS_IEEE) {
lc->extended_save_area_addr = (__u32) lc->extended_save_area_addr = (__u32)
__alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0); __alloc_bootmem_low(PAGE_SIZE, PAGE_SIZE, 0);
/* enable extended save area */ /* enable extended save area */
__ctl_set_bit(14, 29); __ctl_set_bit(14, 29);
} }
......
...@@ -292,9 +292,9 @@ static void __init smp_get_save_area(unsigned int cpu, unsigned int phy_cpu) ...@@ -292,9 +292,9 @@ static void __init smp_get_save_area(unsigned int cpu, unsigned int phy_cpu)
zfcpdump_save_areas[cpu] = kmalloc(sizeof(struct save_area), GFP_KERNEL); zfcpdump_save_areas[cpu] = kmalloc(sizeof(struct save_area), GFP_KERNEL);
while (raw_sigp(phy_cpu, sigp_stop_and_store_status) == sigp_busy) while (raw_sigp(phy_cpu, sigp_stop_and_store_status) == sigp_busy)
cpu_relax(); cpu_relax();
memcpy(zfcpdump_save_areas[cpu], memcpy_real(zfcpdump_save_areas[cpu],
(void *)(unsigned long) store_prefix() + SAVE_AREA_BASE, (void *)(unsigned long) store_prefix() + SAVE_AREA_BASE,
sizeof(struct save_area)); sizeof(struct save_area));
} }
struct save_area *zfcpdump_save_areas[NR_CPUS + 1]; struct save_area *zfcpdump_save_areas[NR_CPUS + 1];
......
...@@ -59,3 +59,29 @@ long probe_kernel_write(void *dst, void *src, size_t size) ...@@ -59,3 +59,29 @@ long probe_kernel_write(void *dst, void *src, size_t size)
} }
return copied < 0 ? -EFAULT : 0; return copied < 0 ? -EFAULT : 0;
} }
int memcpy_real(void *dest, void *src, size_t count)
{
register unsigned long _dest asm("2") = (unsigned long) dest;
register unsigned long _len1 asm("3") = (unsigned long) count;
register unsigned long _src asm("4") = (unsigned long) src;
register unsigned long _len2 asm("5") = (unsigned long) count;
unsigned long flags;
int rc = -EFAULT;
if (!count)
return 0;
flags = __raw_local_irq_stnsm(0xf8UL);
asm volatile (
"0: mvcle %1,%2,0x0\n"
"1: jo 0b\n"
" lhi %0,0x0\n"
"2:\n"
EX_TABLE(1b,2b)
: "+d" (rc), "+d" (_dest), "+d" (_src), "+d" (_len1),
"+d" (_len2), "=m" (*((long *) dest))
: "m" (*((long *) src))
: "cc", "memory");
__raw_local_irq_ssm(flags);
return rc;
}
...@@ -2287,7 +2287,8 @@ static struct dasd_ccw_req *dasd_3990_erp_add_erp(struct dasd_ccw_req *cqr) ...@@ -2287,7 +2287,8 @@ static struct dasd_ccw_req *dasd_3990_erp_add_erp(struct dasd_ccw_req *cqr)
if (cqr->cpmode == 1) { if (cqr->cpmode == 1) {
cplength = 0; cplength = 0;
datasize = sizeof(struct tcw) + sizeof(struct tsb); /* TCW needs to be 64 byte aligned, so leave enough room */
datasize = 64 + sizeof(struct tcw) + sizeof(struct tsb);
} else { } else {
cplength = 2; cplength = 2;
datasize = 0; datasize = 0;
...@@ -2316,8 +2317,8 @@ static struct dasd_ccw_req *dasd_3990_erp_add_erp(struct dasd_ccw_req *cqr) ...@@ -2316,8 +2317,8 @@ static struct dasd_ccw_req *dasd_3990_erp_add_erp(struct dasd_ccw_req *cqr)
if (cqr->cpmode == 1) { if (cqr->cpmode == 1) {
/* make a shallow copy of the original tcw but set new tsb */ /* make a shallow copy of the original tcw but set new tsb */
erp->cpmode = 1; erp->cpmode = 1;
erp->cpaddr = erp->data; erp->cpaddr = PTR_ALIGN(erp->data, 64);
tcw = erp->data; tcw = erp->cpaddr;
tsb = (struct tsb *) &tcw[1]; tsb = (struct tsb *) &tcw[1];
*tcw = *((struct tcw *)cqr->cpaddr); *tcw = *((struct tcw *)cqr->cpaddr);
tcw->tsb = (long)tsb; tcw->tsb = (long)tsb;
......
...@@ -3155,11 +3155,11 @@ static void dasd_eckd_dump_sense_tcw(struct dasd_device *device, ...@@ -3155,11 +3155,11 @@ static void dasd_eckd_dump_sense_tcw(struct dasd_device *device,
tsb = NULL; tsb = NULL;
sense = NULL; sense = NULL;
if (irb->scsw.tm.tcw) if (irb->scsw.tm.tcw && (irb->scsw.tm.fcxs == 0x01))
tsb = tcw_get_tsb( tsb = tcw_get_tsb(
(struct tcw *)(unsigned long)irb->scsw.tm.tcw); (struct tcw *)(unsigned long)irb->scsw.tm.tcw);
if (tsb && (irb->scsw.tm.fcxs == 0x01)) { if (tsb) {
len += sprintf(page + len, KERN_ERR PRINTK_HEADER len += sprintf(page + len, KERN_ERR PRINTK_HEADER
" tsb->length %d\n", tsb->length); " tsb->length %d\n", tsb->length);
len += sprintf(page + len, KERN_ERR PRINTK_HEADER len += sprintf(page + len, KERN_ERR PRINTK_HEADER
......
...@@ -84,6 +84,7 @@ static int proc_handler_callhome(struct ctl_table *ctl, int write, ...@@ -84,6 +84,7 @@ static int proc_handler_callhome(struct ctl_table *ctl, int write,
rc = copy_from_user(buf, buffer, sizeof(buf)); rc = copy_from_user(buf, buffer, sizeof(buf));
if (rc != 0) if (rc != 0)
return -EFAULT; return -EFAULT;
buf[len - 1] = '\0';
if (strict_strtoul(buf, 0, &val) != 0) if (strict_strtoul(buf, 0, &val) != 0)
return -EINVAL; return -EINVAL;
if (val != 0 && val != 1) if (val != 0 && val != 1)
......
...@@ -308,6 +308,13 @@ struct assign_storage_sccb { ...@@ -308,6 +308,13 @@ struct assign_storage_sccb {
u16 rn; u16 rn;
} __packed; } __packed;
int arch_get_memory_phys_device(unsigned long start_pfn)
{
if (!rzm)
return 0;
return PFN_PHYS(start_pfn) >> ilog2(rzm);
}
static unsigned long long rn2addr(u16 rn) static unsigned long long rn2addr(u16 rn)
{ {
return (unsigned long long) (rn - 1) * rzm; return (unsigned long long) (rn - 1) * rzm;
...@@ -704,13 +711,6 @@ int sclp_chp_deconfigure(struct chp_id chpid) ...@@ -704,13 +711,6 @@ int sclp_chp_deconfigure(struct chp_id chpid)
return do_chp_configure(SCLP_CMDW_DECONFIGURE_CHPATH | chpid.id << 8); return do_chp_configure(SCLP_CMDW_DECONFIGURE_CHPATH | chpid.id << 8);
} }
int arch_get_memory_phys_device(unsigned long start_pfn)
{
if (!rzm)
return 0;
return PFN_PHYS(start_pfn) / rzm;
}
struct chp_info_sccb { struct chp_info_sccb {
struct sccb_header header; struct sccb_header header;
u8 recognized[SCLP_CHP_INFO_MASK_SIZE]; u8 recognized[SCLP_CHP_INFO_MASK_SIZE];
......
...@@ -141,33 +141,6 @@ static int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count) ...@@ -141,33 +141,6 @@ static int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count)
return memcpy_hsa(dest, src, count, TO_KERNEL); return memcpy_hsa(dest, src, count, TO_KERNEL);
} }
static int memcpy_real(void *dest, unsigned long src, size_t count)
{
unsigned long flags;
int rc = -EFAULT;
register unsigned long _dest asm("2") = (unsigned long) dest;
register unsigned long _len1 asm("3") = (unsigned long) count;
register unsigned long _src asm("4") = src;
register unsigned long _len2 asm("5") = (unsigned long) count;
if (count == 0)
return 0;
flags = __raw_local_irq_stnsm(0xf8UL); /* switch to real mode */
asm volatile (
"0: mvcle %1,%2,0x0\n"
"1: jo 0b\n"
" lhi %0,0x0\n"
"2:\n"
EX_TABLE(1b,2b)
: "+d" (rc), "+d" (_dest), "+d" (_src), "+d" (_len1),
"+d" (_len2), "=m" (*((long*)dest))
: "m" (*((long*)src))
: "cc", "memory");
__raw_local_irq_ssm(flags);
return rc;
}
static int memcpy_real_user(void __user *dest, unsigned long src, size_t count) static int memcpy_real_user(void __user *dest, unsigned long src, size_t count)
{ {
static char buf[4096]; static char buf[4096];
...@@ -175,7 +148,7 @@ static int memcpy_real_user(void __user *dest, unsigned long src, size_t count) ...@@ -175,7 +148,7 @@ static int memcpy_real_user(void __user *dest, unsigned long src, size_t count)
while (offs < count) { while (offs < count) {
size = min(sizeof(buf), count - offs); size = min(sizeof(buf), count - offs);
if (memcpy_real(buf, src + offs, size)) if (memcpy_real(buf, (void *) src + offs, size))
return -EFAULT; return -EFAULT;
if (copy_to_user(dest + offs, buf, size)) if (copy_to_user(dest + offs, buf, size))
return -EFAULT; return -EFAULT;
...@@ -663,7 +636,7 @@ static int __init zcore_reipl_init(void) ...@@ -663,7 +636,7 @@ static int __init zcore_reipl_init(void)
if (ipib_info.ipib < ZFCPDUMP_HSA_SIZE) if (ipib_info.ipib < ZFCPDUMP_HSA_SIZE)
rc = memcpy_hsa_kernel(ipl_block, ipib_info.ipib, PAGE_SIZE); rc = memcpy_hsa_kernel(ipl_block, ipib_info.ipib, PAGE_SIZE);
else else
rc = memcpy_real(ipl_block, ipib_info.ipib, PAGE_SIZE); rc = memcpy_real(ipl_block, (void *) ipib_info.ipib, PAGE_SIZE);
if (rc) { if (rc) {
free_page((unsigned long) ipl_block); free_page((unsigned long) ipl_block);
return rc; return rc;
......
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