Commit 26b73f14 authored by Andrew Jones's avatar Andrew Jones Committed by Anup Patel
Browse files

riscv: KVM: Apply insn-def to hlv encodings



Introduce hlv instruction encodings and apply them to KVM's use.
We're careful not to introduce hlv.d to 32-bit builds. Indeed,
we ensure the build fails if someone tries to use it.

Signed-off-by: default avatarAndrew Jones <ajones@ventanamicro.com>
Reviewed-by: default avatarAnup Patel <anup@brainfault.org>
Signed-off-by: default avatarAnup Patel <anup@brainfault.org>
parent bb233a11
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -97,4 +97,21 @@
	INSN_R(OPCODE_SYSTEM, FUNC3(0), FUNC7(49),		\
	       __RD(0), RS1(gaddr), RS2(vmid))

#define HLVX_HU(dest, addr)					\
	INSN_R(OPCODE_SYSTEM, FUNC3(4), FUNC7(50),		\
	       RD(dest), RS1(addr), __RS2(3))

#define HLV_W(dest, addr)					\
	INSN_R(OPCODE_SYSTEM, FUNC3(4), FUNC7(52),		\
	       RD(dest), RS1(addr), __RS2(0))

#ifdef CONFIG_64BIT
#define HLV_D(dest, addr)					\
	INSN_R(OPCODE_SYSTEM, FUNC3(4), FUNC7(54),		\
	       RD(dest), RS1(addr), __RS2(0))
#else
#define HLV_D(dest, addr)					\
	__ASM_STR(.error "hlv.d requires 64-bit support")
#endif

#endif /* __ASM_INSN_DEF_H */
+8 −31
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@

#include <linux/kvm_host.h>
#include <asm/csr.h>
#include <asm/insn-def.h>

static int gstage_page_fault(struct kvm_vcpu *vcpu, struct kvm_run *run,
			     struct kvm_cpu_trap *trap)
@@ -62,11 +63,7 @@ unsigned long kvm_riscv_vcpu_unpriv_read(struct kvm_vcpu *vcpu,
{
	register unsigned long taddr asm("a0") = (unsigned long)trap;
	register unsigned long ttmp asm("a1");
	register unsigned long val asm("t0");
	register unsigned long tmp asm("t1");
	register unsigned long addr asm("t2") = guest_addr;
	unsigned long flags;
	unsigned long old_stvec, old_hstatus;
	unsigned long flags, val, tmp, old_stvec, old_hstatus;

	local_irq_save(flags);

@@ -82,29 +79,19 @@ unsigned long kvm_riscv_vcpu_unpriv_read(struct kvm_vcpu *vcpu,
			".option push\n"
			".option norvc\n"
			"add %[ttmp], %[taddr], 0\n"
			/*
			 * HLVX.HU %[val], (%[addr])
			 * HLVX.HU t0, (t2)
			 * 0110010 00011 00111 100 00101 1110011
			 */
			".word 0x6433c2f3\n"
			HLVX_HU(%[val], %[addr])
			"andi %[tmp], %[val], 3\n"
			"addi %[tmp], %[tmp], -3\n"
			"bne %[tmp], zero, 2f\n"
			"addi %[addr], %[addr], 2\n"
			/*
			 * HLVX.HU %[tmp], (%[addr])
			 * HLVX.HU t1, (t2)
			 * 0110010 00011 00111 100 00110 1110011
			 */
			".word 0x6433c373\n"
			HLVX_HU(%[tmp], %[addr])
			"sll %[tmp], %[tmp], 16\n"
			"add %[val], %[val], %[tmp]\n"
			"2:\n"
			".option pop"
		: [val] "=&r" (val), [tmp] "=&r" (tmp),
		  [taddr] "+&r" (taddr), [ttmp] "+&r" (ttmp),
		  [addr] "+&r" (addr) : : "memory");
		  [addr] "+&r" (guest_addr) : : "memory");

		if (trap->scause == EXC_LOAD_PAGE_FAULT)
			trap->scause = EXC_INST_PAGE_FAULT;
@@ -121,24 +108,14 @@ unsigned long kvm_riscv_vcpu_unpriv_read(struct kvm_vcpu *vcpu,
			".option norvc\n"
			"add %[ttmp], %[taddr], 0\n"
#ifdef CONFIG_64BIT
			/*
			 * HLV.D %[val], (%[addr])
			 * HLV.D t0, (t2)
			 * 0110110 00000 00111 100 00101 1110011
			 */
			".word 0x6c03c2f3\n"
			HLV_D(%[val], %[addr])
#else
			/*
			 * HLV.W %[val], (%[addr])
			 * HLV.W t0, (t2)
			 * 0110100 00000 00111 100 00101 1110011
			 */
			".word 0x6803c2f3\n"
			HLV_W(%[val], %[addr])
#endif
			".option pop"
		: [val] "=&r" (val),
		  [taddr] "+&r" (taddr), [ttmp] "+&r" (ttmp)
		: [addr] "r" (addr) : "memory");
		: [addr] "r" (guest_addr) : "memory");
	}

	csr_write(CSR_STVEC, old_stvec);