2

I can't set correctly shared memory for Qemu RISCV emulation.
My intention is to create a portion of shared memory between Qemu RISCV emulator and the host server. I need this because my intention will be then to interface Qemu with a FPGA and probably this is best method (for the best I have understood).

But anyway, I think I'm not able to do it.

This is the command I use for running the emulation:

qemu-system-riscv64 -M 'virt' \
-cpu 'rv64' -smp 4 -m 4096 \
-object memory-backend-file,size=1G,share=on,mem-path=/dev/shm,id=hostmem \
-device virtio-blk-device,drive=hd \
-drive file=/home/user/qemu/db-riscv64/image.qcow2,if=none,id=hd \
-device virtio-net-device,netdev=net \
-netdev user,id=net,hostfwd=tcp::2222-:22 \
-bios  /usr/share/qemu/opensbi-riscv64-generic-fw_dynamic.bin \
-kernel /home/user/qemu/db-riscv64/kernel \
-initrd /home/user/qemu/db-riscv64/initrd \
-nographic  -append "root=LABEL=rootfs console=ttyS0"

I'm trying to allocate 1G of shared memory on /dev/shm (RAM is faster). So my first step would be to make the host and Qemu communicate through /dev/shm, but I'm not able for instance to write something on the host and read from Qemu, and viceversa.

I tried with another folder with -virtfs local,path=/home/user/qemu/db-riscv64 shared_memory,mount_tag=shared,security_model=none,id=hostshare and I was able to read and write from host to Qemu.

Could anyone kindly tell me what's wrong with these stuff?

I premise that it is the first time I use Qemu and it is not too clear to me how to use shared memory with that.

EDIT: I solved by means of ivshmem as suggested, but now I have another problem. The command for running qemu is now the following:

qemu-system-riscv64 -M 'virt' \
-cpu 'rv64' -smp 4 -m 4096 \
-object memory-backend-file,size=1G,share=on,mem-path=/dev/shm,id=hostmem \
-device ivshmem-plain,memdev=hostmem \
-device virtio-blk-device,drive=hd \
-drive file=/home/user/qemu/db-riscv64/image.qcow2,if=none,id=hd \
-device virtio-net-device,netdev=net \
-netdev user,id=net,hostfwd=tcp::2222-:22 \
-bios  /usr/share/qemu/opensbi-riscv64-generic-fw_dynamic.bin \
-kernel /home/user/qemu/db-riscv64/kernel \
-initrd /home/user/qemu/db-riscv64/initrd \
-virtfs local,path=/home/user/qemu/db-riscv64/shared_folder,mount_tag=shared,security_model=none,id=hostshare \
-nographic  -append "root=LABEL=rootfs console=ttyS0"

Using lspci -vv I obtain:

00:00.0 Host bridge: Red Hat, Inc. QEMU PCIe Host bridge
        Subsystem: Red Hat, Inc. Device 1100
        Control: I/O- Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
        Status: Cap- 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-

00:01.0 RAM memory: Red Hat, Inc. Inter-VM shared memory (rev 01)
        Subsystem: Red Hat, Inc. QEMU Virtual Machine
        Control: I/O- Mem+ BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
        Status: Cap- 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
        Region 0: Memory at 40001000 (32-bit, non-prefetchable) [size=256]
        Region 2: Memory at 400000000 (64-bit, prefetchable) [size=1G]

00:02.0 Unclassified device [0002]: Red Hat, Inc. Virtio filesystem
        Subsystem: Red Hat, Inc. Device 0009
        Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
        Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
        Latency: 0
        Interrupt: pin A routed to IRQ 12
        Region 0: I/O ports at 0020 [size=32]
        Region 1: Memory at 40000000 (32-bit, non-prefetchable) [size=4K]
        Region 4: Memory at 440000000 (64-bit, prefetchable) [size=16K]
        Capabilities: <access denied>
        Kernel driver in use: virtio-pci

So now I want to execute this C code on the riscv VM:

#include <sys/mman.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdint.h>

#define SHM_SIZE 4096 // size of the shared memory region to map
#define SHM_BAR 0x400000000 // BAR address of the ivshmem device (obtained from lspci)

void write_to_shared_memory(){
    volatile uint32_t *shm = (volatile uint32_t *)SHM_BAR;
    shm[0] = 1234;  
    printf("Written Data: %d\n", shm[0]);
}

int main() {
    int fd = open("/dev/mem", O_RDWR); // open the /dev/mem device file
    if (fd == -1) {
        perror("open");
        return -1;
    }
    void *shm = mmap(NULL, SHM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, SHM_BAR); // map the BAR address to shm
    if (shm == MAP_FAILED) {
        perror("mmap");
        return -1;
    }
    // do something with shm, such as reading or writing data
    write_to_shared_memory();

    munmap(shm, SHM_SIZE); // unmap the shared memory region
    close(fd); // close the /dev/mem device file
    return 0;
}

But I get segmentation fault:

[11086.441459] memory_sharing[475]: unhandled signal 11 code 0x1 at 0x0000000400000000 in memory_sharing[5555571d8000+1000]
[11086.441834] CPU: 1 PID: 475 Comm: memory_sharing Not tainted 6.8.12-riscv64 #1  Debian 6.8.12-1
[11086.442040] Hardware name: riscv-virtio,qemu (DT)
[11086.442156] epc : 00005555571d87ee ra : 00005555571d8880 sp : 00007ffff7628a90
[11086.442324]  gp : 00005555571da838 tp : 00007fff970193c0 t0 : 000000007c9ab170
[11086.442493]  t1 : 00007fff96f6fae8 t2 : 0000000001f26ac5 s0 : 00007ffff7628ab0
[11086.442664]  s1 : 0000000000000001 a0 : 00007fff9701b000 a1 : 0000000000001000
[11086.442833]  a2 : 0000000000000003 a3 : 0000000000000001 a4 : 00000000000004d2
[11086.443004]  a5 : 0000000400000000 a6 : 0000000000000000 a7 : 00000000000000de
[11086.443174]  s2 : 0000000000000000 s3 : 00005555571d9de0 s4 : 00005555571d8810
[11086.443346]  s5 : 00007ffff7628c68 s6 : 00005555571d9de0 s7 : 00007fff97040d20
[11086.443516]  s8 : 00007fff97041000 s9 : 00007fffe9dd7420 s10: 0000000000000001
[11086.443680]  s11: ffffffffffffffff t3 : 0000000000000030 t4 : 0000000000000000
[11086.443841]  t5 : 00007fff97042270 t6 : 00007fff97018548
[11086.443966] status: 8000000200006020 badaddr: 0000000400000000 cause: 000000000000000f
[11086.444170] Code: e822 1000 4785 178a 3423 fef4 3783 fe84 0713 4d20 (c398) 3783 
Segmentation fault

Does anyone know what's happening here?

1
  • 1
    You need to use the mmap returned address (virtual memory in your process mapped onto BAR), not physical address itself. Commented Mar 21 at 8:18

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.