0

I am a green hand in linux kernel writing. I have two kvm virtual machines in qemu. I add a ivshmem for each, and they can use open and mmap function to read/write /sys/bus/pci/devices/0000:00:05.0/resource2 to sync memory. Here is a reference: https://liujunming.top/2021/11/30/QEMU-tutorial-Inter-VM-Shared-Memory-device/

# QEMU parameters:
    -object memory-backend-file,size=4M,share=on,mem-path=/dev/shm/shm1,id=shm1 \
    -device ivshmem-plain,memdev=shm1,addr=0x05,master=on

However, I need to sync memory in kernel but not user space. I use linux kernel 5.10.20. There are two functions kernel_read and kernel_write. I can use the two functions to read/write a normal file such as /home/xxx/a.txt, but I cannot read/write /sys/bus/pci/devices/0000:00:05.0/resource2.

Here is my code to read the first character:

char buf_2[1];

void read_file(const char *filename)
{
    ssize_t i;
    struct file *f = NULL;
    loff_t f_pos = 0;

    f = filp_open(filename, O_RDWR, 0);
    if (IS_ERR(f)) {
        pr_err("open file error!\n");
    }

    memset(buf_2, 0, sizeof(buf_2));
    i = kernel_read(f, buf_2, 1, &f_pos);
    pr_info("f: %p, f_pos: %lld, buf_2: %d, i: %ld", f, f_pos, buf_2[0], i);

    filp_close(f, NULL);
}

When I pass /home/xxx/a.txt and /sys/bus/pci/devices/0000:00:05.0/resource2 to the read_file, it prints this:

[   40.154424] f: 00000000cad673bc, f_pos: 1, buf_2: 115, i: 1
[   40.154457] f: 0000000047ddc318, f_pos: 0, buf_2: 0, i: -5

The first result is corrent. But the second is not. And kernel_read returns a error code -5.

How can I read/write /sys/bus/pci/devices/0000:00:05.0/resource2 in linux kernel?

$ ls /sys/bus/pci/devices/0000:00:05.0/
ari_enabled               driver_override  msi_bus    resource2_wc
broken_parity_status      enable           numa_node  revision
class                     firmware_node    power      subsystem
config                    irq              remove     subsystem_device
consistent_dma_mask_bits  link             rescan     subsystem_vendor
d3cold_allowed            local_cpulist    resource   uevent
device                    local_cpus       resource0  vendor
dma_mask_bits             modalias         resource2

$ cat /sys/bus/pci/devices/0000:00:05.0/resource
0x00000000c1031000 0x00000000c10310ff 0x0000000000040200
0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000001000000000 0x00000010003fffff 0x000000000014220c
0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 0x0000000000000000
CatFood
  • 13
  • 5
  • 1
    _resource*_ files are the representations of the PCI BARs IIUC, so it means that you just need to find a PCI device and get its resources: `struct pci_dev *pdev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(5, 0)); struct resource *res = &pdev->resource[2]; dev_info(&pdev->dev, "%pR\n", res); pci_dev_put(pdev)`. – 0andriy May 18 '22 at 17:08
  • Couple of important notes: 1) opening files in the kernel is a bad idea; 2) *writing* to that file is not a simple operation — one needs to be quite aware of how PCI bus resource management works. – 0andriy May 23 '22 at 07:49

0 Answers0