mp-r0drv-solaris.c revision e904b5a4859a22fe1f1c34f53b72729955923c46
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync/* $Id$ */
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync/** @file
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync * IPRT - Multiprocessor, Ring-0 Driver, Solaris.
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync */
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync/*
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * Copyright (C) 2008 Oracle Corporation
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync *
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync * available from http://www.virtualbox.org. This file is free software;
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync * you can redistribute it and/or modify it under the terms of the GNU
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * General Public License (GPL) as published by the Free Software
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync *
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * The contents of this file may alternatively be used under the terms
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * of the Common Development and Distribution License Version 1.0
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync * VirtualBox OSE distribution, in which case the provisions of the
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync * CDDL are applicable instead of those of the GPL.
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync *
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync * You may elect to license modified versions of this file under the
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync * terms and conditions of either the GPL or the CDDL or both.
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync */
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
da957c069c2a3c582fe265ff88170ce4c42b499dvboxsync/*******************************************************************************
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync* Header Files *
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync*******************************************************************************/
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync#include "the-solaris-kernel.h"
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync#include "internal/iprt.h"
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync#include <iprt/mp.h>
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync#include <iprt/cpuset.h>
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync#include <iprt/thread.h>
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync#include <iprt/asm.h>
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync# include <iprt/asm-amd64-x86.h>
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync#endif
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync#include <iprt/err.h>
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync#include "r0drv/mp-r0drv.h"
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsynctypedef int FNRTMPSOLWORKER(void *pvUser1, void *pvUser2, void *pvUser3);
0f1e77149ab5ab40fa2bd74a5330e087416b3c7bvboxsynctypedef FNRTMPSOLWORKER *PFNRTMPSOLWORKER;
0f1e77149ab5ab40fa2bd74a5330e087416b3c7bvboxsync
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsyncRTDECL(bool) RTMpIsCpuWorkPending(void)
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync{
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync return false;
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync}
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsyncRTDECL(RTCPUID) RTMpCpuId(void)
0f1e77149ab5ab40fa2bd74a5330e087416b3c7bvboxsync{
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync return CPU->cpu_id;
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync}
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsyncRTDECL(int) RTMpCpuIdToSetIndex(RTCPUID idCpu)
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync{
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync return idCpu < RTCPUSET_MAX_CPUS && idCpu <= max_cpuid ? idCpu : -1;
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync}
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
0f1e77149ab5ab40fa2bd74a5330e087416b3c7bvboxsyncRTDECL(RTCPUID) RTMpCpuIdFromSetIndex(int iCpu)
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync{
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync return (unsigned)iCpu <= max_cpuid ? iCpu : NIL_RTCPUID;
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync}
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsyncRTDECL(RTCPUID) RTMpGetMaxCpuId(void)
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync{
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync return max_cpuid;
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync}
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsyncRTDECL(bool) RTMpIsCpuOnline(RTCPUID idCpu)
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync{
fe96bc0e43d9c137304462ef8c2d79cbff22446fvboxsync /*
fa033b734cf3b131680f290326ccbbd23c42946bvboxsync * We cannot query CPU status recursively, check cpu member from cached set.
fe96bc0e43d9c137304462ef8c2d79cbff22446fvboxsync */
fe96bc0e43d9c137304462ef8c2d79cbff22446fvboxsync if (idCpu >= ncpus)
fe96bc0e43d9c137304462ef8c2d79cbff22446fvboxsync return false;
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
fa033b734cf3b131680f290326ccbbd23c42946bvboxsync return RTCpuSetIsMember(&g_rtMpSolCpuSet, idCpu);
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync}
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsyncRTDECL(bool) RTMpIsCpuPossible(RTCPUID idCpu)
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync{
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync return idCpu < ncpus;
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync}
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsyncRTDECL(PRTCPUSET) RTMpGetSet(PRTCPUSET pSet)
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync{
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync RTCPUID idCpu;
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync RTCpuSetEmpty(pSet);
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync idCpu = RTMpGetMaxCpuId(); /* it's inclusive */
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync do
0f1e77149ab5ab40fa2bd74a5330e087416b3c7bvboxsync {
0f1e77149ab5ab40fa2bd74a5330e087416b3c7bvboxsync if (RTMpIsCpuPossible(idCpu))
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync RTCpuSetAdd(pSet, idCpu);
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync } while (idCpu-- > 0);
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync return pSet;
0f1e77149ab5ab40fa2bd74a5330e087416b3c7bvboxsync}
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
0f1e77149ab5ab40fa2bd74a5330e087416b3c7bvboxsync
0f1e77149ab5ab40fa2bd74a5330e087416b3c7bvboxsyncRTDECL(RTCPUID) RTMpGetCount(void)
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync{
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync return ncpus;
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync}
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsyncRTDECL(PRTCPUSET) RTMpGetOnlineSet(PRTCPUSET pSet)
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync{
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync /*
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync * We cannot query CPU status recursively, return the cached set.
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync */
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync *pSet = g_rtMpSolCpuSet;
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync return pSet;
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync}
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsyncRTDECL(RTCPUID) RTMpGetOnlineCount(void)
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync{
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync RTCPUSET Set;
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync RTMpGetOnlineSet(&Set);
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync return RTCpuSetCount(&Set);
0f1e77149ab5ab40fa2bd74a5330e087416b3c7bvboxsync}
0f1e77149ab5ab40fa2bd74a5330e087416b3c7bvboxsync
aa32d4906f2f685992091893d5abdf27a2352a85vboxsync
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync/**
aa32d4906f2f685992091893d5abdf27a2352a85vboxsync * Wrapper to Solaris IPI infrastructure.
e3f5c51715cbf77ae2d2e9d05bafd00d69b1bec9vboxsync *
aa32d4906f2f685992091893d5abdf27a2352a85vboxsync * @param pCpuSet Pointer to Solaris CPU set.
aa32d4906f2f685992091893d5abdf27a2352a85vboxsync * @param pfnSolWorker Function to execute on target CPU(s).
aa32d4906f2f685992091893d5abdf27a2352a85vboxsync * @param pArgs Pointer to RTMPARGS to pass to @a pfnSolWorker.
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync *
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync * @returns Solaris error code.
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync */
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsyncstatic void rtMpSolCrossCall(PRTSOLCPUSET pCpuSet, PFNRTMPSOLWORKER pfnSolWorker, PRTMPARGS pArgs)
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync{
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync AssertPtrReturnVoid(pCpuSet);
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync AssertPtrReturnVoid(pfnSolWorker);
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync AssertPtrReturnVoid(pCpuSet);
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync if (g_frtSolOldIPI)
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync {
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync if (g_frtSolOldIPIUlong)
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync {
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync g_rtSolXcCall.u.pfnSol_xc_call_old_ulong((xc_arg_t)pArgs, /* Arg to IPI function */
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync 0, /* Arg2, ignored */
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync 0, /* Arg3, ignored */
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync IPRT_SOL_X_CALL_HIPRI, /* IPI priority */
b7a5b3f9f9ecce32ddacf8404c625ce0451bbdc1vboxsync pCpuSet->auCpus[0], /* Target CPU(s) */
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync (xc_func_t)pfnSolWorker); /* Function to execute on target(s) */
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync }
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync else
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync {
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync g_rtSolXcCall.u.pfnSol_xc_call_old((xc_arg_t)pArgs, /* Arg to IPI function */
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync 0, /* Arg2, ignored */
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync 0, /* Arg3, ignored */
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync IPRT_SOL_X_CALL_HIPRI, /* IPI priority */
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync *pCpuSet, /* Target CPU set */
b514c03a427443a7ad18c1202d2ee7acc47cf9afvboxsync (xc_func_t)pfnSolWorker); /* Function to execute on target(s) */
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync }
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync }
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync else
b7a5b3f9f9ecce32ddacf8404c625ce0451bbdc1vboxsync {
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync g_rtSolXcCall.u.pfnSol_xc_call((xc_arg_t)pArgs, /* Arg to IPI function */
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync 0, /* Arg2 */
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync 0, /* Arg3 */
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync &pCpuSet->auCpus[0], /* Target CPU set */
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync (xc_func_t)pfnSolWorker); /* Function to execute on target(s) */
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync }
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync}
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync/**
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync * Wrapper between the native solaris per-cpu callback and PFNRTWORKER
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync * for the RTMpOnAll API.
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync *
fe813b3594039ba864493438e78ee0e7132bc445vboxsync * @param uArgs Pointer to the RTMPARGS package.
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync * @param uIgnored1 Ignored.
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync * @param uIgnored2 Ignored.
b514c03a427443a7ad18c1202d2ee7acc47cf9afvboxsync */
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsyncstatic int rtMpSolOnAllCpuWrapper(void *uArg, void *uIgnored1, void *uIgnored2)
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync{
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync PRTMPARGS pArgs = (PRTMPARGS)(uArg);
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync /*
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync * Solaris CPU cross calls execute on offline CPUs too. Check our CPU cache
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync * set and ignore if it's offline.
914d33aebb63d8c288dfd1b7e74f8e2acf3eaa66vboxsync */
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync if (!RTMpIsCpuOnline(RTMpCpuId()))
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync return 0;
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync pArgs->pfnWorker(RTMpCpuId(), pArgs->pvUser1, pArgs->pvUser2);
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync NOREF(uIgnored1);
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync NOREF(uIgnored2);
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync return 0;
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync}
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsyncRTDECL(int) RTMpOnAll(PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2)
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync{
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync RTMPARGS Args;
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync RT_ASSERT_INTS_ON();
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync Args.pfnWorker = pfnWorker;
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync Args.pvUser1 = pvUser1;
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync Args.pvUser2 = pvUser2;
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync Args.idCpu = NIL_RTCPUID;
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync Args.cHits = 0;
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync RTTHREADPREEMPTSTATE PreemptState = RTTHREADPREEMPTSTATE_INITIALIZER;
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync RTThreadPreemptDisable(&PreemptState);
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync RTSOLCPUSET CpuSet;
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync for (int i = 0; i < IPRT_SOL_SET_WORDS; i++)
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync CpuSet.auCpus[i] = (ulong_t)-1L;
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync
b7a5b3f9f9ecce32ddacf8404c625ce0451bbdc1vboxsync rtMpSolCrossCall(&CpuSet, rtMpSolOnAllCpuWrapper, &Args);
c6958b923ed12aadcf58ebbdbc80aadebbd9493evboxsync
fe813b3594039ba864493438e78ee0e7132bc445vboxsync RTThreadPreemptRestore(&PreemptState);
c6958b923ed12aadcf58ebbdbc80aadebbd9493evboxsync
c6958b923ed12aadcf58ebbdbc80aadebbd9493evboxsync return VINF_SUCCESS;
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync}
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync/**
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync * Wrapper between the native solaris per-cpu callback and PFNRTWORKER
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync * for the RTMpOnOthers API.
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync *
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync * @param uArgs Pointer to the RTMPARGS package.
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync * @param uIgnored1 Ignored.
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync * @param uIgnored2 Ignored.
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync */
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsyncstatic int rtMpSolOnOtherCpusWrapper(void *uArg, void *uIgnored1, void *uIgnored2)
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync{
b7a5b3f9f9ecce32ddacf8404c625ce0451bbdc1vboxsync PRTMPARGS pArgs = (PRTMPARGS)(uArg);
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync RTCPUID idCpu = RTMpCpuId();
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync Assert(idCpu != pArgs->idCpu);
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync pArgs->pfnWorker(idCpu, pArgs->pvUser1, pArgs->pvUser2);
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync NOREF(uIgnored1);
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync NOREF(uIgnored2);
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync return 0;
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync}
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsyncRTDECL(int) RTMpOnOthers(PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2)
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync{
b1cc88518a7578ee20491f3d97b9792c24c6428dvboxsync RTMPARGS Args;
fe813b3594039ba864493438e78ee0e7132bc445vboxsync RT_ASSERT_INTS_ON();
b1cc88518a7578ee20491f3d97b9792c24c6428dvboxsync
b1cc88518a7578ee20491f3d97b9792c24c6428dvboxsync Args.pfnWorker = pfnWorker;
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync Args.pvUser1 = pvUser1;
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync Args.pvUser2 = pvUser2;
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync Args.idCpu = RTMpCpuId();
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync Args.cHits = 0;
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync /* The caller is supposed to have disabled preemption, but take no chances. */
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync RTTHREADPREEMPTSTATE PreemptState = RTTHREADPREEMPTSTATE_INITIALIZER;
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync RTThreadPreemptDisable(&PreemptState);
362838d79d234a41380be42aae9118850cc3c929vboxsync
362838d79d234a41380be42aae9118850cc3c929vboxsync RTSOLCPUSET CpuSet;
362838d79d234a41380be42aae9118850cc3c929vboxsync for (int i = 0; i < IPRT_SOL_SET_WORDS; i++)
362838d79d234a41380be42aae9118850cc3c929vboxsync CpuSet.auCpus[0] = (ulong_t)-1L;
362838d79d234a41380be42aae9118850cc3c929vboxsync BT_CLEAR(CpuSet.auCpus, RTMpCpuId());
bc36547e8dd3d35e5f756643a267bbe01e2c1d4cvboxsync
bc36547e8dd3d35e5f756643a267bbe01e2c1d4cvboxsync rtMpSolCrossCall(&CpuSet, rtMpSolOnOtherCpusWrapper, &Args);
362838d79d234a41380be42aae9118850cc3c929vboxsync
0f1e77149ab5ab40fa2bd74a5330e087416b3c7bvboxsync RTThreadPreemptRestore(&PreemptState);
362838d79d234a41380be42aae9118850cc3c929vboxsync
362838d79d234a41380be42aae9118850cc3c929vboxsync return VINF_SUCCESS;
362838d79d234a41380be42aae9118850cc3c929vboxsync}
362838d79d234a41380be42aae9118850cc3c929vboxsync
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
22bdb1ce26b2d5a41d1b071c16f1078e5348bb0dvboxsync/**
22bdb1ce26b2d5a41d1b071c16f1078e5348bb0dvboxsync * Wrapper between the native solaris per-cpu callback and PFNRTWORKER
22bdb1ce26b2d5a41d1b071c16f1078e5348bb0dvboxsync * for the RTMpOnSpecific API.
22bdb1ce26b2d5a41d1b071c16f1078e5348bb0dvboxsync *
22bdb1ce26b2d5a41d1b071c16f1078e5348bb0dvboxsync * @param uArgs Pointer to the RTMPARGS package.
22bdb1ce26b2d5a41d1b071c16f1078e5348bb0dvboxsync * @param uIgnored1 Ignored.
22bdb1ce26b2d5a41d1b071c16f1078e5348bb0dvboxsync * @param uIgnored2 Ignored.
22bdb1ce26b2d5a41d1b071c16f1078e5348bb0dvboxsync *
0f1e77149ab5ab40fa2bd74a5330e087416b3c7bvboxsync * @returns Solaris error code.
22bdb1ce26b2d5a41d1b071c16f1078e5348bb0dvboxsync */
22bdb1ce26b2d5a41d1b071c16f1078e5348bb0dvboxsyncstatic int rtMpSolOnSpecificCpuWrapper(void *uArg, void *uIgnored1, void *uIgnored2)
22bdb1ce26b2d5a41d1b071c16f1078e5348bb0dvboxsync{
22bdb1ce26b2d5a41d1b071c16f1078e5348bb0dvboxsync PRTMPARGS pArgs = (PRTMPARGS)(uArg);
22bdb1ce26b2d5a41d1b071c16f1078e5348bb0dvboxsync RTCPUID idCpu = RTMpCpuId();
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync Assert(idCpu == pArgs->idCpu);
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync pArgs->pfnWorker(idCpu, pArgs->pvUser1, pArgs->pvUser2);
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync ASMAtomicIncU32(&pArgs->cHits);
ad77e3ec3cde24263bc7537575f5cae442bee3b1vboxsync
cba6719bd64ec749967bbe931230452664109857vboxsync NOREF(uIgnored1);
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync NOREF(uIgnored2);
cba6719bd64ec749967bbe931230452664109857vboxsync return 0;
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync}
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsyncRTDECL(int) RTMpOnSpecific(RTCPUID idCpu, PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2)
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync{
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync RTMPARGS Args;
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync RT_ASSERT_INTS_ON();
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync if (idCpu >= ncpus)
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync return VERR_CPU_NOT_FOUND;
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
0f1e77149ab5ab40fa2bd74a5330e087416b3c7bvboxsync if (RT_UNLIKELY(!RTMpIsCpuOnline(idCpu)))
0f1e77149ab5ab40fa2bd74a5330e087416b3c7bvboxsync return RTMpIsCpuPresent(idCpu) ? VERR_CPU_OFFLINE : VERR_CPU_NOT_FOUND;
0f1e77149ab5ab40fa2bd74a5330e087416b3c7bvboxsync
0f1e77149ab5ab40fa2bd74a5330e087416b3c7bvboxsync Args.pfnWorker = pfnWorker;
0f1e77149ab5ab40fa2bd74a5330e087416b3c7bvboxsync Args.pvUser1 = pvUser1;
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync Args.pvUser2 = pvUser2;
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync Args.idCpu = idCpu;
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync Args.cHits = 0;
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
0f1e77149ab5ab40fa2bd74a5330e087416b3c7bvboxsync RTTHREADPREEMPTSTATE PreemptState = RTTHREADPREEMPTSTATE_INITIALIZER;
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync RTThreadPreemptDisable(&PreemptState);
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync RTSOLCPUSET CpuSet;
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync for (int i = 0; i < IPRT_SOL_SET_WORDS; i++)
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync CpuSet.auCpus[i] = 0;
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync BT_SET(CpuSet.auCpus, idCpu);
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
cba6719bd64ec749967bbe931230452664109857vboxsync rtMpSolCrossCall(&CpuSet, rtMpSolOnSpecificCpuWrapper, &Args);
b7a5b3f9f9ecce32ddacf8404c625ce0451bbdc1vboxsync
30adc6dd25ed9fef4d800a6d9f1ab7e765b4c340vboxsync RTThreadPreemptRestore(&PreemptState);
da3503c04ce76e653401396fe2795a9bc2427a1dvboxsync
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync Assert(ASMAtomicUoReadU32(&Args.cHits) <= 1);
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync
5b1d6bab9f4cf5dacf1883e7c4a40c84349f597fvboxsync return ASMAtomicUoReadU32(&Args.cHits) == 1
ad77e3ec3cde24263bc7537575f5cae442bee3b1vboxsync ? VINF_SUCCESS
801238b286a80a5dd67ba56a1f26c0bc98a2a1eavboxsync : VERR_CPU_NOT_FOUND;
801238b286a80a5dd67ba56a1f26c0bc98a2a1eavboxsync}
801238b286a80a5dd67ba56a1f26c0bc98a2a1eavboxsync
801238b286a80a5dd67ba56a1f26c0bc98a2a1eavboxsync