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

From: WANG Xuerui
Date: Tue May 23 2023 - 06:27:34 EST


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.)


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;
}

--
WANG "xen0n" Xuerui

Linux/LoongArch mailing list: https://lore.kernel.org/loongarch/