tandasat/MiniVisorPkg

HandleMsrAccess not being triggered on __writemsr

nicholasdkunes opened this issue · 9 comments

UEFI version, HV seems to be working fine otherwise, other VMExits are triggering. __writemsr isn't. Possibly __readmsr too, haven't checked. Will update with more information as I debug it.

Yep, __readmsr not handling either.

To test, I handle common exception, and put

           LOG_INFO("__readmsr: %d", __readmsr((IA32_MSR_ADDRESS)IA32_GS_BASE));

result is 0, if that helps regardless, at this point, system is in KeInitAmd64SpecificState(). so vmexit is working, as the handle exception was called, because i see that log output. but i don't see this readmsr handled, or any other read/write msr calls handled in the HandleMsrAccess fn.

Nevermind, __readmsr/__writemsr are triggering just fine. I just didn't realize because none of the other MSRs were processing...

This is the code that matters in HandleMsrAccess:

static
VOID
HandleMsrAccess(
    _Inout_ GUEST_CONTEXT* GuestContext,
    _In_ OPERATION_TYPE OperationType
)
{
    IA32_MSR_ADDRESS msr;
    UINT64 value;

    msr = (IA32_MSR_ADDRESS)GuestContext->StackBasedRegisters->Rcx;
    LOG_INFO("[msr] %s >> %02X", (OperationType == OperationRead) ? "__readmsr" : "__writemsr", (unsigned long)msr);

Where the only log that ever is displayed over serial is: [msr] __readmsr >> 8B

Interestingly, that is the IA32_BIOS_UPDATE_SIGNATURE, which is left default from the github code where it sets value = MAXUINT64

No other msr are being written/read, only 8B.

Now, for the most unusual thing, if I call __readmsr like this:
LOG_INFO("__readmsr: %d", __readmsr((IA32_MSR_ADDRESS)IA32_GS_BASE));
I still see:
[msr] __readmsr >> 8B

which is clearly wrong.

Actually calling __readmsr at host level like I did to "test" shouldn't trigger a VM exit because we're already at host level... so ignore that. The issue still stands though, why am I only seeing 8B & no other write/read msrs.

why am I only seeing 8B & no other write/read msrs.

It is because the MSR bitmap is used to specify other MSRs should not cause VM-exit. Search InitializeMsrBitmaps in the code base, and read 24.6.9 MSR-Bitmap Address for more details.

If you wonder "why I do/do not get VM-exit", I suggest looking up 25.1.3 Instructions That Cause VM Exits Conditionally too.

OK, yeah I see it. Thank you Satoshi, you're always extremely helpful.

Love this project so far, I'm using it to get into HV development. It's so well commented it's insane. So I really appreciate that. Thanks!

You are very welcome. I do not provide a dedicated place for Q&A and non-issue discussions for my projects, but feel free to ask questions if you struggle to make sense of things. I publish my projects to help anyone learn.

@tandasat thank you. if I do have questions, where would you like them? As a new, individual issue to help other users in the future, or just one thread?

Regarding VMExits, from my understanding of reading the manual so far for Intel VT-x, there are times when the guest VM must exit the VM because of certain execution, and have the host (MiniVisor) execute that code for them on hardware. Is this the correct way of looking at it?

--edited out question as i solved this on my own--

You are very welcome. I do not provide a dedicated place for Q&A and non-issue discussions for my projects, but feel free to ask questions if you struggle to make sense of things. I publish my projects to help anyone learn.

You are doing very important things. Thank you very much for that!