Re: [PATCH v7 10/21] RISC-V: KVM: Handle MMIO exits for VCPU

From: Paolo Bonzini
Date: Mon Sep 23 2019 - 07:12:25 EST


On 04/09/19 18:15, Anup Patel wrote:
> + unsigned long guest_sstatus =
> + vcpu->arch.guest_context.sstatus | SR_MXR;
> + unsigned long guest_hstatus =
> + vcpu->arch.guest_context.hstatus | HSTATUS_SPRV;
> + unsigned long guest_vsstatus, old_stvec, tmp;
> +
> + guest_sstatus = csr_swap(CSR_SSTATUS, guest_sstatus);
> + old_stvec = csr_swap(CSR_STVEC, (ulong)&__kvm_riscv_unpriv_trap);
> +
> + if (read_insn) {
> + guest_vsstatus = csr_read_set(CSR_VSSTATUS, SR_MXR);

Is this needed? IIUC SSTATUS.MXR encompasses a wider set of permissions:

The HS-level MXR bit makes any executable page readable. {\tt
vsstatus}.MXR makes readable those pages marked executable at the VS
translation level, but only if readable at the guest-physical
translation level.

So it should be enough to set SSTATUS.MXR=1 I think. But you also
shouldn't set SSTATUS.MXR=1 in the !read_insn case.

Also, you can drop the irq save/restore (which is already a save/restore
of SSTATUS) since you already write 0 to SSTATUS.SIE in your csr_swap.
Perhaps add a BUG_ON(guest_sstatus & SR_SIE) before the csr_swap?

> + asm volatile ("\n"
> + "csrrw %[hstatus], " STR(CSR_HSTATUS) ", %[hstatus]\n"
> + "li %[tilen], 4\n"
> + "li %[tscause], 0\n"
> + "lhu %[val], (%[addr])\n"
> + "andi %[tmp], %[val], 3\n"
> + "addi %[tmp], %[tmp], -3\n"
> + "bne %[tmp], zero, 2f\n"
> + "lhu %[tmp], 2(%[addr])\n"
> + "sll %[tmp], %[tmp], 16\n"
> + "add %[val], %[val], %[tmp]\n"
> + "2: csrw " STR(CSR_HSTATUS) ", %[hstatus]"
> + : [hstatus] "+&r"(guest_hstatus), [val] "=&r" (val),
> + [tmp] "=&r" (tmp), [tilen] "+&r" (tilen),
> + [tscause] "+&r" (tscause)
> + : [addr] "r" (addr));
> + csr_write(CSR_VSSTATUS, guest_vsstatus);

>
> +#ifndef CONFIG_RISCV_ISA_C
> + "li %[tilen], 4\n"
> +#else
> + "li %[tilen], 2\n"
> +#endif

Can you use an assembler directive to force using a non-compressed
format for ld and lw? This would get rid of tilen, which is costing 6
bytes (if I did the RVC math right) in order to save two. :)

Paolo

> + "li %[tscause], 0\n"
> +#ifdef CONFIG_64BIT
> + "ld %[val], (%[addr])\n"
> +#else
> + "lw %[val], (%[addr])\n"
> +#endif