Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

Removed interface lags workaround for the Web drivers (starting with …

…387.10.10.10.30.106 it is present in the distribution), closes #15
  • Loading branch information...
vit9696 committed Apr 18, 2018
1 parent 8275a6c commit 9ddc07558737d5085f665002dda94b636958e47b
@@ -1,5 +1,7 @@
NvidiaGraphicsFixup Changelog
=============================
#### v1.2.7
- Removed interface lags workaround for the Web drivers (starting with 387.10.10.10.30.106 it is present in the distribution)

#### v1.2.6
- Made `ngfxcompat=0` explicitly disable NVDAStartupWeb.kext loading from HDD
@@ -376,7 +376,7 @@
MODULE_NAME = as.lvs1974.NvidiaGraphicsFixup;
MODULE_START = "$(PRODUCT_NAME)_kern_start";
MODULE_STOP = "$(PRODUCT_NAME)_kern_stop";
MODULE_VERSION = 1.2.6;
MODULE_VERSION = 1.2.7;
OTHER_CFLAGS = (
"-mmmx",
"-msse",
@@ -420,7 +420,7 @@
MODULE_NAME = as.lvs1974.NvidiaGraphicsFixup;
MODULE_START = "$(PRODUCT_NAME)_kern_start";
MODULE_STOP = "$(PRODUCT_NAME)_kern_stop";
MODULE_VERSION = 1.2.6;
MODULE_VERSION = 1.2.7;
OTHER_CFLAGS = (
"-mmmx",
"-msse",
@@ -52,7 +52,6 @@ static NGFX *callbackNGFX = nullptr;

// Used by asm code
bool (*orgVaddrPresubmitOfficial)(void *addr) = nullptr;
bool (*orgVaddrPresubmitWeb)(void *addr) = nullptr;

bool NGFX::init() {
// The code below (enabled by ngfxcompat=0) is not only relevant for a not so important optimisation
@@ -233,7 +232,7 @@ void NGFX::processKext(KernelPatcher &patcher, size_t index, mach_vm_address_t a
}
}

restoreLegacyOptimisations(patcher, index, address, size, false);
restoreLegacyOptimisations(patcher, index, address, size);

progressState |= ProcessingState::GeForceRouted;
}
@@ -256,8 +255,6 @@ void NGFX::processKext(KernelPatcher &patcher, size_t index, mach_vm_address_t a
}
}

restoreLegacyOptimisations(patcher, index, address, size, true);

progressState |= ProcessingState::GeForceWebRouted;
}
else if (!(progressState & ProcessingState::NVDAStartupWebRouted) && i == KextNVDAStartupWeb)
@@ -287,7 +284,7 @@ void NGFX::processKext(KernelPatcher &patcher, size_t index, mach_vm_address_t a
patcher.clearError();
}

