Skip to content

Commit

Permalink
Merge pull request #3726 from Sonicadvance1/oryon_errata
Browse files Browse the repository at this point in the history
HostFeatures: Work around Qualcomm Oryon RNG errata
  • Loading branch information
Sonicadvance1 committed Jun 20, 2024
2 parents 053620f + b34c23f commit df96bc8
Showing 1 changed file with 25 additions and 0 deletions.
25 changes: 25 additions & 0 deletions FEXCore/Source/Interface/Core/HostFeatures.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ static uint32_t GetFPCR() {
static void SetFPCR(uint64_t Value) {
__asm("msr FPCR, %[Value]" ::[Value] "r"(Value));
}

static uint32_t GetMIDR() {
uint64_t Result {};
__asm("mrs %[Res], MIDR_EL1" : [Res] "=r"(Result));
return Result;
}

#else
static uint32_t GetDCZID() {
// Return unsupported
Expand Down Expand Up @@ -194,6 +201,24 @@ HostFeatures::HostFeatures() {

// Set FPCR back to original just in case anything changed
SetFPCR(OriginalFPCR);

if (SupportsRAND) {
const auto MIDR = GetMIDR();
constexpr uint32_t Implementer_QCOM = 0x51;
constexpr uint32_t PartNum_Oryon1 = 0x001;
const uint32_t MIDR_Implementer = (MIDR >> 24) & 0xFF;
const uint32_t MIDR_PartNum = (MIDR >> 4) & 0xFFF;
if (MIDR_Implementer == Implementer_QCOM && MIDR_PartNum == PartNum_Oryon1) {
// Work around an errata in Qualcomm's Oryon.
// While this CPU implements the RAND extension:
// - The RNDR register works.
// - The RNDRRS register will never read a random number. (Always return failure)
// This is contrary to x86 RNG behaviour where it allows spurious failure with RDSEED, but guarantees eventual success.
// This manifested itself on Linux when an x86 processor failed to guarantee forward progress and boot of services would infinite
// loop. Just disable this extension if this CPU is detected.
SupportsRAND = false;
}
}
#endif

#ifdef VIXL_SIMULATOR
Expand Down

0 comments on commit df96bc8

Please sign in to comment.