Hello Community,
I decided to check how KVM determines a length of VMIDLEN and found the following:
void __init kvm_riscv_gstage_vmid_detect(void)
{
unsigned long old;
/* Figure-out number of VMID bits in HW */
old = csr_read(CSR_HGATP);
csr_write(CSR_HGATP, old | HGATP_VMID);
vmid_bits = csr_read(CSR_HGATP);
vmid_bits = (vmid_bits & HGATP_VMID) >> HGATP_VMID_SHIFT;
vmid_bits = fls_long(vmid_bits);
csr_write(CSR_HGATP, old);
/* We polluted local TLB so flush all guest TLB */
kvm_riscv_local_hfence_gvma_all();
/* We don't use VMID bits if they are not sufficient */
if ((1UL << vmid_bits) < num_possible_cpus())
vmid_bits = 0;
}
It is not clear actually why so broad ( a guest ) and why not hfence_gvma_vmid(vmid_bits).And I am not really 100% sure that any hfence_gvma() is needed here as I don't see what could pollutes local guest TLB between csr_write() calls.RISC-V spec. says that:
Note that writing hgatp does not imply any ordering constraints between page-table updates and subsequent G-stage address translations. If the new virtual machine's guest physical page tables have been modified, or if a VMID is reused, it may be necessary to execute an HFENCE.GVMA instruction (see Section 18.3.2) before or after writing hgatp.
But we don't modify VM's guest physical page table. We could potentially reuse VMID between csr_write() calls, but it is returning back and we don't switch to a guest with this "new" VMID, so it isn't really used.Any pointers about that?Thanks in advance.