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] s390: fix single stepping on svc0 [S390] sclp: undo quiesce handler override on resume [S390] reset cputime accounting after IPL from NSS [S390] monreader: fix use after free bug with suspend/resume
This commit is contained in:
Коммит
0283243849
|
@ -55,6 +55,7 @@ static void __init reset_tod_clock(void)
|
||||||
disabled_wait(0);
|
disabled_wait(0);
|
||||||
|
|
||||||
sched_clock_base_cc = TOD_UNIX_EPOCH;
|
sched_clock_base_cc = TOD_UNIX_EPOCH;
|
||||||
|
S390_lowcore.last_update_clock = sched_clock_base_cc;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SHARED_KERNEL
|
#ifdef CONFIG_SHARED_KERNEL
|
||||||
|
@ -167,6 +168,14 @@ static noinline __init void create_kernel_nss(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* re-initialize cputime accounting. */
|
||||||
|
sched_clock_base_cc = get_clock();
|
||||||
|
S390_lowcore.last_update_clock = sched_clock_base_cc;
|
||||||
|
S390_lowcore.last_update_timer = 0x7fffffffffffffffULL;
|
||||||
|
S390_lowcore.user_timer = 0;
|
||||||
|
S390_lowcore.system_timer = 0;
|
||||||
|
asm volatile("SPT 0(%0)" : : "a" (&S390_lowcore.last_update_timer));
|
||||||
|
|
||||||
/* re-setup boot command line with new ipl vm parms */
|
/* re-setup boot command line with new ipl vm parms */
|
||||||
ipl_update_parameters();
|
ipl_update_parameters();
|
||||||
setup_boot_command_line();
|
setup_boot_command_line();
|
||||||
|
|
|
@ -565,10 +565,10 @@ pgm_svcper:
|
||||||
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
|
TRACE_IRQS_OFF
|
||||||
l %r1,__TI_task(%r9)
|
l %r8,__TI_task(%r9)
|
||||||
mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
|
mvc __THREAD_per+__PER_atmid(2,%r8),__LC_PER_ATMID
|
||||||
mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS
|
mvc __THREAD_per+__PER_address(4,%r8),__LC_PER_ADDRESS
|
||||||
mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
|
mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID
|
||||||
oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
|
oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
|
||||||
TRACE_IRQS_ON
|
TRACE_IRQS_ON
|
||||||
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
|
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
|
||||||
|
|
|
@ -543,10 +543,10 @@ pgm_svcper:
|
||||||
mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
|
mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
|
||||||
llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore
|
llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore
|
||||||
lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
|
lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
|
||||||
lg %r1,__TI_task(%r9)
|
lg %r8,__TI_task(%r9)
|
||||||
mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
|
mvc __THREAD_per+__PER_atmid(2,%r8),__LC_PER_ATMID
|
||||||
mvc __THREAD_per+__PER_address(8,%r1),__LC_PER_ADDRESS
|
mvc __THREAD_per+__PER_address(8,%r8),__LC_PER_ADDRESS
|
||||||
mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
|
mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID
|
||||||
oi __TI_flags+7(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
|
oi __TI_flags+7(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
|
||||||
TRACE_IRQS_ON
|
TRACE_IRQS_ON
|
||||||
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
|
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
|
||||||
|
|
|
@ -357,6 +357,7 @@ static int mon_close(struct inode *inode, struct file *filp)
|
||||||
atomic_set(&monpriv->msglim_count, 0);
|
atomic_set(&monpriv->msglim_count, 0);
|
||||||
monpriv->write_index = 0;
|
monpriv->write_index = 0;
|
||||||
monpriv->read_index = 0;
|
monpriv->read_index = 0;
|
||||||
|
dev_set_drvdata(monreader_device, NULL);
|
||||||
|
|
||||||
for (i = 0; i < MON_MSGLIM; i++)
|
for (i = 0; i < MON_MSGLIM; i++)
|
||||||
kfree(monpriv->msg_array[i]);
|
kfree(monpriv->msg_array[i]);
|
||||||
|
|
|
@ -20,9 +20,12 @@
|
||||||
|
|
||||||
#include "sclp.h"
|
#include "sclp.h"
|
||||||
|
|
||||||
|
static void (*old_machine_restart)(char *);
|
||||||
|
static void (*old_machine_halt)(void);
|
||||||
|
static void (*old_machine_power_off)(void);
|
||||||
|
|
||||||
/* Shutdown handler. Signal completion of shutdown by loading special PSW. */
|
/* Shutdown handler. Signal completion of shutdown by loading special PSW. */
|
||||||
static void
|
static void do_machine_quiesce(void)
|
||||||
do_machine_quiesce(void)
|
|
||||||
{
|
{
|
||||||
psw_t quiesce_psw;
|
psw_t quiesce_psw;
|
||||||
|
|
||||||
|
@ -33,23 +36,48 @@ do_machine_quiesce(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handler for quiesce event. Start shutdown procedure. */
|
/* Handler for quiesce event. Start shutdown procedure. */
|
||||||
static void
|
static void sclp_quiesce_handler(struct evbuf_header *evbuf)
|
||||||
sclp_quiesce_handler(struct evbuf_header *evbuf)
|
|
||||||
{
|
{
|
||||||
_machine_restart = (void *) do_machine_quiesce;
|
if (_machine_restart != (void *) do_machine_quiesce) {
|
||||||
_machine_halt = do_machine_quiesce;
|
old_machine_restart = _machine_restart;
|
||||||
_machine_power_off = do_machine_quiesce;
|
old_machine_halt = _machine_halt;
|
||||||
|
old_machine_power_off = _machine_power_off;
|
||||||
|
_machine_restart = (void *) do_machine_quiesce;
|
||||||
|
_machine_halt = do_machine_quiesce;
|
||||||
|
_machine_power_off = do_machine_quiesce;
|
||||||
|
}
|
||||||
ctrl_alt_del();
|
ctrl_alt_del();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Undo machine restart/halt/power_off modification on resume */
|
||||||
|
static void sclp_quiesce_pm_event(struct sclp_register *reg,
|
||||||
|
enum sclp_pm_event sclp_pm_event)
|
||||||
|
{
|
||||||
|
switch (sclp_pm_event) {
|
||||||
|
case SCLP_PM_EVENT_RESTORE:
|
||||||
|
if (old_machine_restart) {
|
||||||
|
_machine_restart = old_machine_restart;
|
||||||
|
_machine_halt = old_machine_halt;
|
||||||
|
_machine_power_off = old_machine_power_off;
|
||||||
|
old_machine_restart = NULL;
|
||||||
|
old_machine_halt = NULL;
|
||||||
|
old_machine_power_off = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SCLP_PM_EVENT_FREEZE:
|
||||||
|
case SCLP_PM_EVENT_THAW:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static struct sclp_register sclp_quiesce_event = {
|
static struct sclp_register sclp_quiesce_event = {
|
||||||
.receive_mask = EVTYP_SIGQUIESCE_MASK,
|
.receive_mask = EVTYP_SIGQUIESCE_MASK,
|
||||||
.receiver_fn = sclp_quiesce_handler
|
.receiver_fn = sclp_quiesce_handler,
|
||||||
|
.pm_event_fn = sclp_quiesce_pm_event
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Initialize quiesce driver. */
|
/* Initialize quiesce driver. */
|
||||||
static int __init
|
static int __init sclp_quiesce_init(void)
|
||||||
sclp_quiesce_init(void)
|
|
||||||
{
|
{
|
||||||
return sclp_register(&sclp_quiesce_event);
|
return sclp_register(&sclp_quiesce_event);
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче