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