Opened 9 years ago
Last modified 9 years ago
#32 assigned defect
Adjust RTMp* R0 API for OS/2
Reported by: | dmik | Owned by: | Valery V. Sedletski |
---|---|---|---|
Priority: | blocker | Milestone: | SMP Mode |
Component: | Driver | Keywords: | |
Cc: |
Description
The current SVN (r55) uses the generic implementations of all RTMp*
functions on OS/2 (as other platforms do). The only non-generic ones are RTMpCurSetIndex
and RTMpCurSetIndexAndId
but they are simply synonyms for the generic RTMpCpuId
(which simply calls ASMGetApicId
).
However, VBoxDrv.sys
(where these APIs are used) fails to process the open call in this state ATM. While it is known that it works if we provide dummy RTMp
implementations that behave as if there is only one CPU, instead of using generic implementations. It needs to be found out why generic implementations fail. Depending on that we will decide what to do.
Change History (6)
comment:1 by , 9 years ago
Owner: | set to |
---|---|
Status: | new → assigned |
comment:3 by , 9 years ago
Milestone: | VBox driver → preview |
---|
comment:4 by , 9 years ago
So far, the solution above (use starting the code on a current processor for RTMpOnAll() and RTMpOnSpecific() and a dummy, returning VERR_NOT_SUPPORTED, for RTMpOnOthers()) works on UNI and SMP machines without problems. I.e., if we not trying to use emulation of more than one processor, and don't use hardware virtualisation (of course, we need them, but for now, we may use an "uniprocessor" case only), then we are safe.
Running code on more than one processor in sync requires "SMP rendezvous" function, and for that, the help of kernel and PSD is needed. But this function in needed mainly for turning on the VT-x/AMD-V support on all cores simultaneously, and for updating the TSC counters in GIP structure, which needs to be done on all cores in sync too.
We don't use VT-x/AMD-V for now, and have disabled the TSC thread for now too, so with these limitations, we can live without RTMpOnAll/SMP rendezvous. And because of that, we're safe to run code on current core only.
comment:5 by , 9 years ago
The task (investigate, why the dummy functions don't work) is completed, the next level task (make real RTMp implementation) is not for the preview, so I move this to "SMP" milestone.
comment:6 by , 9 years ago
Milestone: | preview → SMP Mode |
---|
The generic implementation fails because it's needed a real RTMpOnAll/RTMpOnSpecific implementation, not returning just a VERR_NOT_SUPPORTED, but starting a real thread. For a single core case, it is sufficient to start a thread on a current CPU, and assert that we're starting it on a current CPU only, and return VERR_CPU_NOT_FOUND otherwise. Real multicore implementation requires CPU rendezvous in the kernel, or, at least, some kind of thread affinity API for kernel threads, this is to start a thread on a specific CPU, or on a set of CPU's in parallel.
The vboxdrv.sys failed to process the open call because it failed to start some thread, and driver init failed, so no driver in memory and opening it fails.
Also, it should be noted that ASMGetApicId returns the LAPIC ID, which is not necessarily started with 0, and can have breaks. So, situations with LAPIC ID's like this:
or
or
are possible. So, we should use it as CpuId with care, and it may happen that generic implementation may fail because of this (it seems that some places assume that the CpuId starts with 0 and uses consecutive numbers.)
Also, pure generic implementation seems to be valid for single core only, because RTMpGetMaxCpuId returns RTMpCpuId, i.e., max. CpuId is the current one, which is valid for single CPU only. The same with RTMpIsCpuOnline, RTMpIsCpuPossible. And we see that
is used in RuntimeR0Drv for OS/2 only. Other OS'es use a 'real' implementation. All OS'es also use their own RTMpCpuId() implementation, not just a LAPIC ID.
Also, note that we on OS/2 have DHGETDOSV_TOTALCPUS DosHlp_GetDosVar option (undocumented?), so we can get the no. of CPU's from there. Looking at FreeBSD implementation, I can see that three functions are needed for 'real' implementation: 1) no. of CPU's 2) no. of current CPU 2) CPU rendezvous.