mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-20 09:46:20 +00:00
vbox6: avoid unintended state transfer on hw enter
intr_state and actv_state are now charged only if required and with valid values. Issue #4313
This commit is contained in:
parent
74a8a801e4
commit
8d5903cba9
@ -123,7 +123,6 @@ class Sup::Vcpu_impl : public Sup::Vcpu, Genode::Noncopyable
|
||||
};
|
||||
|
||||
struct {
|
||||
unsigned intr_state = 0;
|
||||
unsigned ctrl_primary = VIRT::ctrl_primary();
|
||||
unsigned ctrl_secondary = VIRT::ctrl_secondary();
|
||||
} _cached_state;
|
||||
@ -173,9 +172,6 @@ template <typename VIRT> void Sup::Vcpu_impl<VIRT>::_transfer_state_to_vcpu(CPUM
|
||||
Vcpu_state &state { _vcpu.state() };
|
||||
|
||||
/* transfer defaults and cached state */
|
||||
state.inj_info.charge(VMX_ENTRY_INT_INFO_NONE); /* XXX never injects events */
|
||||
state.intr_state.charge(_cached_state.intr_state);
|
||||
state.actv_state.charge(VMX_VMCS_GUEST_ACTIVITY_ACTIVE);
|
||||
state.ctrl_primary.charge(_cached_state.ctrl_primary); /* XXX always updates ctrls */
|
||||
state.ctrl_secondary.charge(_cached_state.ctrl_secondary); /* XXX always updates ctrls */
|
||||
|
||||
@ -354,14 +350,14 @@ template <typename VIRT> void Sup::Vcpu_impl<VIRT>::_transfer_state_to_vbox(CPUM
|
||||
uint32_t const tpr = state.tpr.value();
|
||||
|
||||
/* update cached state */
|
||||
Assert(!VMX_ENTRY_INT_INFO_IS_VALID(state.inj_info.value()));
|
||||
_cached_state.intr_state = state.intr_state.value();
|
||||
_cached_state.ctrl_primary = state.ctrl_primary.value();
|
||||
_cached_state.ctrl_secondary = state.ctrl_secondary.value();
|
||||
|
||||
/* clear blocking by MOV SS or STI bits */
|
||||
if (_cached_state.intr_state & 3)
|
||||
_cached_state.intr_state &= ~3U;
|
||||
if (_vcpu.state().intr_state.value() & 3) {
|
||||
_vcpu.state().intr_state.charge(state.intr_state.value() & ~3U);
|
||||
_vcpu.state().actv_state.charge(VMX_VMCS_GUEST_ACTIVITY_ACTIVE);
|
||||
}
|
||||
|
||||
VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TO_R3);
|
||||
|
||||
@ -491,7 +487,7 @@ typename Sup::Vcpu_impl<T>::Current_state Sup::Vcpu_impl<T>::_handle_paused()
|
||||
|
||||
Assert(state.actv_state.value() == VMX_VMCS_GUEST_ACTIVITY_ACTIVE);
|
||||
|
||||
if (VMX_ENTRY_INT_INFO_IS_VALID(state.inj_info.value())) {
|
||||
if (VMX_EXIT_INT_INFO_IS_VALID(state.inj_info.value())) {
|
||||
|
||||
Assert(state.flags.value() & X86_EFL_IF);
|
||||
|
||||
@ -519,7 +515,6 @@ typename Sup::Vcpu_impl<T>::Current_state Sup::Vcpu_impl<T>::_handle_paused()
|
||||
|
||||
/* check whether we have to request irq injection window */
|
||||
if (_check_and_request_irq_window()) {
|
||||
state.discharge();
|
||||
state.inj_info.charge(state.inj_info.value());
|
||||
_irq_window = true;
|
||||
return RUNNING;
|
||||
@ -541,14 +536,12 @@ typename Sup::Vcpu_impl<T>::Current_state Sup::Vcpu_impl<T>::_handle_irq_window(
|
||||
{
|
||||
Vcpu_state &state { _vcpu.state() };
|
||||
|
||||
state.discharge();
|
||||
|
||||
PVMCPU pVCpu = &_vmcpu;
|
||||
|
||||
Assert(state.intr_state.value() == VMX_VMCS_GUEST_INT_STATE_NONE);
|
||||
Assert(state.flags.value() & X86_EFL_IF);
|
||||
Assert(!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS));
|
||||
Assert(!VMX_ENTRY_INT_INFO_IS_VALID(state.inj_info.value()));
|
||||
Assert(!VMX_EXIT_INT_INFO_IS_VALID(state.inj_info.value()));
|
||||
Assert(_irq_window);
|
||||
|
||||
_irq_window = false;
|
||||
@ -638,6 +631,9 @@ template <typename VIRT> VBOXSTRICTRC Sup::Vcpu_impl<VIRT>::_switch_to_hw()
|
||||
|
||||
result = VIRT::handle_exit(_vcpu.state());
|
||||
|
||||
/* discharge by default */
|
||||
_vcpu.state().discharge();
|
||||
|
||||
switch (result.state) {
|
||||
|
||||
case Exit_state::STARTUP:
|
||||
|
@ -193,7 +193,7 @@ Sup::Handle_exit_result Sup::Svm::handle_exit(Vcpu_state &state)
|
||||
case SVM_EXIT_RDTSCP:
|
||||
case SVM_EXIT_WBINVD:
|
||||
Assert(state.actv_state.value() == VMX_VMCS_GUEST_ACTIVITY_ACTIVE);
|
||||
Assert(!VMX_ENTRY_INT_INFO_IS_VALID(state.inj_info.value()));
|
||||
Assert(!VMX_EXIT_INT_INFO_IS_VALID(state.inj_info.value()));
|
||||
return { Exit_state::DEFAULT, VINF_EM_RAW_EMULATE_INSTR };
|
||||
|
||||
case SVM_EXIT_VINTR:
|
||||
|
@ -183,7 +183,7 @@ void Sup::Vmx::_handle_invalid(Vcpu_state const &state)
|
||||
void Sup::Vmx::_handle_default(Vcpu_state &state)
|
||||
{
|
||||
Assert(state.actv_state.value() == VMX_VMCS_GUEST_ACTIVITY_ACTIVE);
|
||||
Assert(!VMX_ENTRY_INT_INFO_IS_VALID(state.inj_info.value()));
|
||||
Assert(!VMX_EXIT_INT_INFO_IS_VALID(state.inj_info.value()));
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user