What dose sfence.vma do on qemu ?

304 views
Skip to first unread message

Phantom

unread,
Nov 28, 2020, 12:18:17 PM11/28/20
to RISC-V SW Dev
Recently, I try to write a virtual memory init program like linux does, in linux:
1. it first map DRAM to high address, 
2. then calculate the offset between physic address and virtual address, 
3. add the offset to the address of the next instruction after write satp, and write the result to stvec
4. when machine write satp, it will trap a instruction page fault, and pc will set to the value in stvec, 
By this way, it change the physic pc to virtual pc.
But there is a strange thing is that before write satp, it first execute a sfence.vma, like following:

```
// suppose pc in 0x8000xxxx
    call setup_vm     // mapping early_pgtbl 0x8xxx xxxx -> 0xffffffff 8xxx xxxx

    li t0, VM_START
    la t1, _start
    sub a0, t0, t1       // a0 = 0xffffffff 0000 0000

    la t0, 1f
    add t0, t0, a0
    csrw stvec, t0

    # set early_pgtbl to satp
    la t0, early_pgtbl
    srl t0, t0, PAGE_SHIFT
    li t1, SATP_MODE
    or t0, t1, t0
    sfence.vma 
    csrw satp, t0
1:
    ...
```
Why the sfence execute before write satp ? I swap them (or delete sfence) find the program crashed ...
So I log qemu's in_asm stream, I find that:
``` 
    csrw satp, t0
1:
    sfence.vma  

----------------
IN:
...
0x00000000800000f4:  18029073          csrrw           zero,satp,t0

----------------
IN:
0x00000000800000f8:  0000              illegal
0x00000000800000fa:  0000              illegal
0x00000000800000fc:  0000              illegal
0x00000000800000fe:  0000              illegal
0x0000000080000100:  0000              illegal
0x0000000080000102:  0000              illegal
0x0000000080000104:  0000              illegal
0x0000000080000106:  0000              illegal
0x0000000080000108:  0000              illegal
0x000000008000010a:  0000              illegal
0x000000008000010c:  0000              illegal
0x000000008000010e:  0000              illegal
```

For the origin:
```
    sfence.vma    
    csrw satp, t0
1:

----------------
IN:
...
0x00000000800000f4:  12000073          sfence.vma      zero,zero
0x00000000800000f8:  18029073          csrrw           zero,satp,t0

----------------
IN:
0xffffffff800000fc:  0000a117          auipc           sp,40960        # 0xffffffff8000a0fc
...
```
I view sfence as a TLB flush, so in this case, because stap is empty before, we directly write early page table in it. However, it seems when swap or delete sfence, qemu will not throw a page fault, I'm true the page mapping is corret, so is this a bug of qemu or I missunderstanding the sfence. 

Phantom

unread,
Dec 2, 2020, 9:00:51 AM12/2/20
to RISC-V SW Dev, Phantom

After checking, I think this is a qemu bug, https://bugs.launchpad.net/qemu/+bug/1906516
Since sfence.vma will flush tlb, qemu should end its tranlation block

Anup Patel

unread,
Dec 2, 2020, 9:31:38 AM12/2/20
to Phantom, RISC-V SW Dev
Try fence.i immediately after satp csr write.

This will might help speculative execution.

Regards,
Anup

--
You received this message because you are subscribed to the Google Groups "RISC-V SW Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sw-dev+un...@groups.riscv.org.
To view this discussion on the web visit https://groups.google.com/a/groups.riscv.org/d/msgid/sw-dev/2fa98565-ae33-49ef-ae5b-34179a4ffa72n%40groups.riscv.org.
Reply all
Reply to author
Forward
0 new messages