Commit 9ccc2362 authored by Linus Torvalds's avatar Linus Torvalds

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

* 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6:
  [S390] cio: Register/unregister subchannels only from kslowcrw.
  [S390] Add missing die_notifier() call to die().
  [S390] Fix memory detection.
  [S390] Explicitly code allocpercpu calls in iucv
  [S390] Dont overwrite lowcores on smp_send_stop().
  [S390] Optimize storage key handling for anonymous pages
  [S390] Fix kernel preemption.
  [S390] appldata: remove unused binary sysctls.
  [S390] cmm: remove unused binary sysctls.
  [S390] Fix irq tracing and lockdep_sys_exit calls.
  [S390] magic sysrq: check for in_atomic before doing an console_unblank
  [S390] cio: change device sense procedure to work with pav aliases
parents da457d4b c5d4a999
...@@ -45,7 +45,6 @@ struct appldata_ops { ...@@ -45,7 +45,6 @@ struct appldata_ops {
int active; /* monitoring status */ int active; /* monitoring status */
/* fill in from here */ /* fill in from here */
unsigned int ctl_nr; /* sysctl ID */
char name[APPLDATA_PROC_NAME_LENGTH]; /* name of /proc fs node */ char name[APPLDATA_PROC_NAME_LENGTH]; /* name of /proc fs node */
unsigned char record_nr; /* Record Nr. for Product ID */ unsigned char record_nr; /* Record Nr. for Product ID */
void (*callback)(void *data); /* callback function */ void (*callback)(void *data); /* callback function */
......
...@@ -53,29 +53,26 @@ static int appldata_interval_handler(ctl_table *ctl, int write, ...@@ -53,29 +53,26 @@ static int appldata_interval_handler(ctl_table *ctl, int write,
static struct ctl_table_header *appldata_sysctl_header; static struct ctl_table_header *appldata_sysctl_header;
static struct ctl_table appldata_table[] = { static struct ctl_table appldata_table[] = {
{ {
.ctl_name = CTL_APPLDATA_TIMER,
.procname = "timer", .procname = "timer",
.mode = S_IRUGO | S_IWUSR, .mode = S_IRUGO | S_IWUSR,
.proc_handler = &appldata_timer_handler, .proc_handler = &appldata_timer_handler,
}, },
{ {
.ctl_name = CTL_APPLDATA_INTERVAL,
.procname = "interval", .procname = "interval",
.mode = S_IRUGO | S_IWUSR, .mode = S_IRUGO | S_IWUSR,
.proc_handler = &appldata_interval_handler, .proc_handler = &appldata_interval_handler,
}, },
{ .ctl_name = 0 } { },
}; };
static struct ctl_table appldata_dir_table[] = { static struct ctl_table appldata_dir_table[] = {
{ {
.ctl_name = CTL_APPLDATA,
.procname = appldata_proc_name, .procname = appldata_proc_name,
.maxlen = 0, .maxlen = 0,
.mode = S_IRUGO | S_IXUGO, .mode = S_IRUGO | S_IXUGO,
.child = appldata_table, .child = appldata_table,
}, },
{ .ctl_name = 0 } { },
}; };
/* /*
...@@ -441,75 +438,38 @@ out: ...@@ -441,75 +438,38 @@ out:
*/ */
int appldata_register_ops(struct appldata_ops *ops) int appldata_register_ops(struct appldata_ops *ops)
{ {
struct list_head *lh; if ((ops->size > APPLDATA_MAX_REC_SIZE) || (ops->size < 0))
struct appldata_ops *tmp_ops; return -EINVAL;
int i;
i = 0;
if ((ops->size > APPLDATA_MAX_REC_SIZE) || ops->ctl_table = kzalloc(4 * sizeof(struct ctl_table), GFP_KERNEL);
(ops->size < 0)){ if (!ops->ctl_table)
P_ERROR("Invalid size of %s record = %i, maximum = %i!\n",
ops->name, ops->size, APPLDATA_MAX_REC_SIZE);
return -ENOMEM;
}
if ((ops->ctl_nr == CTL_APPLDATA) ||
(ops->ctl_nr == CTL_APPLDATA_TIMER) ||
(ops->ctl_nr == CTL_APPLDATA_INTERVAL)) {
P_ERROR("ctl_nr %i already in use!\n", ops->ctl_nr);
return -EBUSY;
}
ops->ctl_table = kzalloc(4*sizeof(struct ctl_table), GFP_KERNEL);
if (ops->ctl_table == NULL) {
P_ERROR("Not enough memory for %s ctl_table!\n", ops->name);
return -ENOMEM; return -ENOMEM;
}
spin_lock(&appldata_ops_lock); spin_lock(&appldata_ops_lock);
list_for_each(lh, &appldata_ops_list) {
tmp_ops = list_entry(lh, struct appldata_ops, list);
P_DEBUG("register_ops loop: %i) name = %s, ctl = %i\n",
++i, tmp_ops->name, tmp_ops->ctl_nr);
P_DEBUG("Comparing %s (ctl %i) with %s (ctl %i)\n",
tmp_ops->name, tmp_ops->ctl_nr, ops->name,
ops->ctl_nr);
if (strncmp(tmp_ops->name, ops->name,
APPLDATA_PROC_NAME_LENGTH) == 0) {
P_ERROR("Name \"%s\" already registered!\n", ops->name);
kfree(ops->ctl_table);
spin_unlock(&appldata_ops_lock);
return -EBUSY;
}
if (tmp_ops->ctl_nr == ops->ctl_nr) {
P_ERROR("ctl_nr %i already registered!\n", ops->ctl_nr);
kfree(ops->ctl_table);
spin_unlock(&appldata_ops_lock);
return -EBUSY;
}
}
list_add(&ops->list, &appldata_ops_list); list_add(&ops->list, &appldata_ops_list);
spin_unlock(&appldata_ops_lock); spin_unlock(&appldata_ops_lock);
ops->ctl_table[0].ctl_name = CTL_APPLDATA;
ops->ctl_table[0].procname = appldata_proc_name; ops->ctl_table[0].procname = appldata_proc_name;
ops->ctl_table[0].maxlen = 0; ops->ctl_table[0].maxlen = 0;
ops->ctl_table[0].mode = S_IRUGO | S_IXUGO; ops->ctl_table[0].mode = S_IRUGO | S_IXUGO;
ops->ctl_table[0].child = &ops->ctl_table[2]; ops->ctl_table[0].child = &ops->ctl_table[2];
ops->ctl_table[1].ctl_name = 0;
ops->ctl_table[2].ctl_name = ops->ctl_nr;
ops->ctl_table[2].procname = ops->name; ops->ctl_table[2].procname = ops->name;
ops->ctl_table[2].mode = S_IRUGO | S_IWUSR; ops->ctl_table[2].mode = S_IRUGO | S_IWUSR;
ops->ctl_table[2].proc_handler = appldata_generic_handler; ops->ctl_table[2].proc_handler = appldata_generic_handler;
ops->ctl_table[2].data = ops; ops->ctl_table[2].data = ops;
ops->ctl_table[3].ctl_name = 0;
ops->sysctl_header = register_sysctl_table(ops->ctl_table); ops->sysctl_header = register_sysctl_table(ops->ctl_table);
if (!ops->sysctl_header)
goto out;
P_INFO("%s-ops registered!\n", ops->name); P_INFO("%s-ops registered!\n", ops->name);
return 0; return 0;
out:
spin_lock(&appldata_ops_lock);
list_del(&ops->list);
spin_unlock(&appldata_ops_lock);
kfree(ops->ctl_table);
return -ENOMEM;
} }
/* /*
...@@ -519,15 +479,11 @@ int appldata_register_ops(struct appldata_ops *ops) ...@@ -519,15 +479,11 @@ int appldata_register_ops(struct appldata_ops *ops)
*/ */
void appldata_unregister_ops(struct appldata_ops *ops) void appldata_unregister_ops(struct appldata_ops *ops)
{ {
void *table;
spin_lock(&appldata_ops_lock); spin_lock(&appldata_ops_lock);
list_del(&ops->list); list_del(&ops->list);
/* at that point any incoming access will fail */
table = ops->ctl_table;
ops->ctl_table = NULL;
spin_unlock(&appldata_ops_lock); spin_unlock(&appldata_ops_lock);
unregister_sysctl_table(ops->sysctl_header); unregister_sysctl_table(ops->sysctl_header);
kfree(table); kfree(ops->ctl_table);
P_INFO("%s-ops unregistered!\n", ops->name); P_INFO("%s-ops unregistered!\n", ops->name);
} }
/********************** module-ops management <END> **************************/ /********************** module-ops management <END> **************************/
......
...@@ -147,7 +147,6 @@ static void appldata_get_mem_data(void *data) ...@@ -147,7 +147,6 @@ static void appldata_get_mem_data(void *data)
static struct appldata_ops ops = { static struct appldata_ops ops = {
.ctl_nr = CTL_APPLDATA_MEM,
.name = "mem", .name = "mem",
.record_nr = APPLDATA_RECORD_MEM_ID, .record_nr = APPLDATA_RECORD_MEM_ID,
.size = sizeof(struct appldata_mem_data), .size = sizeof(struct appldata_mem_data),
......
...@@ -142,7 +142,6 @@ static void appldata_get_net_sum_data(void *data) ...@@ -142,7 +142,6 @@ static void appldata_get_net_sum_data(void *data)
static struct appldata_ops ops = { static struct appldata_ops ops = {
.ctl_nr = CTL_APPLDATA_NET_SUM,
.name = "net_sum", .name = "net_sum",
.record_nr = APPLDATA_RECORD_NET_SUM_ID, .record_nr = APPLDATA_RECORD_NET_SUM_ID,
.size = sizeof(struct appldata_net_sum_data), .size = sizeof(struct appldata_net_sum_data),
......
...@@ -82,7 +82,6 @@ struct appldata_os_data { ...@@ -82,7 +82,6 @@ struct appldata_os_data {
static struct appldata_os_data *appldata_os_data; static struct appldata_os_data *appldata_os_data;
static struct appldata_ops ops = { static struct appldata_ops ops = {
.ctl_nr = CTL_APPLDATA_OS,
.name = "os", .name = "os",
.record_nr = APPLDATA_RECORD_OS_ID, .record_nr = APPLDATA_RECORD_OS_ID,
.owner = THIS_MODULE, .owner = THIS_MODULE,
......
...@@ -200,7 +200,7 @@ static noinline __init void find_memory_chunks(unsigned long memsize) ...@@ -200,7 +200,7 @@ static noinline __init void find_memory_chunks(unsigned long memsize)
cc = __tprot(addr); cc = __tprot(addr);
while (cc == old_cc) { while (cc == old_cc) {
addr += CHUNK_INCR; addr += CHUNK_INCR;
if (addr >= memsize) if (memsize && addr >= memsize)
break; break;
#ifndef CONFIG_64BIT #ifndef CONFIG_64BIT
if (addr == ADDR2G) if (addr == ADDR2G)
......
...@@ -69,13 +69,31 @@ STACK_SIZE = 1 << STACK_SHIFT ...@@ -69,13 +69,31 @@ STACK_SIZE = 1 << STACK_SHIFT
basr %r14,%r1 basr %r14,%r1
.endm .endm
.macro LOCKDEP_SYS_EXIT .macro TRACE_IRQS_CHECK
l %r1,BASED(.Llockdep_sys_exit) tm SP_PSW(%r15),0x03 # irqs enabled?
jz 0f
l %r1,BASED(.Ltrace_irq_on)
basr %r14,%r1 basr %r14,%r1
j 1f
0: l %r1,BASED(.Ltrace_irq_off)
basr %r14,%r1
1:
.endm .endm
#else #else
#define TRACE_IRQS_ON #define TRACE_IRQS_ON
#define TRACE_IRQS_OFF #define TRACE_IRQS_OFF
#define TRACE_IRQS_CHECK
#endif
#ifdef CONFIG_LOCKDEP
.macro LOCKDEP_SYS_EXIT
tm SP_PSW+1(%r15),0x01 # returning to user ?
jz 0f
l %r1,BASED(.Llockdep_sys_exit)
basr %r14,%r1
0:
.endm
#else
#define LOCKDEP_SYS_EXIT #define LOCKDEP_SYS_EXIT
#endif #endif
...@@ -234,8 +252,6 @@ sysc_saveall: ...@@ -234,8 +252,6 @@ sysc_saveall:
lh %r7,0x8a # get svc number from lowcore lh %r7,0x8a # get svc number from lowcore
#ifdef CONFIG_VIRT_CPU_ACCOUNTING #ifdef CONFIG_VIRT_CPU_ACCOUNTING
sysc_vtime: sysc_vtime:
tm SP_PSW+1(%r15),0x01 # interrupting from user ?
bz BASED(sysc_do_svc)
UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
sysc_stime: sysc_stime:
UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
...@@ -263,19 +279,34 @@ sysc_do_restart: ...@@ -263,19 +279,34 @@ sysc_do_restart:
sysc_return: sysc_return:
tm SP_PSW+1(%r15),0x01 # returning to user ? tm SP_PSW+1(%r15),0x01 # returning to user ?
bno BASED(sysc_leave) bno BASED(sysc_restore)
tm __TI_flags+3(%r9),_TIF_WORK_SVC tm __TI_flags+3(%r9),_TIF_WORK_SVC
bnz BASED(sysc_work) # there is work to do (signals etc.) bnz BASED(sysc_work) # there is work to do (signals etc.)
sysc_restore:
#ifdef CONFIG_TRACE_IRQFLAGS
la %r1,BASED(sysc_restore_trace_psw)
lpsw 0(%r1)
sysc_restore_trace:
TRACE_IRQS_CHECK
LOCKDEP_SYS_EXIT LOCKDEP_SYS_EXIT
#endif
sysc_leave: sysc_leave:
RESTORE_ALL __LC_RETURN_PSW,1 RESTORE_ALL __LC_RETURN_PSW,1
sysc_done:
#ifdef CONFIG_TRACE_IRQFLAGS
.align 8
.globl sysc_restore_trace_psw
sysc_restore_trace_psw:
.long 0, sysc_restore_trace + 0x80000000
#endif
# #
# recheck if there is more work to do # recheck if there is more work to do
# #
sysc_work_loop: sysc_work_loop:
tm __TI_flags+3(%r9),_TIF_WORK_SVC tm __TI_flags+3(%r9),_TIF_WORK_SVC
bz BASED(sysc_leave) # there is no work to do bz BASED(sysc_restore) # there is no work to do
# #
# One of the work bits is on. Find out which one. # One of the work bits is on. Find out which one.
# #
...@@ -290,8 +321,8 @@ sysc_work: ...@@ -290,8 +321,8 @@ sysc_work:
bo BASED(sysc_restart) bo BASED(sysc_restart)
tm __TI_flags+3(%r9),_TIF_SINGLE_STEP tm __TI_flags+3(%r9),_TIF_SINGLE_STEP
bo BASED(sysc_singlestep) bo BASED(sysc_singlestep)
LOCKDEP_SYS_EXIT b BASED(sysc_restore)
b BASED(sysc_leave) sysc_work_done:
# #
# _TIF_NEED_RESCHED is set, call schedule # _TIF_NEED_RESCHED is set, call schedule
...@@ -458,6 +489,7 @@ pgm_check_handler: ...@@ -458,6 +489,7 @@ pgm_check_handler:
pgm_no_vtime: pgm_no_vtime:
#endif #endif
l %r9,__LC_THREAD_INFO # load pointer to thread_info struct l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
TRACE_IRQS_OFF
l %r3,__LC_PGM_ILC # load program interruption code l %r3,__LC_PGM_ILC # load program interruption code
la %r8,0x7f la %r8,0x7f
nr %r8,%r3 nr %r8,%r3
...@@ -497,6 +529,7 @@ pgm_per_std: ...@@ -497,6 +529,7 @@ pgm_per_std:
pgm_no_vtime2: pgm_no_vtime2:
#endif #endif
l %r9,__LC_THREAD_INFO # load pointer to thread_info struct l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
TRACE_IRQS_OFF
l %r1,__TI_task(%r9) l %r1,__TI_task(%r9)
mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS
...@@ -517,15 +550,13 @@ pgm_svcper: ...@@ -517,15 +550,13 @@ pgm_svcper:
SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
#ifdef CONFIG_VIRT_CPU_ACCOUNTING #ifdef CONFIG_VIRT_CPU_ACCOUNTING
tm SP_PSW+1(%r15),0x01 # interrupting from user ?
bz BASED(pgm_no_vtime3)
UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
pgm_no_vtime3:
#endif #endif
lh %r7,0x8a # get svc number from lowcore lh %r7,0x8a # get svc number from lowcore
l %r9,__LC_THREAD_INFO # load pointer to thread_info struct l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
TRACE_IRQS_OFF
l %r1,__TI_task(%r9) l %r1,__TI_task(%r9)
mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS
...@@ -542,7 +573,7 @@ kernel_per: ...@@ -542,7 +573,7 @@ kernel_per:
mvi SP_TRAP+1(%r15),0x28 # set trap indication to pgm check mvi SP_TRAP+1(%r15),0x28 # set trap indication to pgm check
la %r2,SP_PTREGS(%r15) # address of register-save area la %r2,SP_PTREGS(%r15) # address of register-save area
l %r1,BASED(.Lhandle_per) # load adr. of per handler l %r1,BASED(.Lhandle_per) # load adr. of per handler
la %r14,BASED(sysc_leave) # load adr. of system return la %r14,BASED(sysc_restore)# load adr. of system return
br %r1 # branch to do_single_step br %r1 # branch to do_single_step
/* /*
...@@ -569,26 +600,38 @@ io_no_vtime: ...@@ -569,26 +600,38 @@ io_no_vtime:
l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ
la %r2,SP_PTREGS(%r15) # address of register-save area la %r2,SP_PTREGS(%r15) # address of register-save area
basr %r14,%r1 # branch to standard irq handler basr %r14,%r1 # branch to standard irq handler
TRACE_IRQS_ON
io_return: io_return:
tm SP_PSW+1(%r15),0x01 # returning to user ? tm SP_PSW+1(%r15),0x01 # returning to user ?
#ifdef CONFIG_PREEMPT #ifdef CONFIG_PREEMPT
bno BASED(io_preempt) # no -> check for preemptive scheduling bno BASED(io_preempt) # no -> check for preemptive scheduling
#else #else
bno BASED(io_leave) # no-> skip resched & signal bno BASED(io_restore) # no-> skip resched & signal
#endif #endif
tm __TI_flags+3(%r9),_TIF_WORK_INT tm __TI_flags+3(%r9),_TIF_WORK_INT
bnz BASED(io_work) # there is work to do (signals etc.) bnz BASED(io_work) # there is work to do (signals etc.)
io_restore:
#ifdef CONFIG_TRACE_IRQFLAGS
la %r1,BASED(io_restore_trace_psw)
lpsw 0(%r1)
io_restore_trace:
TRACE_IRQS_CHECK
LOCKDEP_SYS_EXIT LOCKDEP_SYS_EXIT
#endif
io_leave: io_leave:
RESTORE_ALL __LC_RETURN_PSW,0 RESTORE_ALL __LC_RETURN_PSW,0
io_done: io_done:
#ifdef CONFIG_TRACE_IRQFLAGS
.align 8
.globl io_restore_trace_psw
io_restore_trace_psw:
.long 0, io_restore_trace + 0x80000000
#endif
#ifdef CONFIG_PREEMPT #ifdef CONFIG_PREEMPT
io_preempt: io_preempt:
icm %r0,15,__TI_precount(%r9) icm %r0,15,__TI_precount(%r9)
bnz BASED(io_leave) bnz BASED(io_restore)
l %r1,SP_R15(%r15) l %r1,SP_R15(%r15)
s %r1,BASED(.Lc_spsize) s %r1,BASED(.Lc_spsize)
mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
...@@ -596,14 +639,10 @@ io_preempt: ...@@ -596,14 +639,10 @@ io_preempt:
lr %r15,%r1 lr %r15,%r1
io_resume_loop: io_resume_loop:
tm __TI_flags+3(%r9),_TIF_NEED_RESCHED tm __TI_flags+3(%r9),_TIF_NEED_RESCHED
bno BASED(io_leave) bno BASED(io_restore)
mvc __TI_precount(4,%r9),BASED(.Lc_pactive) l %r1,BASED(.Lpreempt_schedule_irq)
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts la %r14,BASED(io_resume_loop)
l %r1,BASED(.Lschedule) br %r1 # call schedule
basr %r14,%r1 # call schedule
stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
xc __TI_precount(4,%r9),__TI_precount(%r9)
b BASED(io_resume_loop)
#endif #endif
# #
...@@ -627,40 +666,42 @@ io_work_loop: ...@@ -627,40 +666,42 @@ io_work_loop:
bo BASED(io_reschedule) bo BASED(io_reschedule)
tm __TI_flags+3(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK) tm __TI_flags+3(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)
bnz BASED(io_sigpending) bnz BASED(io_sigpending)
LOCKDEP_SYS_EXIT b BASED(io_restore)
b BASED(io_leave) io_work_done:
# #
# _TIF_MCCK_PENDING is set, call handler # _TIF_MCCK_PENDING is set, call handler
# #
io_mcck_pending: io_mcck_pending:
TRACE_IRQS_OFF
l %r1,BASED(.Ls390_handle_mcck) l %r1,BASED(.Ls390_handle_mcck)
basr %r14,%r1 # TIF bit will be cleared by handler basr %r14,%r1 # TIF bit will be cleared by handler
TRACE_IRQS_ON
b BASED(io_work_loop) b BASED(io_work_loop)
# #
# _TIF_NEED_RESCHED is set, call schedule # _TIF_NEED_RESCHED is set, call schedule
# #
io_reschedule: io_reschedule:
TRACE_IRQS_ON
l %r1,BASED(.Lschedule) l %r1,BASED(.Lschedule)
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
basr %r14,%r1 # call scheduler basr %r14,%r1 # call scheduler
stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
TRACE_IRQS_OFF
tm __TI_flags+3(%r9),_TIF_WORK_INT tm __TI_flags+3(%r9),_TIF_WORK_INT
bz BASED(io_leave) # there is no work to do bz BASED(io_restore) # there is no work to do
b BASED(io_work_loop) b BASED(io_work_loop)
# #
# _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal # _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal
# #
io_sigpending: io_sigpending:
TRACE_IRQS_ON
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
la %r2,SP_PTREGS(%r15) # load pt_regs la %r2,SP_PTREGS(%r15) # load pt_regs
l %r1,BASED(.Ldo_signal) l %r1,BASED(.Ldo_signal)
basr %r14,%r1 # call do_signal basr %r14,%r1 # call do_signal
stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
TRACE_IRQS_OFF
b BASED(io_work_loop) b BASED(io_work_loop)
/* /*
...@@ -688,7 +729,6 @@ ext_no_vtime: ...@@ -688,7 +729,6 @@ ext_no_vtime:
lh %r3,__LC_EXT_INT_CODE # get interruption code lh %r3,__LC_EXT_INT_CODE # get interruption code
l %r1,BASED(.Ldo_extint) l %r1,BASED(.Ldo_extint)
basr %r14,%r1 basr %r14,%r1
TRACE_IRQS_ON