On 2026/1/13 上午5:45, Richard Henderson wrote:
On 1/12/26 19:07, Bibo Mao wrote:
+#if defined(CONFIG_KVM)
+static int read_cpuinfo(const char *field, char *value, int len)
+{
+ FILE *f;
+ int ret = -1;
+ int field_len = strlen(field);
+ char line[512];
+
+ f = fopen("/proc/cpuinfo", "r");
+ if (!f) {
+ return -1;
+ }
+
+ do {
+ if (!fgets(line, sizeof(line), f)) {
+ break;
+ }
+ if (!strncmp(line, field, field_len)) {
+ strncpy(value, line, len);
+ ret = 0;
+ break;
+ }
+ } while (*line);
+
+ fclose(f);
+
+ return ret;
+}
+
+static uint64_t get_host_cpu_model(void)
+{
+ char line[512];
+ char *ns;
+ static uint64_t cpuid;
+
+ if (cpuid) {
+ return cpuid;
+ }
+
+ if (read_cpuinfo("Model Name", line, sizeof(line))) {
+ return 0;
+ }
+
+ ns = strchr(line, ':');
+ if (!ns) {
+ return 0;
+ }
+
+ ns = strstr(ns, "Loongson-");
+ if (!ns) {
+ return 0;
+ }
+
+ ns += strlen("Loongson-");
+ memccpy((void *)&cpuid, ns, 0, 8);
+ return cpuid;
+}
+
+static uint32_t get_host_cpucfg(int number)
+{
+ unsigned int data = 0;
+
+#ifdef __loongarch__
+ asm volatile("cpucfg %[val], %[reg]"
+ : [val] "=r" (data)
+ : [reg] "r" (number)
+ : "memory");
+#endif
+
+ return data;
+}
Are you sure you should be bypassing KVM for this? Other targets start
a scratch vcpu and then read the values via KVM_GET_ONE_REG.
Feature detection instruction CPUCFG can be executed in user mode,
similar with CPUID on X86, on ARM platform instruction MRS can only used
in privileged mode.
On LoongArch platform, it is both OK to detect host CPU features by
CPUCFG instruction or KVM_GET_DEVICE_ATTR ioctl command method.
struct kvm_device_attr attr = {
.group = KVM_LOONGARCH_VCPU_CPUCFG,
.attr = 2,
.addr = (uint64_t)&val,
};
CPULoongArchState *env = cpu_env(cs);
ret = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, &attr);
if (!ret) {
kvm_vcpu_ioctl(cs, KVM_GET_DEVICE_ATTR, &attr);
}
Regards
Bibo Mao
I'm not sure how much trap-and-emulate support LoongArch has for such ID
registers.
r~