riscv: KVM: Apply insn-def to hlv encodings
authorAndrew Jones <ajones@ventanamicro.com>
Sun, 2 Oct 2022 04:48:20 +0000 (10:18 +0530)
committerAnup Patel <anup@brainfault.org>
Sun, 2 Oct 2022 04:48:20 +0000 (10:18 +0530)
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>
arch/riscv/include/asm/insn-def.h
arch/riscv/kvm/vcpu_exit.c

index c8aca3c..af7b0b5 100644 (file)
        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 */
index d5c3638..c9f741a 100644 (file)
@@ -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);