Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

RISC-V: KVM: Fix GPA passed to __kvm_riscv_hfence_gvma_xyz() functions

The parameter passed to HFENCE.GVMA instruction in rs1 register
is guest physical address right shifted by 2 (i.e. divided by 4).

Unfortunately, we overlooked the semantics of rs1 registers for
HFENCE.GVMA instruction and never right shifted guest physical
address by 2. This issue did not manifest for hypervisors till
now because:
1) Currently, only __kvm_riscv_hfence_gvma_all() and SBI
HFENCE calls are used to invalidate TLB.
2) All H-extension implementations (such as QEMU, Spike,
Rocket Core FPGA, etc) that we tried till now were
conservatively flushing everything upon any HFENCE.GVMA
instruction.

This patch fixes GPA passed to __kvm_riscv_hfence_gvma_vmid_gpa()
and __kvm_riscv_hfence_gvma_gpa() functions.

Fixes: fd7bb4a251df ("RISC-V: KVM: Implement VMID allocator")
Reported-by: Ian Huang <ihuang@ventanamicro.com>
Signed-off-by: Anup Patel <anup.patel@wdc.com>
Message-Id: <20211026170136.2147619-4-anup.patel@wdc.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

authored by

Anup Patel and committed by
Paolo Bonzini
7c8de080 0a86512d

+5 -4
+3 -2
arch/riscv/include/asm/kvm_host.h
··· 214 214 215 215 #define KVM_ARCH_WANT_MMU_NOTIFIER 216 216 217 - void __kvm_riscv_hfence_gvma_vmid_gpa(unsigned long gpa, unsigned long vmid); 217 + void __kvm_riscv_hfence_gvma_vmid_gpa(unsigned long gpa_divby_4, 218 + unsigned long vmid); 218 219 void __kvm_riscv_hfence_gvma_vmid(unsigned long vmid); 219 - void __kvm_riscv_hfence_gvma_gpa(unsigned long gpa); 220 + void __kvm_riscv_hfence_gvma_gpa(unsigned long gpa_divby_4); 220 221 void __kvm_riscv_hfence_gvma_all(void); 221 222 222 223 int kvm_riscv_stage2_map(struct kvm_vcpu *vcpu,
+2 -2
arch/riscv/kvm/tlb.S
··· 31 31 32 32 ENTRY(__kvm_riscv_hfence_gvma_vmid_gpa) 33 33 /* 34 - * rs1 = a0 (GPA) 34 + * rs1 = a0 (GPA >> 2) 35 35 * rs2 = a1 (VMID) 36 36 * HFENCE.GVMA a0, a1 37 37 * 0110001 01011 01010 000 00000 1110011 ··· 53 53 54 54 ENTRY(__kvm_riscv_hfence_gvma_gpa) 55 55 /* 56 - * rs1 = a0 (GPA) 56 + * rs1 = a0 (GPA >> 2) 57 57 * rs2 = zero 58 58 * HFENCE.GVMA a0 59 59 * 0110001 00000 01010 000 00000 1110011