From 2e9a28272e790d36ee398ba7ab9934b82231ba18 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sat, 22 Jul 2023 20:45:59 +0200 Subject: [PATCH] Kernel/Audio: Fail AC97 probe if no good BAR1 is found Otherwise we get a kernel panic later on Intel SOF. --- Kernel/Devices/Audio/AC97/AC97.cpp | 15 +++++++++++++++ Kernel/Devices/Audio/AC97/AC97.h | 2 ++ 2 files changed, 17 insertions(+) diff --git a/Kernel/Devices/Audio/AC97/AC97.cpp b/Kernel/Devices/Audio/AC97/AC97.cpp index bd30caee72..f505a0a58f 100644 --- a/Kernel/Devices/Audio/AC97/AC97.cpp +++ b/Kernel/Devices/Audio/AC97/AC97.cpp @@ -35,6 +35,21 @@ UNMAP_AFTER_INIT ErrorOr> AC97::create(PCI::Devic UNMAP_AFTER_INIT ErrorOr AC97::probe(PCI::DeviceIdentifier const& device_identifier) { VERIFY(device_identifier.class_code() == PCI::ClassID::Multimedia); + + // TODO: Check pci ids. + + if (PCI::get_BAR_space_size(device_identifier, PCI::HeaderType0BaseRegister::BAR0) <= NativeAudioMixerRegister::MaxUsedMixerOffset) + return Error::from_errno(EIO); + + // BAR registers are 32-bit. So if BAR0 is 64-bit then + // it occupies BAR0 and BAR1 and hence BAR1 isn't present on its own. + u64 pci_bar0_value = PCI::get_BAR(device_identifier, PCI::HeaderType0BaseRegister::BAR0); + if (PCI::get_BAR_space_type(pci_bar0_value) == PCI::BARSpaceType::Memory64BitSpace) + return Error::from_errno(EIO); + + if (PCI::get_BAR_space_size(device_identifier, PCI::HeaderType0BaseRegister::BAR1) <= NativeAudioBusRegister::MaxUsedBusOffset) + return Error::from_errno(EIO); + return device_identifier.subclass_code() == PCI::Multimedia::SubclassID::Audio; } diff --git a/Kernel/Devices/Audio/AC97/AC97.h b/Kernel/Devices/Audio/AC97/AC97.h index 1b0ab9aecb..bf072dd8e1 100644 --- a/Kernel/Devices/Audio/AC97/AC97.h +++ b/Kernel/Devices/Audio/AC97/AC97.h @@ -48,6 +48,7 @@ private: PCMFrontDACRate = 0x2c, VendorID1 = 0x7c, VendorID2 = 0x7e, + MaxUsedMixerOffset = 0x7f, }; enum ExtendedAudioMask : u16 { @@ -79,6 +80,7 @@ private: enum NativeAudioBusRegister : u8 { GlobalControl = 0x2c, + MaxUsedBusOffset = 0x2f }; enum AudioStatusRegisterFlag : u16 {