• Mahesh Salgaonkar's avatar
    powerpc/book3s: handle machine check in Linux host. · 1e9b4507
    Mahesh Salgaonkar authored
    Move machine check entry point into Linux. So far we were dependent on
    firmware to decode MCE error details and handover the high level info to OS.
    
    This patch introduces early machine check routine that saves the MCE
    information (srr1, srr0, dar and dsisr) to the emergency stack. We allocate
    stack frame on emergency stack and set the r1 accordingly. This allows us to be
    prepared to take another exception without loosing context. One thing to note
    here that, if we get another machine check while ME bit is off then we risk a
    checkstop. Hence we restrict ourselves to save only MCE information and
    register saved on PACA_EXMC save are before we turn the ME bit on. We use
    paca->in_mce flag to differentiate between first entry and nested machine check
    entry which helps proper use of emergency stack. We increment paca->in_mce
    every time we enter in early machine check handler and decrement it while
    leaving. When we enter machine check early handler first time (paca->in_mce ==
    0), we are sure nobody is using MC emergency stack and allocate a stack frame
    at the start of the emergency stack. During subsequent entry (paca->in_mce >
    0), we know that r1 points inside emergency stack and we allocate separate
    stack frame accordingly. This prevents us from clobbering MCE information
    during nested machine checks.
    
    The early machine check handler changes are placed under CPU_FTR_HVMODE
    section. This makes sure that the early machine check handler will get executed
    only in hypervisor kernel.
    
    This is the code flow:
    
    		Machine Check Interrupt
    			|
    			V
    		   0x200 vector				  ME=0, IR=0, DR=0
    			|
    			V
    	+-----------------------------------------------+
    	|machine_check_pSeries_early:			| ME=0, IR=0, DR=0
    	|	Alloc frame on emergency stack		|
    	|	Save srr1, srr0, dar and dsisr on stack |
    	+-----------------------------------------------+
    			|
    		(ME=1, IR=0, DR=0, RFID)
    			|
    			V
    		machine_check_handle_early		  ME=1, IR=0, DR=0
    			|
    			V
    	+-----------------------------------------------+
    	|	machine_check_early (r3=pt_regs)	| ME=1, IR=0, DR=0
    	|	Things to do: (in next patches)		|
    	|		Flush SLB for SLB errors	|
    	|		Flush TLB for TLB errors	|
    	|		Decode and save MCE info	|
    	+-----------------------------------------------+
    			|
    	(Fall through existing exception handler routine.)
    			|
    			V
    		machine_check_pSerie			  ME=1, IR=0, DR=0
    			|
    		(ME=1, IR=1, DR=1, RFID)
    			|
    			V
    		machine_check_common			  ME=1, IR=1, DR=1
    			.
    			.
    			.
    Signed-off-by: default avatarMahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
    Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
    1e9b4507
exceptions-64s.S 43.7 KB