UefiCpuPkg/RegisterCpuFeaturesLib: Adjust Order.

V2 changes:
V1 change has regression which caused by change feature order.
V2 changes logic to detect dependence not only for the
neighborhood features. It need to check all features in the list.

V1 Changes:
In current code logic, only adjust feature position if current
CPU feature position not follow the request order. Just like
Feature A need to be executed before feature B, but current
feature A registers after feature B. So code will adjust the
position for feature A, move it to just before feature B. If
the position already met the requirement, code will not adjust
the position.

This logic has issue when met all below cases:
1. feature A has core or package level dependence with feature B.
2. feature A is register before feature B.
3. Also exist other features exist between feature A and B.

Root cause is driver ignores the dependence for this case, so
threads may execute not follow the dependence order.

Fix this issue by change code logic to adjust feature position
for CPU features which has dependence relationship.

Related BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=1311

Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ruiyu Ni <Ruiyu.ni@intel.com>
This commit is contained in:
Eric Dong
2018-11-09 13:20:41 +08:00
parent 8cd4e734cc
commit c1528b855c
3 changed files with 193 additions and 20 deletions

View File

@@ -112,6 +112,75 @@ IsBitMaskMatchCheck (
return FALSE;
}
/**
Try to find the specify cpu featuren in former/after feature list.
@param[in] FeatureList Pointer to dependent CPU feature list
@param[in] CurrentEntry Pointer to current CPU feature entry.
@param[in] SearchFormer Find in former feature or after features.
@param[in] FeatureMask Pointer to CPU feature bit mask
@retval TRUE The feature bit mask is in dependent CPU feature bit mask buffer.
@retval FALSE The feature bit mask is not in dependent CPU feature bit mask buffer.
**/
BOOLEAN
FindSpecifyFeature (
IN LIST_ENTRY *FeatureList,
IN LIST_ENTRY *CurrentEntry,
IN BOOLEAN SearchFormer,
IN UINT8 *FeatureMask
)
{
CPU_FEATURES_ENTRY *CpuFeature;
LIST_ENTRY *NextEntry;
//
// Check whether exist the not neighborhood entry first.
// If not exist, return FALSE means not found status.
//
if (SearchFormer) {
NextEntry = CurrentEntry->BackLink;
if (IsNull (FeatureList, NextEntry)) {
return FALSE;
}
NextEntry = NextEntry->BackLink;
if (IsNull (FeatureList, NextEntry)) {
return FALSE;
}
NextEntry = CurrentEntry->BackLink->BackLink;
} else {
NextEntry = CurrentEntry->ForwardLink;
if (IsNull (FeatureList, NextEntry)) {
return FALSE;
}
NextEntry = NextEntry->ForwardLink;
if (IsNull (FeatureList, NextEntry)) {
return FALSE;
}
NextEntry = CurrentEntry->ForwardLink->ForwardLink;
}
while (!IsNull (FeatureList, NextEntry)) {
CpuFeature = CPU_FEATURE_ENTRY_FROM_LINK (NextEntry);
if (IsBitMaskMatchCheck (FeatureMask, CpuFeature->FeatureMask)) {
return TRUE;
}
if (SearchFormer) {
NextEntry = NextEntry->BackLink;
} else {
NextEntry = NextEntry->ForwardLink;
}
}
return FALSE;
}
/**
Return feature dependence result.
@@ -178,6 +247,59 @@ DetectFeatureScope (
return NoneDepType;
}
/**
Return feature dependence result.
@param[in] CpuFeature Pointer to CPU feature.
@param[in] Before Check before dependence or after.
@param[in] FeatureList Pointer to CPU feature list.
@retval return the dependence result.
**/
CPU_FEATURE_DEPENDENCE_TYPE
DetectNoneNeighborhoodFeatureScope (
IN CPU_FEATURES_ENTRY *CpuFeature,
IN BOOLEAN Before,
IN LIST_ENTRY *FeatureList
)
{
if (Before) {
if ((CpuFeature->PackageBeforeFeatureBitMask != NULL) &&
FindSpecifyFeature(FeatureList, &CpuFeature->Link, FALSE, CpuFeature->PackageBeforeFeatureBitMask)) {
return PackageDepType;
}
if ((CpuFeature->CoreBeforeFeatureBitMask != NULL) &&
FindSpecifyFeature(FeatureList, &CpuFeature->Link, FALSE, CpuFeature->CoreBeforeFeatureBitMask)) {
return CoreDepType;
}
if ((CpuFeature->BeforeFeatureBitMask != NULL) &&
FindSpecifyFeature(FeatureList, &CpuFeature->Link, FALSE, CpuFeature->BeforeFeatureBitMask)) {
return ThreadDepType;
}
return NoneDepType;
}
if ((CpuFeature->PackageAfterFeatureBitMask != NULL) &&
FindSpecifyFeature(FeatureList, &CpuFeature->Link, TRUE, CpuFeature->PackageAfterFeatureBitMask)) {
return PackageDepType;
}
if ((CpuFeature->CoreAfterFeatureBitMask != NULL) &&
FindSpecifyFeature(FeatureList, &CpuFeature->Link, TRUE, CpuFeature->CoreAfterFeatureBitMask)) {
return CoreDepType;
}
if ((CpuFeature->AfterFeatureBitMask != NULL) &&
FindSpecifyFeature(FeatureList, &CpuFeature->Link, TRUE, CpuFeature->AfterFeatureBitMask)) {
return ThreadDepType;
}
return NoneDepType;
}
/**
Base on dependence relationship to asjust feature dependence.