mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-26 00:21:17 +00:00
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
This commit is contained in:
commit
c27b9a2e6c
12 changed files with 59 additions and 56 deletions
|
@ -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)
|
||||||
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);
|
||||||
#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)
|
||||||
" 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)
|
||||||
" 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:
|
||||||
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:
|
||||||
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:
|
||||||
.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)
|
||||||
* 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)
|
||||||
#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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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,
|
||||||
|
|
||||||
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,
|
||||||
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 {
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue