diff options
author | xli24 <xli24@6f19259b-4bc3-4df7-8a09-765794883524> | 2010-07-30 01:49:51 +0000 |
---|---|---|
committer | xli24 <xli24@6f19259b-4bc3-4df7-8a09-765794883524> | 2010-07-30 01:49:51 +0000 |
commit | d6d858c4b7f0311f1c4d3b5d410ce87b1a261538 (patch) | |
tree | ccc363e7eb13f45084171a7a5b765af35f2b5121 | |
parent | 28d1916584e75dfbe38a192435e4d7549c12040e (diff) | |
download | edk2-platforms-d6d858c4b7f0311f1c4d3b5d410ce87b1a261538.tar.xz |
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
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
|