236b2935f217749893b7034e59da3e3568928acevboxsync/* $Id$ */
236b2935f217749893b7034e59da3e3568928acevboxsync/** @file
236b2935f217749893b7034e59da3e3568928acevboxsync * GIM - Guest Interface Manager - All Contexts.
236b2935f217749893b7034e59da3e3568928acevboxsync */
236b2935f217749893b7034e59da3e3568928acevboxsync
236b2935f217749893b7034e59da3e3568928acevboxsync/*
f84ab9e4599e758ec1f36479f871b3f5b7f271f2vboxsync * Copyright (C) 2014-2015 Oracle Corporation
236b2935f217749893b7034e59da3e3568928acevboxsync *
236b2935f217749893b7034e59da3e3568928acevboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
236b2935f217749893b7034e59da3e3568928acevboxsync * available from http://www.virtualbox.org. This file is free software;
236b2935f217749893b7034e59da3e3568928acevboxsync * you can redistribute it and/or modify it under the terms of the GNU
236b2935f217749893b7034e59da3e3568928acevboxsync * General Public License (GPL) as published by the Free Software
236b2935f217749893b7034e59da3e3568928acevboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
236b2935f217749893b7034e59da3e3568928acevboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
236b2935f217749893b7034e59da3e3568928acevboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
236b2935f217749893b7034e59da3e3568928acevboxsync */
236b2935f217749893b7034e59da3e3568928acevboxsync
236b2935f217749893b7034e59da3e3568928acevboxsync
236b2935f217749893b7034e59da3e3568928acevboxsync/*******************************************************************************
236b2935f217749893b7034e59da3e3568928acevboxsync* Header Files *
236b2935f217749893b7034e59da3e3568928acevboxsync*******************************************************************************/
236b2935f217749893b7034e59da3e3568928acevboxsync#define LOG_GROUP LOG_GROUP_GIM
236b2935f217749893b7034e59da3e3568928acevboxsync#include "GIMInternal.h"
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync#include <VBox/err.h>
236b2935f217749893b7034e59da3e3568928acevboxsync#include <VBox/vmm/vm.h>
236b2935f217749893b7034e59da3e3568928acevboxsync
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync/* Include all the providers. */
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync#include "GIMHvInternal.h"
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync#include "GIMMinimalInternal.h"
236b2935f217749893b7034e59da3e3568928acevboxsync
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync/**
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync * Checks whether GIM is being used by this VM.
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync *
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync * @retval @c true if used.
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync * @retval @c false if no GIM provider ("none") is used.
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync *
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync * @param pVM Pointer to the VM.
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync */
236b2935f217749893b7034e59da3e3568928acevboxsyncVMMDECL(bool) GIMIsEnabled(PVM pVM)
236b2935f217749893b7034e59da3e3568928acevboxsync{
4ae0ac3d0dc641305a0b0197db43ee7c4b40f747vboxsync return pVM->gim.s.enmProviderId != GIMPROVIDERID_NONE;
236b2935f217749893b7034e59da3e3568928acevboxsync}
236b2935f217749893b7034e59da3e3568928acevboxsync
236b2935f217749893b7034e59da3e3568928acevboxsync
2ac3892cdc8b16a0dee55e8b4510b8ecea83c95fvboxsync/**
2ac3892cdc8b16a0dee55e8b4510b8ecea83c95fvboxsync * Gets the GIM provider configured for this VM.
2ac3892cdc8b16a0dee55e8b4510b8ecea83c95fvboxsync *
2ac3892cdc8b16a0dee55e8b4510b8ecea83c95fvboxsync * @returns The GIM provider Id.
2ac3892cdc8b16a0dee55e8b4510b8ecea83c95fvboxsync * @param pVM Pointer to the VM.
2ac3892cdc8b16a0dee55e8b4510b8ecea83c95fvboxsync */
2ac3892cdc8b16a0dee55e8b4510b8ecea83c95fvboxsyncVMMDECL(GIMPROVIDERID) GIMGetProvider(PVM pVM)
2ac3892cdc8b16a0dee55e8b4510b8ecea83c95fvboxsync{
2ac3892cdc8b16a0dee55e8b4510b8ecea83c95fvboxsync return pVM->gim.s.enmProviderId;
2ac3892cdc8b16a0dee55e8b4510b8ecea83c95fvboxsync}
2ac3892cdc8b16a0dee55e8b4510b8ecea83c95fvboxsync
2ac3892cdc8b16a0dee55e8b4510b8ecea83c95fvboxsync
ce9f428fc2f581b4d8968d870967e259d9924d8dvboxsync/**
ce9f428fc2f581b4d8968d870967e259d9924d8dvboxsync * Returns whether the guest has configured and enabled calls to the hypervisor.
ce9f428fc2f581b4d8968d870967e259d9924d8dvboxsync *
ce9f428fc2f581b4d8968d870967e259d9924d8dvboxsync * @returns true if hypercalls are enabled and usable, false otherwise.
ce9f428fc2f581b4d8968d870967e259d9924d8dvboxsync * @param pVCpu Pointer to the VMCPU.
ce9f428fc2f581b4d8968d870967e259d9924d8dvboxsync */
ce9f428fc2f581b4d8968d870967e259d9924d8dvboxsyncVMM_INT_DECL(bool) GIMAreHypercallsEnabled(PVMCPU pVCpu)
ce9f428fc2f581b4d8968d870967e259d9924d8dvboxsync{
ce9f428fc2f581b4d8968d870967e259d9924d8dvboxsync PVM pVM = pVCpu->CTX_SUFF(pVM);
ce9f428fc2f581b4d8968d870967e259d9924d8dvboxsync if (!GIMIsEnabled(pVM))
ce9f428fc2f581b4d8968d870967e259d9924d8dvboxsync return false;
ce9f428fc2f581b4d8968d870967e259d9924d8dvboxsync
ce9f428fc2f581b4d8968d870967e259d9924d8dvboxsync switch (pVM->gim.s.enmProviderId)
ce9f428fc2f581b4d8968d870967e259d9924d8dvboxsync {
ce9f428fc2f581b4d8968d870967e259d9924d8dvboxsync case GIMPROVIDERID_HYPERV:
f84ab9e4599e758ec1f36479f871b3f5b7f271f2vboxsync return gimHvAreHypercallsEnabled(pVCpu);
ce9f428fc2f581b4d8968d870967e259d9924d8dvboxsync
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync case GIMPROVIDERID_KVM:
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync return gimKvmAreHypercallsEnabled(pVCpu);
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync
ce9f428fc2f581b4d8968d870967e259d9924d8dvboxsync default:
ce9f428fc2f581b4d8968d870967e259d9924d8dvboxsync return false;
ce9f428fc2f581b4d8968d870967e259d9924d8dvboxsync }
ce9f428fc2f581b4d8968d870967e259d9924d8dvboxsync}
ce9f428fc2f581b4d8968d870967e259d9924d8dvboxsync
ce9f428fc2f581b4d8968d870967e259d9924d8dvboxsync
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync/**
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync * Implements a GIM hypercall with the provider configured for the VM.
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync *
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync * @returns VBox status code.
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync * @param pVCpu Pointer to the VMCPU.
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync * @param pCtx Pointer to the guest-CPU context.
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync */
236b2935f217749893b7034e59da3e3568928acevboxsyncVMM_INT_DECL(int) GIMHypercall(PVMCPU pVCpu, PCPUMCTX pCtx)
236b2935f217749893b7034e59da3e3568928acevboxsync{
236b2935f217749893b7034e59da3e3568928acevboxsync PVM pVM = pVCpu->CTX_SUFF(pVM);
236b2935f217749893b7034e59da3e3568928acevboxsync VMCPU_ASSERT_EMT(pVCpu);
236b2935f217749893b7034e59da3e3568928acevboxsync
ce9f428fc2f581b4d8968d870967e259d9924d8dvboxsync if (RT_UNLIKELY(!GIMIsEnabled(pVM)))
ce9f428fc2f581b4d8968d870967e259d9924d8dvboxsync return VERR_GIM_NOT_ENABLED;
ce9f428fc2f581b4d8968d870967e259d9924d8dvboxsync
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync switch (pVM->gim.s.enmProviderId)
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync {
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync case GIMPROVIDERID_HYPERV:
f84ab9e4599e758ec1f36479f871b3f5b7f271f2vboxsync return gimHvHypercall(pVCpu, pCtx);
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync case GIMPROVIDERID_KVM:
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync return gimKvmHypercall(pVCpu, pCtx);
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync default:
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync AssertMsgFailed(("GIMHypercall: for provider %u not available/implemented\n", pVM->gim.s.enmProviderId));
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync return VERR_GIM_HYPERCALLS_NOT_AVAILABLE;
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync }
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync}
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync
ce9f428fc2f581b4d8968d870967e259d9924d8dvboxsync
ce9f428fc2f581b4d8968d870967e259d9924d8dvboxsync/**
ce9f428fc2f581b4d8968d870967e259d9924d8dvboxsync * Returns whether the guest has configured and setup the use of paravirtualized
6d0dfca130b3267e60e6dcb6f8cea0487534680avboxsync * TSC.
6d0dfca130b3267e60e6dcb6f8cea0487534680avboxsync *
6d0dfca130b3267e60e6dcb6f8cea0487534680avboxsync * Paravirtualized TSCs are per-VM and the rest of the execution engine logic
6d0dfca130b3267e60e6dcb6f8cea0487534680avboxsync * relies on that.
ce9f428fc2f581b4d8968d870967e259d9924d8dvboxsync *
ce9f428fc2f581b4d8968d870967e259d9924d8dvboxsync * @returns true if enabled and usable, false otherwise.
ce9f428fc2f581b4d8968d870967e259d9924d8dvboxsync * @param pVM Pointer to the VM.
ce9f428fc2f581b4d8968d870967e259d9924d8dvboxsync */
ce9f428fc2f581b4d8968d870967e259d9924d8dvboxsyncVMM_INT_DECL(bool) GIMIsParavirtTscEnabled(PVM pVM)
eca46116c06b850c8c6be84678ba1f9dbdb3f9ddvboxsync{
eca46116c06b850c8c6be84678ba1f9dbdb3f9ddvboxsync switch (pVM->gim.s.enmProviderId)
eca46116c06b850c8c6be84678ba1f9dbdb3f9ddvboxsync {
eca46116c06b850c8c6be84678ba1f9dbdb3f9ddvboxsync case GIMPROVIDERID_HYPERV:
f84ab9e4599e758ec1f36479f871b3f5b7f271f2vboxsync return gimHvIsParavirtTscEnabled(pVM);
eca46116c06b850c8c6be84678ba1f9dbdb3f9ddvboxsync
fa35e2dfd910e18dbb7f136bfe56030e5116d51cvboxsync case GIMPROVIDERID_KVM:
fa35e2dfd910e18dbb7f136bfe56030e5116d51cvboxsync return gimKvmIsParavirtTscEnabled(pVM);
fa35e2dfd910e18dbb7f136bfe56030e5116d51cvboxsync
eca46116c06b850c8c6be84678ba1f9dbdb3f9ddvboxsync default:
eca46116c06b850c8c6be84678ba1f9dbdb3f9ddvboxsync break;
eca46116c06b850c8c6be84678ba1f9dbdb3f9ddvboxsync }
eca46116c06b850c8c6be84678ba1f9dbdb3f9ddvboxsync return false;
eca46116c06b850c8c6be84678ba1f9dbdb3f9ddvboxsync}
eca46116c06b850c8c6be84678ba1f9dbdb3f9ddvboxsync
eca46116c06b850c8c6be84678ba1f9dbdb3f9ddvboxsync
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync/**
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync * Whether #UD exceptions in the guest needs to be intercepted by the GIM
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync * provider.
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync *
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync * At the moment, the reason why this isn't a more generic interface wrt to
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync * exceptions is because of performance (each VM-exit would have to manually
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync * check whether or not GIM needs to be notified). Left as a todo for later if
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync * really required.
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync *
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync * @returns true if needed, false otherwise.
66d96ba0c4c722996a3a1e6d92403a14a27db1b4vboxsync * @param pVCpu Pointer to the VMCPU.
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync */
66d96ba0c4c722996a3a1e6d92403a14a27db1b4vboxsyncVMM_INT_DECL(bool) GIMShouldTrapXcptUD(PVMCPU pVCpu)
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync{
66d96ba0c4c722996a3a1e6d92403a14a27db1b4vboxsync PVM pVM = pVCpu->CTX_SUFF(pVM);
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync if (!GIMIsEnabled(pVM))
fa35e2dfd910e18dbb7f136bfe56030e5116d51cvboxsync return false;
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync switch (pVM->gim.s.enmProviderId)
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync {
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync case GIMPROVIDERID_KVM:
66d96ba0c4c722996a3a1e6d92403a14a27db1b4vboxsync return gimKvmShouldTrapXcptUD(pVCpu);
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync default:
fa35e2dfd910e18dbb7f136bfe56030e5116d51cvboxsync return false;
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync }
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync}
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync/**
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync * Exception handler for #UD when requested by the GIM provider.
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync *
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync * @param pVCpu Pointer to the VMCPU.
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync * @param pCtx Pointer to the guest-CPU context.
fa35e2dfd910e18dbb7f136bfe56030e5116d51cvboxsync * @param pDis Pointer to the disassembled instruction state at RIP.
fa35e2dfd910e18dbb7f136bfe56030e5116d51cvboxsync * Optional, can be NULL.
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync */
fa35e2dfd910e18dbb7f136bfe56030e5116d51cvboxsyncVMM_INT_DECL(int) GIMXcptUD(PVMCPU pVCpu, PCPUMCTX pCtx, PDISCPUSTATE pDis)
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync{
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync PVM pVM = pVCpu->CTX_SUFF(pVM);
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync Assert(GIMIsEnabled(pVM));
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync switch (pVM->gim.s.enmProviderId)
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync {
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync case GIMPROVIDERID_KVM:
fa35e2dfd910e18dbb7f136bfe56030e5116d51cvboxsync return gimKvmXcptUD(pVCpu, pCtx, pDis);
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync default:
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync return VERR_GIM_OPERATION_FAILED;
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync }
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync}
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync
9c178a84047ec38c02debb747cbdc7de4531d940vboxsync
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync/**
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync * Invokes the read-MSR handler for the GIM provider configured for the VM.
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync *
ad4f6ac2063d9b48efd9c3193442136a8c7c890avboxsync * @returns Strict VBox status code like CPUMQueryGuestMsr.
ad4f6ac2063d9b48efd9c3193442136a8c7c890avboxsync * @retval VINF_CPUM_R3_MSR_READ
ad4f6ac2063d9b48efd9c3193442136a8c7c890avboxsync * @retval VERR_CPUM_RAISE_GP_0
ad4f6ac2063d9b48efd9c3193442136a8c7c890avboxsync *
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync * @param pVCpu Pointer to the VMCPU.
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync * @param idMsr The MSR to read.
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync * @param pRange The range this MSR belongs to.
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync * @param puValue Where to store the MSR value read.
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync */
ad4f6ac2063d9b48efd9c3193442136a8c7c890avboxsyncVMM_INT_DECL(VBOXSTRICTRC) GIMReadMsr(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t *puValue)
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync{
bc5cd42756b3f98351040bbfccc08dd9bacd103avboxsync Assert(pVCpu);
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync PVM pVM = pVCpu->CTX_SUFF(pVM);
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync Assert(GIMIsEnabled(pVM));
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync VMCPU_ASSERT_EMT(pVCpu);
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync switch (pVM->gim.s.enmProviderId)
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync {
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync case GIMPROVIDERID_HYPERV:
f84ab9e4599e758ec1f36479f871b3f5b7f271f2vboxsync return gimHvReadMsr(pVCpu, idMsr, pRange, puValue);
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync
0bc35f54322c5f9b2d43b064f839a8cf8c99a234vboxsync case GIMPROVIDERID_KVM:
0bc35f54322c5f9b2d43b064f839a8cf8c99a234vboxsync return gimKvmReadMsr(pVCpu, idMsr, pRange, puValue);
0bc35f54322c5f9b2d43b064f839a8cf8c99a234vboxsync
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync default:
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync AssertMsgFailed(("GIMReadMsr: for unknown provider %u idMsr=%#RX32 -> #GP(0)", pVM->gim.s.enmProviderId, idMsr));
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync return VERR_CPUM_RAISE_GP_0;
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync }
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync}
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync/**
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync * Invokes the write-MSR handler for the GIM provider configured for the VM.
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync *
ad4f6ac2063d9b48efd9c3193442136a8c7c890avboxsync * @returns Strict VBox status code like CPUMSetGuestMsr.
ad4f6ac2063d9b48efd9c3193442136a8c7c890avboxsync * @retval VINF_CPUM_R3_MSR_WRITE
ad4f6ac2063d9b48efd9c3193442136a8c7c890avboxsync * @retval VERR_CPUM_RAISE_GP_0
ad4f6ac2063d9b48efd9c3193442136a8c7c890avboxsync *
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync * @param pVCpu Pointer to the VMCPU.
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync * @param idMsr The MSR to write.
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync * @param pRange The range this MSR belongs to.
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync * @param uValue The value to set, ignored bits masked.
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync * @param uRawValue The raw value with the ignored bits not masked.
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync */
ad4f6ac2063d9b48efd9c3193442136a8c7c890avboxsyncVMM_INT_DECL(VBOXSTRICTRC) GIMWriteMsr(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t uValue, uint64_t uRawValue)
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync{
eca46116c06b850c8c6be84678ba1f9dbdb3f9ddvboxsync AssertPtr(pVCpu);
eca46116c06b850c8c6be84678ba1f9dbdb3f9ddvboxsync NOREF(uValue);
eca46116c06b850c8c6be84678ba1f9dbdb3f9ddvboxsync
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync PVM pVM = pVCpu->CTX_SUFF(pVM);
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync Assert(GIMIsEnabled(pVM));
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync VMCPU_ASSERT_EMT(pVCpu);
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync switch (pVM->gim.s.enmProviderId)
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync {
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync case GIMPROVIDERID_HYPERV:
f84ab9e4599e758ec1f36479f871b3f5b7f271f2vboxsync return gimHvWriteMsr(pVCpu, idMsr, pRange, uRawValue);
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync
0bc35f54322c5f9b2d43b064f839a8cf8c99a234vboxsync case GIMPROVIDERID_KVM:
0bc35f54322c5f9b2d43b064f839a8cf8c99a234vboxsync return gimKvmWriteMsr(pVCpu, idMsr, pRange, uRawValue);
0bc35f54322c5f9b2d43b064f839a8cf8c99a234vboxsync
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync default:
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync AssertMsgFailed(("GIMWriteMsr: for unknown provider %u idMsr=%#RX32 -> #GP(0)", pVM->gim.s.enmProviderId, idMsr));
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync return VERR_CPUM_RAISE_GP_0;
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync }
236b2935f217749893b7034e59da3e3568928acevboxsync}
236b2935f217749893b7034e59da3e3568928acevboxsync