void NGFX::restoreLegacyOptimisations(KernelPatcher &patcher, size_t index, mach_vm_address_t address, size_t size, bool web) {
void NGFX::restoreLegacyOptimisations(KernelPatcher &patcher, size_t index, mach_vm_address_t address, size_t size) {
if (getKernelVersion() < KernelVersion::HighSierra) {
DBGLOG("ngfx", "not bothering vaddr presubmit performance fix on pre-10.13");
return;
@@ -333,9 +330,8 @@ void NGFX::restoreLegacyOptimisations(KernelPatcher &patcher, size_t index, mach
if (!memcmp(reinterpret_cast<void *>(presubmit), prologue, sizeof(prologue))) {
patcher.routeBlock(presubmit, uprologue, sizeof(uprologue));
if (patcher.getError() == KernelPatcher::Error::NoError)
(web ? orgVaddrPresubmitWeb : orgVaddrPresubmitOfficial) = reinterpret_cast<t_nvaddr_pre_submit>(
patcher.routeFunction(presubmit + sizeof(prologue), reinterpret_cast<mach_vm_address_t>(
web ? preSubmitHandlerWeb : preSubmitHandlerOfficial), true));
orgVaddrPresubmitOfficial = reinterpret_cast<t_nvaddr_pre_submit>(
patcher.routeFunction(presubmit + sizeof(prologue), reinterpret_cast<mach_vm_address_t>(preSubmitHandlerOfficial), true));
if (patcher.getError() == KernelPatcher::Error::NoError) {
presubmitBase = presubmit + sizeof(prologue);
DBGLOG("ngfx", "routed __ZN21nvVirtualAddressSpace9PreSubmitEv");
@@ -350,7 +346,7 @@ void NGFX::restoreLegacyOptimisations(KernelPatcher &patcher, size_t index, mach
}

// Then we have to recover the calls to the PreSubmit function, which were removed.
if (((web && orgVaddrPresubmitWeb) || (!web && orgVaddrPresubmitOfficial)) && presubmitBase) {
if (orgVaddrPresubmitOfficial && presubmitBase) {
const char *symbols[] {
"__ZN21nvVirtualAddressSpace12MapMemoryDmaEP11nvSysMemoryP11nvMemoryMapP18nvPageTableMappingj",
"__ZN21nvVirtualAddressSpace12MapMemoryDmaEP16__GLNVsurfaceRecjjyj",
@@ -360,12 +356,6 @@ void NGFX::restoreLegacyOptimisations(KernelPatcher &patcher, size_t index, mach
"__ZN21nvVirtualAddressSpace14UnmapMemoryDmaEyy"
};

if (web) {
// Web drivers added extra params to these two functions
symbols[1] = "__ZN21nvVirtualAddressSpace12MapMemoryDmaEP16__GLNVsurfaceRecjjyjb";
symbols[4] = "__ZN21nvVirtualAddressSpace14UnmapMemoryDmaEP16__GLNVsurfaceRecjjyjb";
}

uint8_t seq_rbx[] {0xC6, 0x83, 0x7C, 0x03, 0x00, 0x00, 0x00};
uint8_t seq_r13[] {0x41, 0xC6, 0x85, 0x7C, 0x03, 0x00, 0x00, 0x00};
uint8_t seq_r12[] {0x41, 0xC6, 0x84, 0x24, 0x7C, 0x03, 0x00, 0x00, 0x00};
@@ -374,11 +364,6 @@ void NGFX::restoreLegacyOptimisations(KernelPatcher &patcher, size_t index, mach
uint8_t rep_r13[] {0xB0, 0x02, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x90};
uint8_t rep_r12[] {0xB0, 0x03, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90};

if (web) {
// Web drivers have the offsets modified
seq_rbx[2] = seq_r13[3] = seq_r12[4] = 0x64;
}

size_t disp_off = 3;
// Pick something reasonably high to ensure the sequence is found.
size_t max_lookup = 0x1000;
@@ -582,40 +567,6 @@ bool NGFX::nvVirtualAddressSpace_PreSubmitOfficial(void *that)
return false;
}

bool NGFX::nvVirtualAddressSpace_PreSubmitWeb(void *that)
{
if (callbackNGFX && orgVaddrPresubmitWeb)
{
bool r = orgSubmitHandlerWeb(that);

if (that && r && callbackNGFX->orgFifoPrepare && callbackNGFX->orgFifoComplete)
{
getMember<uint8_t>(that, 0x365) = 1;
auto fifo = getMember<void *>(that, 0x2B0);
if (callbackNGFX->orgFifoPrepare(fifo))
{
auto fifovt = getMember<void *>(fifo, 0);
// Calls to nvGpFifoChannel::PreSubmit
auto fifopresubmit = getMember<bool (*)(void *, uint32_t, void *, uint32_t,
void *, uint32_t *, uint64_t, uint32_t)>(fifovt, 0x1B0);
if (fifopresubmit(fifo, 0x40000, 0, 0, 0, 0, 0, 0))
{
getMember<uint16_t>(that, 0x364) = 1;
return true;
}

callbackNGFX->orgFifoPrepare(fifo);
return false;
}
}

return r;
}

return false;
}


void NGFX::applyPatches(KernelPatcher &patcher, size_t index, const KextPatch *patches, size_t patchNum, const char* name) {
DBGLOG("ngfx", "applying patch '%s' for %zu kext", name, index);
for (size_t p = 0; p < patchNum; p++) {
@@ -20,10 +20,7 @@ struct KextPatch {
// Assembly exports for restoreLegacyOptimisations
extern "C" bool preSubmitHandlerOfficial(void *that);
extern "C" bool orgSubmitHandlerOfficial(void *that);
extern "C" bool preSubmitHandlerWeb(void *that);
extern "C" bool orgSubmitHandlerWeb(void *that);
extern "C" bool (*orgVaddrPresubmitOfficial)(void *addr);
extern "C" bool (*orgVaddrPresubmitWeb)(void *addr);

class NGFX {
public:
@@ -57,7 +54,7 @@ class NGFX {
* @param address kinfo load address
* @param size kinfo memory size
*/
void restoreLegacyOptimisations(KernelPatcher &patcher, size_t index, mach_vm_address_t address, size_t size, bool web);
void restoreLegacyOptimisations(KernelPatcher &patcher, size_t index, mach_vm_address_t address, size_t size);

/**
* SetAccelProperties callback type
@@ -112,9 +109,6 @@ class NGFX {

static bool nvVirtualAddressSpace_PreSubmitOfficial(void *that);

static bool nvVirtualAddressSpace_PreSubmitWeb(void *that);


/**
* Trampolines for original method invocations
*/
@@ -56,35 +56,3 @@ _orgSubmitHandlerOfficial:
// Jump to the original code
mov _orgVaddrPresubmitOfficial(%rip), %rax
jmp *%rax

.globl _preSubmitHandlerWeb
_preSubmitHandlerWeb:
// Choose the routing
test %al, %al
// Standard routing (for normal calls)
jz __ZN4NGFX34nvVirtualAddressSpace_PreSubmitWebEPv
// Wrapped routing (for patched calls)
cmp $1,%al
jz handle_rbx_web
cmp $2,%al
jz handle_r13_web
cmp $3,%al
jz handle_r12_web
// Do we need more registers?
ud2
handle_rbx_web:
PRESUBMIT_FROM_REG(%rbx, __ZN4NGFX34nvVirtualAddressSpace_PreSubmitWebEPv)
handle_r13_web:
PRESUBMIT_FROM_REG(%r13, __ZN4NGFX34nvVirtualAddressSpace_PreSubmitWebEPv)
handle_r12_web:
PRESUBMIT_FROM_REG(%r12, __ZN4NGFX34nvVirtualAddressSpace_PreSubmitWebEPv)

.globl _orgSubmitHandlerWeb
_orgSubmitHandlerWeb:
// This is the prologue we patched out
push %rbp
mov %rsp, %rbp
// Jump to the original code
mov _orgVaddrPresubmitWeb(%rip), %rax
jmp *%rax

2 comments on commit 9ddc075

@JurekR

This comment has been minimized.

Copy link

replied Apr 18, 2018

So are you saying that the new nvidia driver will be as fast without your patch as with it? Your patch runs fine here even with the recent driver...

@vit9696

This comment has been minimized.

Copy link
Collaborator Author

replied Apr 18, 2018

The new nvidia driver incorporates the code above as is.

Please sign in to comment.
You can’t perform that action at this time.