CreateMemoryDescriptorFromClient can't write data to user?

We've developed a PCIDriverKit driver for the capture card on macOS and have identified an issue: CreateMemoryDescriptorFromClient can only read data from the user space to the driver, but cannot write data back to the user.

typedef struct _MWCAP_EDID_DATA {
    uint64_t size;
    uint64_t uaddr;
} MWCAP_EDID_DATA;


// App
size_t xxx::GetEdid(void *buff, size_t size)
{
    MWCAP_EDID_DATA edid;
    edid.size = size;  
    edid.uaddr = (uint64_t)buff;
    kr = IOConnectCallStructMethod(
                            connect,
                            kUserGetEdid,
                            &edid,
                            sizeof(MWCAP_EDID_DATA),
                            NULL, 
                            NULL
                            );

    // kr is 0. But However, the data in the buffer remains unchanged; 
    // it does not reflect the EDID copied from the DEXT.

    return size;
}

// Driver
MWCAP_EDID_DATA *edid = (MWCAP_EDID_DATA *)input;
IOMemoryDescriptor *user_buf_mem = NULL;

IOAddressSegment segment;
segment.address = edid->uaddr;
segment.length = edid->size;

// We have verified that the values in edid->uaddr and edid->size are consistent with what was set by the application.

ret = CreateMemoryDescriptorFromClient(kIOMemoryDirectionOutIn, 1, &segment, &user_buf_mem);
if (ret != kIOReturnSuccess) {
    os_log(OS_LOG_DEFAULT, "Failed to create memdesc with error: 0x%08x", ret);
    break;
}

IOMemoryMap* user_buf_map = nullptr;
ret = user_buf_mem->CreateMapping(0, 0, 0, 0, 0, &user_buf_map);
if (ret != kIOReturnSuccess) {
    os_log(OS_LOG_DEFAULT, "Failed to create mapping with error: 0x%08x", ret);
    OSSafeReleaseNULL(user_buf_mem);
    break;
}

// ... fill the user_buf_map with edid data ...
// For example:
// memcpy(user_buf_map->GetAddress(), source_edid_data, edid->size);

// At this point we have also verified the data in user_buf_map->GetAddress(), which matches our expectations.

OSSafeReleaseNULL(user_buf_map);
OSSafeReleaseNULL(user_buf_mem);

Please help take a look, thank you!

CreateMemoryDescriptorFromClient can't write data to user?
 
 
Q