Example #1
0
/*
 * machine check handler.
 */
void
s390_do_machine_check(void)
{
    struct mci *mci;

    mci = (struct mci *) &S390_lowcore.mcck_interruption_code;

    if (mci->sd)		/* system damage */
        s390_handle_damage("received system damage machine check\n");

    if (mci->pd)		/* instruction processing damage */
        s390_handle_damage("received instruction processing "
                           "damage machine check\n");

    if (mci->se)		/* storage error uncorrected */
        s390_handle_damage("received storage error uncorrected "
                           "machine check\n");

    if (mci->sc)		/* storage error corrected */
        printk(KERN_WARNING
               "received storage error corrected machine check\n");

    if (mci->ke)		/* storage key-error uncorrected */
        s390_handle_damage("received storage key-error uncorrected "
                           "machine check\n");

    if (mci->ds && mci->fa)	/* storage degradation */
        s390_handle_damage("received storage degradation machine "
                           "check\n");

    if (mci->cp)		/* channel report word pending */
        up(&m_sem);

#ifdef CONFIG_MACHCHK_WARNING
    /*
     * The warning may remain for a prolonged period on the bare iron.
     * (actually till the machine is powered off, or until the problem is gone)
     * So we just stop listening for the WARNING MCH and prevent continuously
     * being interrupted.  One caveat is however, that we must do this per
     * processor and cannot use the smp version of ctl_clear_bit().
     * On VM we only get one interrupt per virtally presented machinecheck.
     * Though one suffices, we may get one interrupt per (virtual) processor.
     */
    if (mci->w) {	/* WARNING pending ? */
        static int mchchk_wng_posted = 0;
        /*
         * Use single machine clear, as we cannot handle smp right now
         */
        __ctl_clear_bit(14, 24);	/* Disable WARNING MCH */
        if (xchg(&mchchk_wng_posted, 1) == 0)
            kill_proc(1, SIGPWR, 1);
    }
#endif
}
Example #2
0
/*
 * s390_do_machine_check
 *
 * mchine check pre-processor, collecting the machine check info,
 *  queueing it and posting the machine check handler for processing.
 */
void s390_do_machine_check( void )
{
	int      crw_count;
	mcic_t   mcic;
        trapid_t ltt_interruption_code;
        uint32_t ltt_old_psw;

#ifdef S390_MACHCHK_DEBUG
	printk( KERN_INFO "s390_do_machine_check : starting ...\n");
#endif

	memcpy( &mcic,
	        &S390_lowcore.mcck_interruption_code,
	        sizeof(__u64));
	memcpy( &ltt_interruption_code,
	        &S390_lowcore.mcck_interruption_code,
	        sizeof(__u64));
	memcpy( &ltt_old_psw,
	        &S390_lowcore.mcck_old_psw,
	        sizeof(uint32_t));
        ltt_old_psw &=  PSW_ADDR_MASK;
        TRACE_TRAP_ENTRY(ltt_interruption_code,ltt_old_psw);
 		
	if (mcic.mcc.mcd.sd) /* system damage */
		s390_handle_damage("received system damage machine check\n");

	if (mcic.mcc.mcd.pd) /* instruction processing damage */
		s390_handle_damage("received instruction processing damage machine check\n");

	if (mcic.mcc.mcd.se) /* storage error uncorrected */
		s390_handle_damage("received storage error uncorrected machine check\n");

	if (mcic.mcc.mcd.sc) /* storage error corrected */
		printk(KERN_WARNING "received storage error corrected machine check\n");

	if (mcic.mcc.mcd.ke) /* storage key-error uncorrected */
		s390_handle_damage("received storage key-error uncorrected machine check\n");

	if (mcic.mcc.mcd.ds && mcic.mcc.mcd.fa) /* storage degradation */
		s390_handle_damage("received storage degradation machine check\n");

	if ( mcic.mcc.mcd.cp )	// CRW pending ?
	{
		crw_count = s390_collect_crw_info();

		if ( crw_count )
		{
			up( &s_sem );

		} /* endif */

	} /* endif */
#ifdef CONFIG_MACHCHK_WARNING
/*
 * The warning may remain for a prolonged period on the bare iron.
 * (actually till the machine is powered off, or until the problem is gone)
 * So we just stop listening for the WARNING MCH and prevent continuously
 * being interrupted.  One caveat is however, that we must do this per 
 * processor and cannot use the smp version of ctl_clear_bit().
 * On VM we only get one interrupt per virtally presented machinecheck.
 * Though one suffices, we may get one interrupt per (virtual) processor. 
 */
	if ( mcic.mcc.mcd.w )	// WARNING pending ?
	{
		// Use single machine clear, as we cannot handle smp right now
		__ctl_clear_bit( 14, 24 );	// Disable WARNING MCH

		if ( ! mchchk_wng_posted )
		{ 
			mchchk_wng_posted = s390_post_warning();

			if ( mchchk_wng_posted )
			{
				up( &s_sem );

			} /* endif */

		} /* endif */

	} /* endif */
#endif

#ifdef S390_MACHCHK_DEBUG
	printk( KERN_INFO "s390_do_machine_check : done \n");
#endif

	return;
}