-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add kernel quirk 'FixAppleVTD' #440
Conversation
In macOS 13.3, WiFi and most Ethernet devices stop working when AppleVTD is enabled and system has more than 16GB memory. This affects motherboards that have one or more 'Reserved Memory Regions' in their DMA Remap table (DMAR). This quirk side-steps the problem, allowing WiFi and Ethernet devices to function once again. Update CommonPatches.c Add kernel version info and fix typo
What is the issue with |
Various Ethernet and Thunderbolt devices do not establish a connection in Big Sur and later when For example, Aquantia AQC107 / AQC113, Antelope Audio Thunderbolt audio interfaces, and Apple Thunderbolt to Gigabit Ethernet adapter, among others. These devices require AppleVTD, so we enable VT-d in BIOS and turn off These threads contain a number of posts about this problem: https://www.insanelymac.com/forum/topic/356135-release-macos-133/?do=findComment&comment=2802842 |
Hmm, what in particular does this patch do? To me it feels like correcting the DMA table is the most efficient way to resolve this as patching the driver may break VT-d even more. |
Normally we would remove Reserved Memory Regions and create a modified In the screenshot below we see early 13.3 on left without call to |
Are you sure that this patch is only required on 13.3+? I recall some old discussions when adding the Aquantia patch: 2441455#commitcomment-70530145 |
The discussion in that link started with user That conversation occurred almost exactly a year ago. At the time there was no way to enable AQC107 and AQC113 on AMD platforms, but that changed in December 2022 when I posted the following kext patches: With these patches we bypass AppleVTD in Monterey and Ventura, which allows AQC107 and AQC113 to function on AMD platforms, effectively reverting to Big Sur behavior. These patches also work on Intel platforms when AppleVTD is disabled. However, AppleVTD affects more than just the Aquantia driver. It also affects Thunderbolt devices such as Antelope Audio interfaces and Apple's Thunderbolt-to-Gigabit Ethernet adapter (which is still in use because it supports Ethernet AVB [audio video bridging protocol]). All of these devices were working properly on Intel platforms in macOS 13.3 beta builds 1 and 2 with AppleVTD enabled and no driver-specific patches applied. But in macOS 13.3 beta build 3 or 4, Apple made some small changes to Motherboards such as Asus Z690 and Z790 do not have Reserved Memory Regions and are not affected by the change. But many Z370, Z390, Z490 (and maybe Z590) boards are affected. In effect, a new problem was introduced in macOS 13.3 late beta, which this quirk addresses. The target audience for this quirk are users with:
Side Note: In Ventura, Apple removed |
Now using find and replace masks
Match nearby bytes as well to reduce false positive chances
Sorry, but I repeat my question. What do these patches do? I am not keen into loading IDA and investigating it myself. Could you explain based on the IOPCIFamily source code? |
Source code for 13.3 has not yet been posted, so the explanation below is based partly on 13.2 source code and partly on disassembled 13.3 x86 binary. In 13.2 the function bool IOPCIBridge::addBridgeMemoryRange( IOPhysicalAddress start,
IOPhysicalLength length, bool host )
{
bool ok;
// fix - ACPIPCI makes this up for hosts with zero space
if ((0x80000000 == start) && (0x7f000000 == length))
return (false);
ok = IOPCIRangeListAddRange(&reserved->rangeLists[kIOPCIResourceTypeMemory],
kIOPCIResourceTypeMemory,
start, length);
return (ok);
} But in 13.3 it looks like this (from x86 disassembly): undefined8 IOPCIBridge::addBridgeMemoryRange(ulonglong param_1,ulonglong param_2,bool param_3)
{
undefined8 uVar1;
undefined7 in_register_00000011;
ulonglong uVar2;
uVar2 = CONCAT71(in_register_00000011,param_3);
if ((param_2 == 0x80000000) && (uVar2 == 0x7f000000)) {
return 0;
}
AppleVTD::addMemoryRange(param_2,uVar2);
uVar1 = IOPCIRangeListAddRange(*(IOPCIRange ***)(param_1 + 0x98),0,param_2,uVar2,1);
return uVar1;
} We can see that the only noteworthy change is a newly added call to The code for // AppleVTD::x(unsigned long long, unsigned long long)
void AppleVTD::addMemoryRange(ulonglong param_1,ulonglong param_2)
{
uint uVar1;
long lVar2;
int iVar3;
long lVar4;
char *pcVar5;
pcVar5 = *(char **)PTR_gSystem_00031058;
lVar4 = OSMetaClassBase::safeMetaCast((OSMetaClassBase *)pcVar5,(OSMetaClass *)&gMetaClass);
if (lVar4 == 0) {
pcVar5 = "[%s()] AppleVTD is not yet installed as gSystem\n";
}
else {
if (*(long *)(lVar4 + 0x1d0) != 0x40) {
*(ulonglong *)(lVar4 + 0x1d8 + *(long *)(lVar4 + 0x1d0) * 8) = param_1;
*(ulonglong *)(lVar4 + 0x3d8 + *(long *)(lVar4 + 0x1d0) * 8) = param_2;
if (*(long *)(lVar4 + 0x1a8) != 0) {
lVar2 = *(long *)(lVar4 + 0x1d0);
uVar1 = *(uint *)(lVar4 + 0x3d8 + lVar2 * 8);
if ((_gIOPCIFlags & 4) != 0) {
iVar3 = _ml_at_interrupt_context();
if (iVar3 == 0) {
pcVar5 = "[%s(%p)] Freeing 0x%llx->0x%llx\n";
_IOLog("[%s(%p)] Freeing 0x%llx->0x%llx\n","addMemoryRange",
*(undefined8 *)(lVar4 + 0x1a8));
}
}
if ((_gIOPCIFlags & 4) != 0) {
pcVar5 = "[%s(%p)] Freeing 0x%llx->0x%llx\n";
_kprintf("[%s(%p)] Freeing 0x%llx->0x%llx\n","addMemoryRange",
*(undefined8 *)(lVar4 + 0x1a8));
}
space_alloc_fixed((AppleVTD *)pcVar5,*(vtd_space **)(lVar4 + 0x1a8),
(uint)(*(ulong *)(lVar4 + 0x1d8 + lVar2 * 8) >> 0xc),uVar1 >> 0xc,false);
}
*(long *)(lVar4 + 0x1d0) = *(long *)(lVar4 + 0x1d0) + 1;
return;
}
pcVar5 = "[%s()] Mem regions limit reached\n";
}
_IOLog(pcVar5,"addMemoryRange");
return;
} Although not a substitute for actual source code, this function first checks if AppleVTD is enabled, otherwise it exits. If AppleVTD is enabled, we can see there is a call to void
AppleVTD::space_alloc_fixed(vtd_space_t * bf, vtd_baddr_t addr, vtd_baddr_t size)
{
vtd_balloc_fixed(bf, addr, size);
vtd_rballoc_fixed(bf, addr, size);
vtd_space_fault(bf, addr, size);
} We can see that it's part of the Note that there is no In early beta builds of 13.3 the By looking for differences between early and late beta builds of 13.3, we spotted this function and applied a patch to skip over it. In other words, we created a patch that specifically blocks out the call to undefined8 IOPCIBridge::addBridgeMemoryRange(ulonglong param_1,ulonglong param_2,bool param_3)
{
undefined8 uVar1;
undefined7 in_register_00000011;
ulonglong uVar2;
uVar2 = CONCAT71(in_register_00000011,param_3);
if ((param_2 == 0x80000000) && (uVar2 == 0x7f000000)) {
return 0;
}
// skip over AppleVTD::addMemoryRange
// AppleVTD::addMemoryRange(param_2,uVar2);
uVar1 = IOPCIRangeListAddRange(*(IOPCIRange ***)(param_1 + 0x98),0,param_2,uVar2,1);
return uVar1;
} After applying the patch we found that all of our WiFi, Ethernet and Thunderbolt devices started to work properly once again. Skipping |
Got it, thank you! (1) Suggest to replace the patch with:
It will simply disable the function, which should be more reliable than finding the call to it. (2) Suggest to rename the quirk to (3) Rewrite the description to explain that this quirk disables mapping PCI bridge device memory in IOMMU (VT-d). Then you may add that this happens to resolve compatibility issues with Wi-Fi and such due to not trying to restrict access to them via VT-d. OpenCore Configuration Manual is not a guide after all. |
FixAppleVTD kernel quirk has been replaced with DisableIoMapperMapping, which modifies "addMemoryRange" to simply return (opcode 0xC3).
These changes have been made and tested on my Gigabyte Z490 Vision D and Gigabyte Z390 Designare. |
Reformatted the description for DisableIoMapperMapping
Improved clarity of description
Thank you very much! Looks good to me now. |
Thanks! Merged) |
华硕z390还是不行, |
You might have a different problem. Please create a new thread in the link below and describe the problem in detail. |
|
Nice patch! After reboot, blueteeth works fine but WIFI can't be enabled. |
Please see the discussion here: acidanthera/bugtracker#2278 (comment) We can follow up with you there. |
In macOS 13.3, WiFi and most Ethernet devices stop working when AppleVTD is enabled and system has more than 16GB memory. This affects motherboards that have one or more Reserved Memory Regions in their DMA Remap table (DMAR). The problem exists even if Reserved Memory Regions are removed and a substitute
SSDT-DMAR.aml
is injected.This quirk side-steps the problem, allowing WiFi and Ethernet devices to function once again. It restores the behavior that existed in earlier versions of Ventura.
This quirk patches IOPCIFamily.kext.
I'm submitting this pull request a little early to allow more time for review and update. Some comments and questions:
Configuration.tex
has been updated, but not sure if other documentation files also need to be updated; doesDifferences.pdf
get updated automatically?Sample.plist
andSampleCustom.plist
have been updatedA description of the patch is provided here.