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: Andrew Jones <ajones@ventanamicro.com> Reviewed-by: Anup Patel <anup@brainfault.org> Signed-off-by: Anup Patel <anup@brainfault.org>
This commit is contained in:
parent
bb233a11dc
commit
26b73f1493
|
@ -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,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);
|
||||
|
|
Loading…
Reference in New Issue