From d6d858c4b7f0311f1c4d3b5d410ce87b1a261538 Mon Sep 17 00:00:00 2001 From: xli24 Date: Fri, 30 Jul 2010 01:49:51 +0000 Subject: [PATCH] Fix the risk of AP stack conflict. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10714 6f19259b-4bc3-4df7-8a09-765794883524 --- .../IA32/AsmInclude.inc | 2 +- .../IA32/MpFuncs.S | 38 +++++++++------- .../IA32/MpFuncs.asm | 36 ++++++++------- .../MpServicesOnFrameworkMpServicesThunk.c | 36 ++++++--------- .../MpServicesOnFrameworkMpServicesThunk.h | 1 + .../X64/AsmInclude.inc | 1 + .../X64/MpFuncs.S | 45 ++++++++++--------- .../X64/MpFuncs.asm | 36 ++++++++------- 8 files changed, 99 insertions(+), 96 deletions(-) diff --git a/EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/IA32/AsmInclude.inc b/EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/IA32/AsmInclude.inc index d396726bfe..ab2443c79e 100644 --- a/EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/IA32/AsmInclude.inc +++ b/EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/IA32/AsmInclude.inc @@ -22,5 +22,5 @@ RendezvousProc equ LockLocation + 0Ch GdtrProfile equ LockLocation + 10h IdtrProfile equ LockLocation + 16h BufferStart equ LockLocation + 1Ch - +ProcessorNumber equ LockLocation + 20h ;------------------------------------------------------------------------------- diff --git a/EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/IA32/MpFuncs.S b/EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/IA32/MpFuncs.S index 1ddf11518f..f1b6bc391a 100644 --- a/EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/IA32/MpFuncs.S +++ b/EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/IA32/MpFuncs.S @@ -22,6 +22,7 @@ #define GdtrProfile RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x10 #define IdtrProfile RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x16 #define BufferStart RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x1C +#define ProcessorNumber, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x20 #------------------------------------------------------------------------------------- #RendezvousFunnelProc procedure follows. All APs execute their procedure. This @@ -94,30 +95,33 @@ ProtectedModeStart: # protected mode entry point .byte 0x66 movw %ax,%ss # Flat mode setup. - + # + # ProgramStack + # + movl $0x1b, %ecx + rdmsr + andl $0xfffff000, %eax + addl $0x20, %eax + movl (%eax), %ebx + shrl $24, %ebx + + xorl %ecx, %ecx movl %esi,%edi - addl $LockLocation, %edi - movb $NotVacantFlag, %al -TestLock: - xchgb (%edi), %al - cmpb $NotVacantFlag, %al - jz TestLock - -ProgramStack: + addl $ProcessorNumber, %edi + movl (%edi, %ebx, 4), %ecx + movl %esi,%edi addl $StackSize, %edi movl (%edi), %eax + incl %ecx + mull %ecx + movl %esi,%edi addl $StackStart, %edi - addl (%edi), %eax - movl %eax,%esp - movl %eax, (%edi) + movl (%edi), %ebx + addl %ebx, %eax -Releaselock: - movb $VacantFlag, %al - movl %esi,%edi - addl $LockLocation, %edi - xchgb (%edi), %al + movl %eax, %esp # # Call C Function diff --git a/EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/IA32/MpFuncs.asm b/EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/IA32/MpFuncs.asm index e5f38a6bbe..13f2bb74d2 100644 --- a/EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/IA32/MpFuncs.asm +++ b/EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/IA32/MpFuncs.asm @@ -85,31 +85,33 @@ ProtectedModeStart:: ; protected mode entry point mov gs, ax mov ss, ax ; Flat mode setup. - + ; + ; ProgramStack + ; + mov ecx, 1bh ; Read IA32_APIC_BASE MSR + rdmsr + and eax, 0fffff000h + add eax, 20h + mov ebx, dword ptr [eax] + shr ebx, 24 + + xor ecx, ecx mov edi, esi - add edi, LockLocation - mov al, NotVacantFlag -TestLock:: - xchg byte ptr [edi], al - cmp al, NotVacantFlag - jz TestLock - -ProgramStack:: + add edi, ProcessorNumber + mov ecx, dword ptr [edi + 4 * ebx] ; ECX = CpuNumber mov edi, esi add edi, StackSize mov eax, dword ptr [edi] + inc ecx + mul ecx ; EAX = StackSize * (CpuNumber + 1) + mov edi, esi add edi, StackStart - add eax, dword ptr [edi] - mov esp, eax - mov dword ptr [edi], eax + mov ebx, dword ptr [edi] + add eax, ebx ; EAX = StackStart + StackSize * (CpuNumber + 1) -Releaselock:: - mov al, VacantFlag - mov edi, esi - add edi, LockLocation - xchg byte ptr [edi], al + mov esp, eax ; ; Call C Function diff --git a/EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/MpServicesOnFrameworkMpServicesThunk.c b/EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/MpServicesOnFrameworkMpServicesThunk.c index f3db9f6b7c..479362dd87 100644 --- a/EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/MpServicesOnFrameworkMpServicesThunk.c +++ b/EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/MpServicesOnFrameworkMpServicesThunk.c @@ -22,7 +22,6 @@ EFI_HANDLE mHandle = NULL; MP_SYSTEM_DATA mMPSystemData; EFI_PHYSICAL_ADDRESS mStartupVector; MP_CPU_EXCHANGE_INFO *mExchangeInfo; -VOID *mStackStartAddress; BOOLEAN mStopCheckAPsStatus = FALSE; UINTN mNumberOfProcessors; EFI_GENERIC_MEMORY_TEST_PROTOCOL *mGenMemoryTest; @@ -1254,14 +1253,14 @@ ApProcWrapper ( This function sends INIT-SIPI-SIPI to AP, and assign procedure specified by ApFunction. - @param Broadcast If TRUE, broadcase IPI to all APs; otherwise, send to specified AP. - @param ApicID The Local APIC ID of the specified AP. If Broadcast is TRUE, it is ignored. - @param ApFunction The procedure for AP to work on. + @param ProcessorNumber The processor number of the specified AP. + @param ApicID The Local APIC ID of the specified AP. + @param ApFunction The procedure for AP to work on. **/ VOID SendInitSipiSipi ( - IN BOOLEAN Broadcast, + IN UINTN ProcessorNumber, IN UINT32 ApicID, IN VOID *ApFunction ) @@ -1274,15 +1273,10 @@ SendInitSipiSipi ( UINT32 DeliveryMode; mExchangeInfo->ApFunction = ApFunction; - mExchangeInfo->StackStart = mStackStartAddress; + mExchangeInfo->ProcessorNumber[ApicID] = (UINT32) ProcessorNumber; - if (Broadcast) { - ICRHigh = 0; - ICRLow = BROADCAST_MODE_ALL_EXCLUDING_SELF_BIT | TRIGGER_MODE_LEVEL_BIT | ASSERT_BIT; - } else { - ICRHigh = ApicID << 24; - ICRLow = SPECIFY_CPU_MODE_BIT | TRIGGER_MODE_LEVEL_BIT | ASSERT_BIT; - } + ICRHigh = ApicID << 24; + ICRLow = SPECIFY_CPU_MODE_BIT | TRIGGER_MODE_LEVEL_BIT | ASSERT_BIT; VectorNumber = 0; DeliveryMode = DELIVERY_MODE_INIT; @@ -1300,11 +1294,7 @@ SendInitSipiSipi ( VectorNumber = (UINT32) RShiftU64 (mStartupVector, 12); DeliveryMode = DELIVERY_MODE_SIPI; - if (Broadcast) { - ICRLow = BROADCAST_MODE_ALL_EXCLUDING_SELF_BIT | TRIGGER_MODE_LEVEL_BIT | ASSERT_BIT; - } else { - ICRLow = SPECIFY_CPU_MODE_BIT | TRIGGER_MODE_LEVEL_BIT | ASSERT_BIT; - } + ICRLow = SPECIFY_CPU_MODE_BIT | TRIGGER_MODE_LEVEL_BIT | ASSERT_BIT; ICRLow |= VectorNumber | (DeliveryMode << 8); @@ -1358,7 +1348,7 @@ WakeUpAp ( ASSERT_EFI_ERROR (Status); SendInitSipiSipi ( - FALSE, + ProcessorNumber, (UINT32) ProcessorInfoBuffer.ProcessorId, (VOID *) (UINTN) ApProcWrapper ); @@ -1390,7 +1380,7 @@ ResetProcessorToIdleState ( ASSERT_EFI_ERROR (Status); SendInitSipiSipi ( - FALSE, + ProcessorNumber, (UINT32) ProcessorInfoBuffer.ProcessorId, NULL ); @@ -1601,7 +1591,7 @@ PrepareAPStartupVector ( ZeroMem ((VOID *) mExchangeInfo, sizeof (MP_CPU_EXCHANGE_INFO)); - mStackStartAddress = AllocatePages (EFI_SIZE_TO_PAGES (MAX_CPU_NUMBER * AP_STACK_SIZE)); + mExchangeInfo->StackStart = AllocatePages (EFI_SIZE_TO_PAGES (mNumberOfProcessors * AP_STACK_SIZE)); mExchangeInfo->StackSize = AP_STACK_SIZE; AsmReadGdtr (&GdtrForBSP); @@ -1711,8 +1701,6 @@ InitializeMpServicesProtocol ( { EFI_STATUS Status; - PrepareMemoryForConfiguration (); - // // Locates Framework version MP Services Protocol // @@ -1734,6 +1722,8 @@ InitializeMpServicesProtocol ( ASSERT_EFI_ERROR (Status); ASSERT (mNumberOfProcessors < MAX_CPU_NUMBER); + PrepareMemoryForConfiguration (); + // // Create timer event to check AP state for non-blocking execution. // diff --git a/EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/MpServicesOnFrameworkMpServicesThunk.h b/EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/MpServicesOnFrameworkMpServicesThunk.h index 8c98300a75..28be5b17d3 100644 --- a/EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/MpServicesOnFrameworkMpServicesThunk.h +++ b/EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/MpServicesOnFrameworkMpServicesThunk.h @@ -72,6 +72,7 @@ typedef struct { IA32_DESCRIPTOR IdtrProfile; UINT32 BufferStart; UINT32 Cr3; + UINT32 ProcessorNumber[MAX_CPU_NUMBER]; } MP_CPU_EXCHANGE_INFO; typedef struct { diff --git a/EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/X64/AsmInclude.inc b/EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/X64/AsmInclude.inc index d0269760a6..b0e611108f 100644 --- a/EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/X64/AsmInclude.inc +++ b/EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/X64/AsmInclude.inc @@ -23,5 +23,6 @@ GdtrLocation equ LockLocation + 20h IdtrLocation equ LockLocation + 2Ah BufferStartLocation equ LockLocation + 34h Cr3OffsetLocation equ LockLocation + 38h +ProcessorNumberLocation equ LockLocation + 3Ch ;------------------------------------------------------------------------------- diff --git a/EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/X64/MpFuncs.S b/EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/X64/MpFuncs.S index 8efd2d183e..5ec90bdaac 100644 --- a/EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/X64/MpFuncs.S +++ b/EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/X64/MpFuncs.S @@ -24,6 +24,7 @@ .equ IdtrLocation, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x2A .equ BufferStartLocation, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x34 .equ Cr3OffsetLocation, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x38 +.equ ProcessorNumberLocation, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x38 #------------------------------------------------------------------------------------- @@ -128,31 +129,33 @@ LongModeStart: .byte 0x66 movw %ax,%ss - movl %esi, %edi - addl $LockLocation, %edi - movb $NotVacantFlag, %al -TestLock: - xchgb (%edi), %al - cmpb $NotVacantFlag, %al - jz TestLock - -ProgramStack: + # + # ProgramStack + # + movl $0x1b, %ecx + rdmsr + andl $0xfffff000, %eax + addl $0x20, %eax + movl (%eax), %ebx + shrl $24, %ebx + + xorq %rcx, %rcx + movl %esi,%edi + addl $ProcessorNumberLocation, %edi + movl (%edi, %ebx, 4), %ecx - movl %esi, %edi - addl $StackSizeLocation, %edi + movl %esi,%edi + addl $StackSizeLocation, %edi movq (%edi), %rax - movl %esi, %edi - addl $StackStartAddressLocation, %edi - addq (%edi), %rax - movq %rax, %rsp - movq %rax, (%edi) + incq %rcx + mulq %rcx -Releaselock: + movl %esi,%edi + addl $StackStartAddressLocation, %edi + movq (%edi), %rbx + addq %rbx, %rax - movb $VacantFlag, %al - movl %esi, %edi - addl $LockLocation, %edi - xchgb (%edi), %al + movq %rax, %rsp # # Call C Function diff --git a/EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/X64/MpFuncs.asm b/EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/X64/MpFuncs.asm index 91bdb22451..5666322486 100644 --- a/EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/X64/MpFuncs.asm +++ b/EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/X64/MpFuncs.asm @@ -112,31 +112,33 @@ LongModeStart:: mov es, ax mov ss, ax + ; + ; ProgramStack + ; + mov ecx, 1bh ; Read IA32_APIC_BASE MSR + rdmsr + and eax, 0fffff000h + add eax, 20h + mov ebx, dword ptr [eax] + shr ebx, 24 + + xor rcx, rcx mov edi, esi - add edi, LockLocation - mov al, NotVacantFlag -TestLock:: - xchg byte ptr [edi], al - cmp al, NotVacantFlag - jz TestLock - -ProgramStack:: + add edi, ProcessorNumberLocation + mov ecx, dword ptr [edi + 4 * ebx] ; RCX = CpuNumber mov edi, esi add edi, StackSizeLocation mov rax, qword ptr [edi] + inc rcx + mul rcx ; RAX = StackSize * (CpuNumber + 1) + mov edi, esi add edi, StackStartAddressLocation - add rax, qword ptr [edi] - mov rsp, rax - mov qword ptr [edi], rax - -Releaselock:: + mov rbx, qword ptr [edi] + add rax, rbx ; RAX = StackStart + StackSize * (CpuNumber + 1) - mov al, VacantFlag - mov edi, esi - add edi, LockLocation - xchg byte ptr [edi], al + mov rsp, rax ; ; Call C Function -- 2.39.2