Re: [PATCH v10 00/30] Add KVM LoongArch support

From: maobibo
Date: Tue May 23 2023 - 07:57:35 EST




在 2023/5/23 18:27, WANG Xuerui 写道:
> On 2023/5/23 10:54, maobibo wrote:
>>
>> [snip]
>>
>> I hate parse_r helper also, it is hard to understand, the kernel about
>> LoongArch has the same issue. How about using a fixed register like this?
>>
>> /* GCSR */
>> static __always_inline u64 gcsr_read(u32 reg)
>> {
>>     u64 val = 0;
>>
>>     BUILD_BUG_ON(!__builtin_constant_p(reg));
>>     /* Instructions will be available in binutils later */
>>     asm volatile (
>>         "parse_r __reg, %[val]\n\t"
>
> Isn't this still parse_r-ing things? ;-)
>
>>         /*
>>          * read val from guest csr register %[reg]
>>          * gcsrrd %[val], %[reg]
>>          */
>>         ".word 0x5 << 24 | %[reg] << 10 | 0 << 5 | __reg\n\t"
>>         : [val] "+r" (val)
>>         : [reg] "i" (reg)
>>         : "memory");
>>
>>     return val;
>> }
>>
>> /* GCSR */
>> static __always_inline u64 gcsr_read(u32 reg)
>> {
>>          register unsigned long val asm("t0");
>
> I got what you're trying to accomplish here. At which point you may just refer to how glibc implements its inline syscall templates and hardcode both the input and output arguments, then simply hard-code the whole instruction word. If others don't have opinions about doing things this way, I wouldn't either.
>
> (CSR operations are not expected to become performance-sensitive in any case, so you may freely choose registers here, and t0 for output seems okay. I'd recommend stuffing "reg" to a temporary value bound to a0 though.)
a0 is ok for me.

riscv has better method than both parse_r helper and using tmp register
as follows, maybe we can use the similiar method.

.macro insn_r, opcode, func3, func7, rd, rs1, rs2
.4byte ((\opcode << INSN_R_OPCODE_SHIFT) | \
(\func3 << INSN_R_FUNC3_SHIFT) | \
(\func7 << INSN_R_FUNC7_SHIFT) | \
(.L__gpr_num_\rd << INSN_R_RD_SHIFT) | \
(.L__gpr_num_\rs1 << INSN_R_RS1_SHIFT) | \
(.L__gpr_num_\rs2 << INSN_R_RS2_SHIFT))
.endm

#define HINVAL_VVMA(vaddr, asid) \
INSN_R(OPCODE_SYSTEM, FUNC3(0), FUNC7(19), \
__RD(0), RS1(vaddr), RS2(asid))

asm volatile(HINVAL_VVMA(%0, %1)
: : "r" (pos), "r" (asid) : "memory");

Regards
Bibo, Mao
>
>>
>>          BUILD_BUG_ON(!__builtin_constant_p(reg));
>>          /* Instructions will be available in binutils later */
>>          asm volatile (
>>                  "parse_r __reg, %[val]\n\t"
>>                  /*
>>                   * read val from guest csr register %[reg]
>>                   * gcsrrd %[val], %[reg]
>>                   */
>>                  ".word 0x5 << 24 | %[reg] << 10 | 0 << 5 | 12 \n\t"
>>                  : : [reg] "i" (reg)
>>                  : "memory", "t0");
>>
>>          return val;
>> }
>