From 7b8d1925a99de1eb904ed100ffb25dcef20aa59e Mon Sep 17 00:00:00 2001 From: Kacper Nowak Date: Thu, 15 Dec 2022 13:23:05 +0000 Subject: [PATCH] feat(zebin): Use AOT config for validating target device Signed-off-by: Kacper Nowak --- .../device_binary_format/elf/zebin_elf.h | 3 +- .../device_binary_format/zebin_decoder.cpp | 49 ++++++++-- .../device_binary_format/zebin_decoder.h | 2 + .../zebin_decoder_tests.cpp | 94 ++++++++++++++++++- 4 files changed, 140 insertions(+), 8 deletions(-) diff --git a/shared/source/device_binary_format/elf/zebin_elf.h b/shared/source/device_binary_format/elf/zebin_elf.h index 0671095933..56c5393980 100644 --- a/shared/source/device_binary_format/elf/zebin_elf.h +++ b/shared/source/device_binary_format/elf/zebin_elf.h @@ -70,7 +70,8 @@ enum IntelGTSectionType : uint32_t { GfxCore = 2, TargetMetadata = 3, ZebinVersion = 4, - LastSupported = ZebinVersion + ProductConfig = 5, + LastSupported = ProductConfig }; struct IntelGTNote { IntelGTSectionType type; diff --git a/shared/source/device_binary_format/zebin_decoder.cpp b/shared/source/device_binary_format/zebin_decoder.cpp index daacf99eeb..d9415b3502 100644 --- a/shared/source/device_binary_format/zebin_decoder.cpp +++ b/shared/source/device_binary_format/zebin_decoder.cpp @@ -21,6 +21,8 @@ #include "shared/source/program/kernel_info.h" #include "shared/source/program/program_info.h" +#include "platforms.h" + namespace NEO { void setKernelMiscInfoPosition(ConstStringRef metadata, NEO::ProgramInfo &dst) { @@ -39,12 +41,46 @@ bool isDeviceBinaryFormat(const ArrayRef(binary)); } +bool validateTargetDevice(const TargetDevice &targetDevice, Elf::ELF_IDENTIFIER_CLASS numBits, PRODUCT_FAMILY productFamily, GFXCORE_FAMILY gfxCore, AOT::PRODUCT_CONFIG productConfig, Elf::ZebinTargetFlags targetMetadata) { + if (targetDevice.maxPointerSizeInBytes == 4 && static_cast(numBits == Elf::EI_CLASS_64)) { + return false; + } + + if (gfxCore == IGFX_UNKNOWN_CORE && productFamily == IGFX_UNKNOWN && productConfig == AOT::UNKNOWN_ISA) { + return false; + } + if (productConfig != AOT::UNKNOWN_ISA) { + if (targetDevice.aotConfig.value != productConfig) { + return false; + } + } else { + if (gfxCore != IGFX_UNKNOWN_CORE) { + if (targetDevice.coreFamily != gfxCore) { + return false; + } + } + if (productFamily != IGFX_UNKNOWN) { + if (false == haveSameCore(targetDevice.productFamily, productFamily)) { + return false; + } + } + } + if (targetMetadata.validateRevisionId) { + bool isValidStepping = (targetDevice.stepping >= targetMetadata.minHwRevisionId) && (targetDevice.stepping <= targetMetadata.maxHwRevisionId); + if (false == isValidStepping) { + return false; + } + } + return true; +} + template bool validateTargetDevice(const Elf::Elf &elf, const TargetDevice &targetDevice, std::string &outErrReason, std::string &outWarning); template bool validateTargetDevice(const Elf::Elf &elf, const TargetDevice &targetDevice, std::string &outErrReason, std::string &outWarning); template bool validateTargetDevice(const Elf::Elf &elf, const TargetDevice &targetDevice, std::string &outErrReason, std::string &outWarning) { GFXCORE_FAMILY gfxCore = IGFX_UNKNOWN_CORE; PRODUCT_FAMILY productFamily = IGFX_UNKNOWN; + AOT::PRODUCT_CONFIG productConfig = AOT::UNKNOWN_ISA; Elf::ZebinTargetFlags targetMetadata = {}; std::vector intelGTNotes = {}; auto decodeError = getIntelGTNotes(elf, intelGTNotes, outErrReason, outWarning); @@ -85,17 +121,18 @@ bool validateTargetDevice(const Elf::Elf &elf, const TargetDevice &targ } break; } + case Elf::IntelGTSectionType::ProductConfig: { + DEBUG_BREAK_IF(sizeof(uint32_t) != intelGTNote.data.size()); + auto productConfigData = reinterpret_cast(intelGTNote.data.begin()); + productConfig = static_cast(*productConfigData); + break; + } default: outWarning.append("DeviceBinaryFormat::Zebin : Unrecognized IntelGTNote type: " + std::to_string(intelGTNote.type) + "\n"); break; } } - bool validForTarget = (gfxCore != IGFX_UNKNOWN_CORE) | (productFamily != IGFX_UNKNOWN); - validForTarget &= (gfxCore != IGFX_UNKNOWN_CORE) ? targetDevice.coreFamily == gfxCore : true; - validForTarget &= (productFamily != IGFX_UNKNOWN) ? haveSameCore(targetDevice.productFamily, productFamily) : true; - validForTarget &= (0 == targetMetadata.validateRevisionId) | ((targetDevice.stepping >= targetMetadata.minHwRevisionId) & (targetDevice.stepping <= targetMetadata.maxHwRevisionId)); - validForTarget &= (targetDevice.maxPointerSizeInBytes >= static_cast(numBits == Elf::EI_CLASS_32 ? 4 : 8)); - return validForTarget; + return validateTargetDevice(targetDevice, numBits, productFamily, gfxCore, productConfig, targetMetadata); } DecodeError validateZeInfoVersion(const Elf::ZebinKernelMetadata::Types::Version &receivedZeInfoVersion, std::string &outErrReason, std::string &outWarning) { diff --git a/shared/source/device_binary_format/zebin_decoder.h b/shared/source/device_binary_format/zebin_decoder.h index d6ae0245ca..fd51c8974d 100644 --- a/shared/source/device_binary_format/zebin_decoder.h +++ b/shared/source/device_binary_format/zebin_decoder.h @@ -50,6 +50,8 @@ struct ZeInfoKernelSections { DecodeError validateZeInfoVersion(const Elf::ZebinKernelMetadata::Types::Version &receivedZeInfoVersion, std::string &outErrReason, std::string &outWarning); +bool validateTargetDevice(const TargetDevice &targetDevice, Elf::ELF_IDENTIFIER_CLASS numBits, PRODUCT_FAMILY productFamily, GFXCORE_FAMILY gfxCore, AOT::PRODUCT_CONFIG productConfig, Elf::ZebinTargetFlags targetMetadata); + template bool validateTargetDevice(const Elf::Elf &elf, const TargetDevice &targetDevice, std::string &outErrReason, std::string &outWarning); diff --git a/shared/test/unit_test/device_binary_format/zebin_decoder_tests.cpp b/shared/test/unit_test/device_binary_format/zebin_decoder_tests.cpp index 6467051eaa..25859f3e71 100644 --- a/shared/test/unit_test/device_binary_format/zebin_decoder_tests.cpp +++ b/shared/test/unit_test/device_binary_format/zebin_decoder_tests.cpp @@ -20,6 +20,8 @@ #include "shared/test/common/mocks/mock_modules_zebin.h" #include "shared/test/common/test_macros/test.h" +#include "platforms.h" + #include #include @@ -6314,6 +6316,37 @@ TEST_F(IntelGTNotesFixture, WhenValidatingTargetDeviceGivenValidTargetDeviceAndV EXPECT_TRUE(validateTargetDevice(elf, targetDevice, outErrReason, outWarning)); } +TEST_F(IntelGTNotesFixture, givenAotConfigInIntelGTNotesSectionWhenValidatingTargetDeviceThenUseOnlyItForValidation) { + NEO::HardwareIpVersion aotConfig = {0}; + aotConfig.value = 0x00001234; + + TargetDevice targetDevice; + targetDevice.maxPointerSizeInBytes = 8u; + ASSERT_EQ(IGFX_UNKNOWN, targetDevice.productFamily); + ASSERT_EQ(IGFX_UNKNOWN_CORE, targetDevice.coreFamily); + targetDevice.aotConfig.value = aotConfig.value; + + Elf::ElfNoteSection elfNoteSection; + elfNoteSection.descSize = 4u; + elfNoteSection.nameSize = 8u; + elfNoteSection.type = Elf::IntelGTSectionType::ProductConfig; + + uint8_t productConfigData[4]; + memcpy_s(productConfigData, 4, &aotConfig.value, 4); + + auto sectionDataSize = sizeof(Elf::ElfNoteSection) + elfNoteSection.nameSize + elfNoteSection.descSize; + auto noteIntelGTSectionData = std::make_unique(sectionDataSize); + appendSingleIntelGTSectionData(elfNoteSection, noteIntelGTSectionData.get(), productConfigData, NEO::Elf::IntelGtNoteOwnerName.data(), sectionDataSize); + zebin.appendSection(Elf::SHT_NOTE, Elf::SectionsNamesZebin::noteIntelGT, ArrayRef::fromAny(noteIntelGTSectionData.get(), sectionDataSize)); + + std::string outErrReason, outWarning; + auto elf = Elf::decodeElf(zebin.storage, outErrReason, outWarning); + EXPECT_TRUE(outWarning.empty()); + EXPECT_TRUE(outErrReason.empty()); + + EXPECT_TRUE(validateTargetDevice(elf, targetDevice, outErrReason, outWarning)); +} + TEST(ValidateTargetDevice32BitZebin, Given32BitZebinAndValidIntelGTNotesWhenValidatingTargetDeviceThenReturnTrue) { TargetDevice targetDevice; targetDevice.productFamily = productFamily; @@ -6415,7 +6448,7 @@ TEST_F(IntelGTNotesFixture, WhenValidatingTargetDeviceGivenValidTargetDeviceAndI targetDevice.stepping = hardwareInfoTable[productFamily]->platform.usRevId; Elf::ElfNoteSection elfNoteSection = {}; - elfNoteSection.type = 5; + elfNoteSection.type = Elf::IntelGTSectionType::LastSupported + 1; elfNoteSection.descSize = 0u; elfNoteSection.nameSize = 8u; auto sectionDataSize = sizeof(Elf::ElfNoteSection) + elfNoteSection.nameSize + elfNoteSection.descSize; @@ -6557,6 +6590,65 @@ TEST_F(IntelGTNotesFixture, GivenIncompatibleVersioningWhenValidatingTargetDevic EXPECT_STREQ("DeviceBinaryFormat::Zebin::.ze_info : Unhandled major version : 2, decoder is at : 1\n", outErrReason.c_str()); } +TEST(ValidateTargetDeviceTests, givenMismatechAotConfigWhenValidatingTargetDeviceThenUseOnlyItForValidationAndReturnFalse) { + TargetDevice targetDevice; + targetDevice.aotConfig.value = 0x00001234; + targetDevice.maxPointerSizeInBytes = 8u; + + auto mismatchedAotConfig = static_cast(0x00004321); + Elf::ZebinTargetFlags targetMetadata; + auto res = validateTargetDevice(targetDevice, Elf::EI_CLASS_64, productFamily, renderCoreFamily, mismatchedAotConfig, targetMetadata); + EXPECT_FALSE(res); +} + +TEST(ValidateTargetDeviceTests, givenMismatchedProductFamilyWhenValidatingTargetDeviceThenReturnFalse) { + TargetDevice targetDevice; + targetDevice.maxPointerSizeInBytes = 8u; + ASSERT_EQ(AOT::UNKNOWN_ISA, targetDevice.aotConfig.value); + targetDevice.coreFamily = IGFX_UNKNOWN_CORE; + targetDevice.productFamily = productFamily; + + Elf::ZebinTargetFlags targetMetadata; + auto mismatchedPlatformFamily = IGFX_UNKNOWN; + for (int i = 0; i < IGFX_MAX_PRODUCT; i++) { + const auto hwInfo = NEO::hardwareInfoTable[i]; + if (nullptr != hwInfo && hwInfo->platform.eRenderCoreFamily != renderCoreFamily) { + mismatchedPlatformFamily = hwInfo->platform.eProductFamily; + } + } + + auto res = validateTargetDevice(targetDevice, Elf::EI_CLASS_64, mismatchedPlatformFamily, IGFX_UNKNOWN_CORE, AOT::UNKNOWN_ISA, targetMetadata); + EXPECT_FALSE(res); +} + +TEST(ValidateTargetDeviceTests, givenMismatchedGfxCoreWhenValidatingTargetDeviceThenReturnFalse) { + TargetDevice targetDevice; + targetDevice.maxPointerSizeInBytes = 8u; + ASSERT_EQ(AOT::UNKNOWN_ISA, targetDevice.aotConfig.value); + targetDevice.coreFamily = renderCoreFamily; + + Elf::ZebinTargetFlags targetMetadata; + auto mismatchedGfxCore = static_cast(renderCoreFamily + 1); + + auto res = validateTargetDevice(targetDevice, Elf::EI_CLASS_64, IGFX_UNKNOWN, mismatchedGfxCore, AOT::UNKNOWN_ISA, targetMetadata); + EXPECT_FALSE(res); +} + +TEST(ValidateTargetDeviceTests, givenSteppingBiggerThanMaxHwRevisionWhenValidatingTargetDeviceThenReturnFalse) { + TargetDevice targetDevice; + targetDevice.maxPointerSizeInBytes = 8u; + auto aotConfigValue = 0x00001234u; + targetDevice.aotConfig.value = aotConfigValue; + + targetDevice.stepping = 2u; + Elf::ZebinTargetFlags targetMetadata; + targetMetadata.validateRevisionId = true; + targetMetadata.maxHwRevisionId = 1u; + + auto res = validateTargetDevice(targetDevice, Elf::EI_CLASS_64, IGFX_UNKNOWN, IGFX_UNKNOWN_CORE, static_cast(aotConfigValue), targetMetadata); + EXPECT_FALSE(res); +} + TEST(PopulateGlobalDeviceHostNameMapping, givenValidZebinWithGlobalHostAccessTableSectionThenPopulateHostDeviceNameMapCorrectly) { NEO::ConstStringRef zeinfo = R"===( kernels: