summaryrefslogtreecommitdiff
path: root/src/VBox/Runtime
diff options
context:
space:
mode:
authorFelix Geyer <debfx-pkg@fobos.de>2009-10-31 16:12:02 +0100
committerFelix Geyer <debfx-pkg@fobos.de>2009-10-31 16:12:02 +0100
commit44ee97ac270d79c70093cbdc4ad6d9d55eb0c679 (patch)
treeb95ded19c2dcda0059376ad5770e78e84739b6c4 /src/VBox/Runtime
parent59cffb992a3c457677eec2b1e4dd1f9fdb8b38f9 (diff)
downloadvirtualbox-44ee97ac270d79c70093cbdc4ad6d9d55eb0c679.tar.gz
Imported Upstream version 3.0.10-dfsgupstream/3.0.10-dfsg
Diffstat (limited to 'src/VBox/Runtime')
-rw-r--r--src/VBox/Runtime/include/internal/mp.h50
-rw-r--r--src/VBox/Runtime/r0drv/linux/the-linux-kernel.h1
-rw-r--r--src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp39
-rw-r--r--src/VBox/Runtime/r0drv/nt/internal-r0drv-nt.h13
-rw-r--r--src/VBox/Runtime/r0drv/nt/mp-r0drv-nt.cpp46
-rw-r--r--src/VBox/Runtime/r0drv/nt/thread-r0drv-nt.cpp6
-rw-r--r--src/VBox/Runtime/r3/fs.cpp3
7 files changed, 89 insertions, 69 deletions
diff --git a/src/VBox/Runtime/include/internal/mp.h b/src/VBox/Runtime/include/internal/mp.h
deleted file mode 100644
index 8b74e4ffc..000000000
--- a/src/VBox/Runtime/include/internal/mp.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* $Id: mp.h $ */
-/** @file
- * IPRT - MP Internal header.
- */
-
-/*
- * Copyright (C) 2006-2007 Sun Microsystems, Inc.
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- *
- * The contents of this file may alternatively be used under the terms
- * of the Common Development and Distribution License Version 1.0
- * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
- * VirtualBox OSE distribution, in which case the provisions of the
- * CDDL are applicable instead of those of the GPL.
- *
- * You may elect to license modified versions of this file under the
- * terms and conditions of either the GPL or the CDDL or both.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
- * Clara, CA 95054 USA or visit http://www.sun.com if you need
- * additional information or have any questions.
- */
-
-#ifndef ___internal_mp_h
-#define ___internal_mp_h
-
-#include <iprt/cdefs.h>
-#include <iprt/param.h>
-
-RT_C_DECLS_BEGIN
-
-/**
- * Clears any pending poke DPC
- *
- * Currently only valid for Windows hosts.
- *
- */
-void rtMpPokeCpuClear();
-
-RT_C_DECLS_END
-
-#endif
-
diff --git a/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h b/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h
index 8d15808b4..9759a4089 100644
--- a/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h
+++ b/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h
@@ -81,6 +81,7 @@
#include <linux/pagemap.h>
#include <linux/slab.h>
#include <linux/time.h>
+#include <linux/sched.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 7)
# include <linux/jiffies.h>
#endif
diff --git a/src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp
index b870cb0c7..1615ac7ab 100644
--- a/src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp
@@ -56,6 +56,14 @@ RTCPUSET g_rtMpNtCpuSet;
PFNMYEXSETTIMERRESOLUTION g_pfnrtNtExSetTimerResolution;
/** KeFlushQueuedDpcs, introduced in XP. */
PFNMYKEFLUSHQUEUEDDPCS g_pfnrtNtKeFlushQueuedDpcs;
+/** HalRequestIpi, introduced in ??. */
+PFNHALREQUESTIPI g_pfnrtNtHalRequestIpi;
+/** HalSendSoftwareInterrupt */
+PFNHALSENDSOFTWAREINTERRUPT g_pfnrtNtHalSendSoftwareInterrupt;
+/** SendIpi handler based on Windows version */
+PFNRTSENDIPI g_pfnrtSendIpi;
+/** KeIpiGenericCall - Windows Server 2003+ only */
+PFNRTKEIPIGENERICCALL g_pfnrtKeIpiGenericCall;
/** Offset of the _KPRCB::QuantumEnd field. 0 if not found. */
uint32_t g_offrtNtPbQuantumEnd;
@@ -82,6 +90,9 @@ int rtR0InitNative(void)
#ifdef IPRT_TARGET_NT4
g_pfnrtNtExSetTimerResolution = NULL;
g_pfnrtNtKeFlushQueuedDpcs = NULL;
+ g_pfnrtNtHalRequestIpi = NULL;
+ g_pfnrtNtHalSendSoftwareInterrupt = NULL;
+ g_pfnrtKeIpiGenericCall = NULL;
#else
/*
* Initialize the function pointers.
@@ -92,6 +103,15 @@ int rtR0InitNative(void)
RtlInitUnicodeString(&RoutineName, L"KeFlushQueuedDpcs");
g_pfnrtNtKeFlushQueuedDpcs = (PFNMYKEFLUSHQUEUEDDPCS)MmGetSystemRoutineAddress(&RoutineName);
+
+ RtlInitUnicodeString(&RoutineName, L"HalRequestIpi");
+ g_pfnrtNtHalRequestIpi = (PFNHALREQUESTIPI)MmGetSystemRoutineAddress(&RoutineName);
+
+ RtlInitUnicodeString(&RoutineName, L"HalSendSoftwareInterrupt");
+ g_pfnrtNtHalSendSoftwareInterrupt = (PFNHALSENDSOFTWAREINTERRUPT)MmGetSystemRoutineAddress(&RoutineName);
+
+ RtlInitUnicodeString(&RoutineName, L"KeIpiGenericCall");
+ g_pfnrtKeIpiGenericCall = (PFNRTKEIPIGENERICCALL)MmGetSystemRoutineAddress(&RoutineName);
#endif
/*
@@ -102,6 +122,25 @@ int rtR0InitNative(void)
ULONG BuildNumber = 0;
BOOLEAN fChecked = PsGetVersion(&MajorVersion, &MinorVersion, &BuildNumber, NULL);
+ g_pfnrtSendIpi = rtMpSendIpiDummy;
+#ifndef IPRT_TARGET_NT4
+ if ( g_pfnrtNtHalRequestIpi
+ && MajorVersion == 6
+ && MinorVersion == 0)
+ {
+ /* Vista or Windows Server 2008 */
+ g_pfnrtSendIpi = rtMpSendIpiVista;
+ }
+ else
+ if ( g_pfnrtNtHalSendSoftwareInterrupt
+ && MajorVersion == 6
+ && MinorVersion == 1)
+ {
+ /* Windows 7 or Windows Server 2008 R2 */
+ g_pfnrtSendIpi = rtMpSendIpiWin7;
+ }
+ /* Windows XP should send always send an IPI -> VERIFY */
+#endif
KIRQL OldIrql;
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); /* make sure we stay on the same cpu */
diff --git a/src/VBox/Runtime/r0drv/nt/internal-r0drv-nt.h b/src/VBox/Runtime/r0drv/nt/internal-r0drv-nt.h
index 38733cbbf..4d4680fe7 100644
--- a/src/VBox/Runtime/r0drv/nt/internal-r0drv-nt.h
+++ b/src/VBox/Runtime/r0drv/nt/internal-r0drv-nt.h
@@ -40,7 +40,10 @@ RT_C_DECLS_BEGIN
*******************************************************************************/
typedef ULONG (__stdcall *PFNMYEXSETTIMERRESOLUTION)(ULONG, BOOLEAN);
typedef VOID (__stdcall *PFNMYKEFLUSHQUEUEDDPCS)(VOID);
-
+typedef VOID (__stdcall *PFNHALREQUESTIPI)(KAFFINITY TargetSet);
+typedef VOID (__stdcall *PFNHALSENDSOFTWAREINTERRUPT)(ULONG ProcessorNumber, KIRQL Irql);
+typedef int (__stdcall *PFNRTSENDIPI)(RTCPUID idCpu);
+typedef ULONG_PTR (__stdcall *PFNRTKEIPIGENERICCALL)(PKIPI_BROADCAST_WORKER BroadcastFunction, ULONG_PTR Context);
/*******************************************************************************
* Global Variables *
@@ -48,11 +51,19 @@ typedef VOID (__stdcall *PFNMYKEFLUSHQUEUEDDPCS)(VOID);
extern RTCPUSET g_rtMpNtCpuSet;
extern PFNMYEXSETTIMERRESOLUTION g_pfnrtNtExSetTimerResolution;
extern PFNMYKEFLUSHQUEUEDDPCS g_pfnrtNtKeFlushQueuedDpcs;
+extern PFNHALREQUESTIPI g_pfnrtNtHalRequestIpi;
+extern PFNHALSENDSOFTWAREINTERRUPT g_pfnrtNtHalSendSoftwareInterrupt;
+extern PFNRTSENDIPI g_pfnrtSendIpi;
+extern PFNRTKEIPIGENERICCALL g_pfnrtKeIpiGenericCall;
extern uint32_t g_offrtNtPbQuantumEnd;
extern uint32_t g_cbrtNtPbQuantumEnd;
extern uint32_t g_offrtNtPbDpcQueueDepth;
+int rtMpSendIpiVista(RTCPUID idCpu);
+int rtMpSendIpiWin7(RTCPUID idCpu);
+int rtMpSendIpiDummy(RTCPUID idCpu);
+
RT_C_DECLS_END
#endif
diff --git a/src/VBox/Runtime/r0drv/nt/mp-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/mp-r0drv-nt.cpp
index d05b4c7a7..15fa72d45 100644
--- a/src/VBox/Runtime/r0drv/nt/mp-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/mp-r0drv-nt.cpp
@@ -40,7 +40,6 @@
#include <iprt/asm.h>
#include "r0drv/mp-r0drv.h"
#include "internal-r0drv-nt.h"
-#include "internal/mp.h"
/*******************************************************************************
@@ -347,6 +346,32 @@ static VOID rtMpNtPokeCpuDummy(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID
NOREF(SystemArgument2);
}
+#ifndef IPRT_TARGET_NT4
+
+ULONG_PTR rtMpIpiGenericCall(ULONG_PTR Argument)
+{
+ return 0;
+}
+
+int rtMpSendIpiVista(RTCPUID idCpu)
+{
+ g_pfnrtKeIpiGenericCall(rtMpIpiGenericCall, 0);
+//// g_pfnrtNtHalRequestIpi(1 << idCpu);
+ return VINF_SUCCESS;
+}
+
+int rtMpSendIpiWin7(RTCPUID idCpu)
+{
+ g_pfnrtKeIpiGenericCall(rtMpIpiGenericCall, 0);
+//// g_pfnrtNtHalSendSoftwareInterrupt(idCpu, DISPATCH_LEVEL);
+ return VINF_SUCCESS;
+}
+#endif /* IPRT_TARGET_NT4 */
+
+int rtMpSendIpiDummy(RTCPUID idCpu)
+{
+ return VERR_NOT_IMPLEMENTED;
+}
RTDECL(int) RTMpPokeCpu(RTCPUID idCpu)
{
@@ -355,6 +380,11 @@ RTDECL(int) RTMpPokeCpu(RTCPUID idCpu)
? VERR_CPU_NOT_FOUND
: VERR_CPU_OFFLINE;
+ int rc = g_pfnrtSendIpi(idCpu);
+ if (rc == VINF_SUCCESS)
+ return rc;
+
+ /* Fallback. */
if (!fPokeDPCsInitialized)
{
for (unsigned i = 0; i < RT_ELEMENTS(aPokeDpcs); i++)
@@ -372,20 +402,14 @@ RTDECL(int) RTMpPokeCpu(RTCPUID idCpu)
KIRQL oldIrql;
KeRaiseIrql(DISPATCH_LEVEL, &oldIrql);
+ KeSetImportanceDpc(&aPokeDpcs[idCpu], HighImportance);
+ KeSetTargetProcessorDpc(&aPokeDpcs[idCpu], (int)idCpu);
+
/* Assuming here that high importance DPCs will be delivered immediately; or at least an IPI will be sent immediately.
- * Todo: verify!
+ * @note: not true on at least Vista & Windows 7
*/
BOOLEAN bRet = KeInsertQueueDpc(&aPokeDpcs[idCpu], 0, 0);
KeLowerIrql(oldIrql);
return (bRet == TRUE) ? VINF_SUCCESS : VERR_ACCESS_DENIED /* already queued */;
}
-
-void rtMpPokeCpuClear()
-{
- RTCPUID idCpu = RTMpCpuId();
-
- /* Remove any pending poke DPC from the queue, so another call to RTMpPokeCpu will send an IPI */
- /* Note: assuming this is a cheap operation. */
- KeRemoveQueueDpc(&aPokeDpcs[idCpu]);
-}
diff --git a/src/VBox/Runtime/r0drv/nt/thread-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/thread-r0drv-nt.cpp
index 6f884a81b..52e16cc65 100644
--- a/src/VBox/Runtime/r0drv/nt/thread-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/thread-r0drv-nt.cpp
@@ -37,7 +37,6 @@
#include <iprt/err.h>
#include <iprt/assert.h>
#include <iprt/asm.h>
-#include "internal/mp.h"
#include "internal-r0drv-nt.h"
@@ -94,11 +93,6 @@ RTDECL(bool) RTThreadPreemptIsPending(RTTHREAD hThread)
{
Assert(hThread == NIL_RTTHREAD);
- /* Remove any pending poke DPC from the queue, so another call to RTMpPokeCpu will send an IPI
- * Also do this so we don't exit from ring 0 for the poke DPC (which does nothing).
- */
- rtMpPokeCpuClear();
-
/*
* Read the globals and check if they are useful.
*/
diff --git a/src/VBox/Runtime/r3/fs.cpp b/src/VBox/Runtime/r3/fs.cpp
index 74a9d64f1..b22b6fe99 100644
--- a/src/VBox/Runtime/r3/fs.cpp
+++ b/src/VBox/Runtime/r3/fs.cpp
@@ -35,6 +35,7 @@
#ifndef RT_OS_WINDOWS
# define RTTIME_INCL_TIMESPEC
# include <sys/time.h>
+# include <sys/param.h>
#endif
#include <iprt/fs.h>
@@ -195,7 +196,7 @@ bool rtFsModeIsValidPermissions(RTFMODE fMode)
void rtFsConvertStatToObjInfo(PRTFSOBJINFO pObjInfo, const struct stat *pStat, const char *pszName, unsigned cbName)
{
pObjInfo->cbObject = pStat->st_size;
- pObjInfo->cbAllocated = pStat->st_size;
+ pObjInfo->cbAllocated = pStat->st_blocks * DEV_BSIZE;
#ifdef HAVE_STAT_NSEC
RTTimeSpecAddNano(RTTimeSpecSetSeconds(&pObjInfo->AccessTime, pStat->st_atime), pStat->st_atimensec);