Opened 8 years ago

Last modified 8 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 Changed 8 years ago by dmik

Owner: set to Valery V. Sedletski
Status: newassigned

comment:2 Changed 8 years ago by Valery V. Sedletski

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:

Processors:     APIC ID
                16
                17
                18
                19

or

Processors:     APIC ID
                 0
                 2
                 4
                 6

or

Processors:     APIC ID
                 0
                 4

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

generic\RTMpGetMaxCpuId-generic.cpp

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.

Last edited 8 years ago by Valery V. Sedletski (previous) (diff)

comment:3 Changed 8 years ago by dmik

Milestone: VBox driverpreview

comment:4 Changed 8 years ago by Valery V. Sedletski

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 Changed 8 years ago by Valery V. Sedletski

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 Changed 8 years ago by Valery V. Sedletski

Milestone: previewSMP Mode
Note: See TracTickets for help on using tickets.