Messages in this thread | | | Date | Fri, 16 Jul 2010 16:53:38 -0600 | Subject | Re: [patch 2/2] x86 NMI-safe INT3 and Page Fault | From | Jeffrey Merkey <> |
| |
> > Well, the way I handled this problem on NetWare SMP and that other > kernel was to create a pool of TSS descriptors and reload each during > the exception to swap stacks before any handlers were called. Allowed > it to nest until I ran out of TSS descriptors (64 levels). Not sure > that's the way to go here though but it worked on that case. > > Jeff >
Here is where that old dusty code lives these days - it deals with this problem.
http://open-source-netware.googlecode.com/files/manos-06-26-2010.tar.gz
file to look at is startup.386
; ; nmi entry code ;
nmi_entry macro cli push ebx push ebp mov ebp, esp sub ebp, SIZE TaskStateSegment mov ebx, ebp
mov [ebp].tSS, ss mov [ebp].tGS, gs ; save segment registers mov [ebp].tFS, fs mov [ebp].tES, es mov [ebp].tDS, ds pop [ebp].tEBP mov [ebp].tEDI, edi mov [ebp].tESI, esi mov [ebp].tEDX, edx mov [ebp].tECX, ecx pop [ebp].tEBX mov [ebp].tEAX, eax
pop [ebp].tEIP ; remove return address pop eax mov [ebp].tCS, ax pop [ebp].tSystemFlags ; get flags into TSS
mov [ebp].tESP, esp ; save true stack address mov esp, ebx ; cover stack frame
mov eax, CR0 and eax, 0FFFFFFF7h ; clear task switch bit in CR0 to mov CR0, eax ; avoid NPX exceptions
xor eax, eax mov dr7, eax ; disable breakpoints
mov eax, CR3 ; mov [ebp].tCR3, eax ; mov eax, DebuggerPDE mov CR3, eax
; ; if we do not clear the NESTED_TASK_FLAG, then the IRET ; at the end of this function will cause ; an invalid TSS exception to be generated because the ; task busy bit was cleared earlier ;
pushfd and dword ptr [esp], NOT (NESTED_TASK_FLAG OR SINGLE_STEP_FLAG) or dword ptr [esp], RESUME_FLAG popfd
mov eax, 0FFFFFFFFh ; mark as a non-pooled TSS exception push eax
push 0 push 0 push ebp
endm
; ; TSS entry code ;
task_entry macro LOCAL @TSSNotNested, @NoLTR LOCAL @UsedDefaultSegment LOCAL @UsedPooledSegment LOCAL @EnterTheDebugger
cli xor eax, eax str ax mov esi, offset SystemGDTTable mov esi, dword ptr [esi + 2] lea ebx, [esi + eax] mov al, [ebx].TSSBase2 mov ah, [ebx].TSSBase3 shl eax, 16 mov ax, [ebx].TSSBase1
; ; eax -> TSS Segment (Current) ; ebx -> TSS Descriptor (Current) ;
movzx ecx, word ptr [eax].tBackLink or ecx, ecx jz @TSSNotNested
mov esi, offset SystemGDTTable mov esi, dword ptr [esi + 2] lea edx, [esi + ecx] mov cl, [edx].TSSBase2 mov ch, [edx].TSSBase3 shl ecx, 16 mov cx, [edx].TSSBase1
mov ebp, ecx
; ; edx -> TSS Descriptor (Previous) ; ebp -> TSS Segment (Previous) ; ; clear busy state and reset TSS ;
mov [edx].TSSType, 10001001b
@TSSNotNested: mov [ebx].TSSType, 10001001b
lgdt ds: SystemGDTTable ; reset GDT TSS Busy bit
movzx eax, word ptr [eax].tBackLink or eax, eax jz @NoLTR
ltr ax
@NoLTR:
mov eax, CR0 and eax, 0FFFFFFF7h ; clear task switch bit in CR0 to mov CR0, eax ; avoid NPX exceptions
xor eax, eax mov dr7, eax ; disable breakpoints
pushfd and dword ptr [esp], NOT (NESTED_TASK_FLAG OR SINGLE_STEP_FLAG) or dword ptr [esp], RESUME_FLAG popfd
push ebp call AllocPooledResource pop ebp
or eax, eax jz @UsedDefaultSegment
lea ebp, [eax].TSSSegment mov esp, [eax].StackTop
push eax ; push address of pooled resource jmp @UsedPooledSegment
@UsedDefaultSegment: mov eax, 0FFFFFFFFh ; push non-pooled marker onto the stack push eax
@UsedPooledSegment:
push 0 mov eax, CR2 ; get fault address push eax push ebp ; pass the TSS
endm
; ; TSS exit code ;
Jeff -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |