VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMR0/TRPMR0.cpp@ 45684

Last change on this file since 45684 was 42025, checked in by vboxsync, 12 years ago

A few missed copyright year updates.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 3.5 KB
Line 
1/* $Id: TRPMR0.cpp 42025 2012-07-05 12:52:41Z vboxsync $ */
2/** @file
3 * TRPM - The Trap Monitor - HC Ring 0
4 */
5
6/*
7 * Copyright (C) 2006-2012 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*******************************************************************************
20* Header Files *
21*******************************************************************************/
22#define LOG_GROUP LOG_GROUP_TRPM
23#include <VBox/vmm/trpm.h>
24#include "TRPMInternal.h"
25#include <VBox/vmm/vm.h>
26#include <VBox/vmm/vmm.h>
27#include <VBox/err.h>
28#include <VBox/log.h>
29#include <iprt/assert.h>
30#include <iprt/asm-amd64-x86.h>
31
32
33/**
34 * Dispatches an interrupt that arrived while we were in the guest context.
35 *
36 * @param pVM Pointer to the VM.
37 * @remark Must be called with interrupts disabled.
38 */
39VMMR0DECL(void) TRPMR0DispatchHostInterrupt(PVM pVM)
40{
41 /*
42 * Get the active interrupt vector number.
43 */
44 PVMCPU pVCpu = VMMGetCpu0(pVM);
45 RTUINT uActiveVector = pVCpu->trpm.s.uActiveVector;
46 pVCpu->trpm.s.uActiveVector = UINT32_MAX;
47 AssertMsgReturnVoid(uActiveVector < 256, ("uActiveVector=%#x is invalid! (More assertions to come, please enjoy!)\n", uActiveVector));
48
49#if HC_ARCH_BITS == 64 && defined(RT_OS_DARWIN)
50 /*
51 * Do it the simple and safe way.
52 *
53 * This is a workaround for an optimization bug in the code below
54 * or a gcc 4.2 on mac (snow leopard seed 314).
55 */
56 trpmR0DispatchHostInterruptSimple(uActiveVector);
57
58#else /* The complicated way: */
59
60# ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
61 /*
62 * Check if we're in long mode or not.
63 */
64 if ( (ASMCpuId_EDX(0x80000001) & X86_CPUID_EXT_FEATURE_EDX_LONG_MODE)
65 && (ASMRdMsr(MSR_K6_EFER) & MSR_K6_EFER_LMA))
66 {
67 trpmR0DispatchHostInterruptSimple(uActiveVector);
68 return;
69 }
70# endif
71
72 /*
73 * Get the handler pointer (16:32 ptr) / (16:48 ptr).
74 */
75 RTIDTR Idtr;
76 ASMGetIDTR(&Idtr);
77# if HC_ARCH_BITS == 32
78 PVBOXIDTE pIdte = &((PVBOXIDTE)Idtr.pIdt)[uActiveVector];
79# else
80 PVBOXIDTE64 pIdte = &((PVBOXIDTE64)Idtr.pIdt)[uActiveVector];
81# endif
82 AssertMsgReturnVoid(pIdte->Gen.u1Present, ("The IDT entry (%d) is not present!\n", uActiveVector));
83 AssertMsgReturnVoid( pIdte->Gen.u3Type1 == VBOX_IDTE_TYPE1
84 || pIdte->Gen.u5Type2 == VBOX_IDTE_TYPE2_INT_32,
85 ("The IDT entry (%d) is not 32-bit int gate! type1=%#x type2=%#x\n",
86 uActiveVector, pIdte->Gen.u3Type1, pIdte->Gen.u5Type2));
87# if HC_ARCH_BITS == 32
88 RTFAR32 pfnHandler;
89 pfnHandler.off = VBOXIDTE_OFFSET(*pIdte);
90 pfnHandler.sel = pIdte->Gen.u16SegSel;
91
92 const RTR0UINTREG uRSP = ~(RTR0UINTREG)0;
93
94# else /* 64-bit: */
95 RTFAR64 pfnHandler;
96 pfnHandler.off = VBOXIDTE64_OFFSET(*pIdte);
97 pfnHandler.sel = pIdte->Gen.u16SegSel;
98
99 const RTR0UINTREG uRSP = ~(RTR0UINTREG)0;
100 if (pIdte->Gen.u3Ist)
101 {
102 trpmR0DispatchHostInterruptSimple(uActiveVector);
103 return;
104 }
105
106# endif
107
108 /*
109 * Dispatch it.
110 */
111 trpmR0DispatchHostInterrupt(pfnHandler.off, pfnHandler.sel, uRSP);
112#endif
113}
114
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette