ARM64。在 mmap() PCIe BAR 返回的地址上调用 memset() 会导致总线错误

问题描述 投票:0回答:1

我在应用层写了一个非常简单的测试程序。首先,我打开 PCIe 设备,然后

mmap()
PCIe BAR 的起始空间。最后,我使用
mmap()
返回的地址,应用偏移量,并将其传递给
memset()
进行归零。我发现无论地址如何对齐,传递给memset的最大大小只有240字节。当地址对齐小于 16 字节时,传递给
memset()
的最大大小将减少到小于 8 字节。我不知道为什么会这样。

总线错误发生时,没有AER错误。

在驱动程序中使用

memset_io()
/
memcpy_toio()
不会导致错误,无论大小如何,但这些需要特定的 I/O 接口。我不确定在用户空间中使用
memset()
后会发生什么,因为它不使用特定的 I/O 接口。

// driver
static int pci_rc_mmap(struct file *file, struct vm_area_struct *vma)
{
    resource_size_t offset = vma->vm_pgoff << PAGE_SHIFT;
    resource_size_t start = 0;
    
    start = bar2_start_addr;  // bar2_start_addr = pci_resource_start(pdev, BAR_2); bar2_start_addr = 0x1B70000
    
    vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
    
    return io_remap_pfn_range(vma, vma->vm_start, ((start + offset) >> PAGE_SHIFT), vma->vm_end - vma->vm_start, vma->vm_page_prot);
}

// user
int main(int argc, char **argv)
{
    int fd;
    void *bar = NULL;

    fd = open("/dev/pcie-dev", O_RDWR);
    if (fd < 0) {
        perror("open");
        return -1;
    }
    
    bar = mmap(0, 65536, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    
    memset(bar, 0, 241); // Bus error

    munmap(bar, 65536);
    
    close(fd); 
    
    return 0;   
}
linux-device-driver mmap memset pci-e bus-error
1个回答
-1
投票

您好,最后这个问题解决了吗我也遇到了类似的问题,我往mmap的地址写没有报错,但是我去读该地址的数据出现总线错误了

© www.soinside.com 2019 - 2024. All rights reserved.