Re: lapic detection at runtime for kernel modules

"Jean-Yves Migeon (NetBSD)" <[email protected]> Thu, 20 Mar 2025 19:40:32 +0100
Newsgroups gmane.os.netbsd.ports.x86-64
Organization NetBSD
Message-ID <[email protected]>
Oh hai,

Le 16/03/2025 à 07:45, Emile `iMil' Heitor a écrit :
> I'm in the process of adding support for CPUID leaf 0x40000010 in the
> NVMM hypervisor.
> This leaf forwards TSC and LAPIC frequency from the host machine to
> the guest in order to avoid their computation and gain speed at boot
> time. This is easily done in sys/dev/nvmm/x86/nvmm_x86_{svm,vmx}.c
> 
> cpudata->gprs[NVMM_X64_GPR_RAX] = curcpu()->ci_data.cpu_cc_freq / 1000;
> cpudata->gprs[NVMM_X64_GPR_RBX] = lapic_per_second / 1000;
> 
> [...]
> for nvmm and check for lapic presence at runtime.
> I came up with the following piece of code to achieve just that:
> 
> static bool
> cpu_has_lapic(struct cpu_info *ci)
> {
>      int i;
>      struct intrsource *isp;
> 
>      for (i = 0; i < MAX_INTR_SOURCES; i++) {
>          isp = ci->ci_isources[i];
>          if (isp == NULL)
>              continue;
>          if (isp->is_pic->pic_type == PIC_LAPIC)
>              return true;
>      }
>      return false;
> }
> 
> Does this seem reasonable?

I would say yes (assumption), however note that it depends on caller's 
context especially if it passes down curcpu() or another reference, or 
iterates with CPU_INFO_FOREACH(...). In that case I would

     KASSERT(kpreempt_disabled()) or KASSERT(mutex_owned(&cpu_lock))

at the beginning if you expect it to be used in paths with these 
properties (especially kernel preemption -- I don't think &cpu_lock is 
expected for that case alone).

I guess that your intent is to use the LAPIC check to set the leaf regs 
afterwards, but as there is no way to ensure the cpu_info passed as ref 
is the one from the same curcpu()... hence my recommendation for the 
kpreempt check

Cheers (:

-- 
jym@