hv: fix general protection injection

Exception type is missing when inject a #GP.
GP should be injected even when guest irq disabled.

Signed-off-by: Binbin Wu <binbin.wu@intel.com>
Reviewed-by: Jason Chen CJ <jason.cj.chen@intel.com>
Acked-by: Eddie Dong <Eddie.dong@intel.com>
This commit is contained in:
Binbin Wu 2018-05-20 23:35:30 +08:00 committed by lijinxia
parent 2175bcafa1
commit d8d6176266

View File

@ -200,9 +200,17 @@ static int vcpu_do_pending_extint(struct vcpu *vcpu)
static int vcpu_do_pending_gp(__unused struct vcpu *vcpu) static int vcpu_do_pending_gp(__unused struct vcpu *vcpu)
{ {
/* SDM Vol. 3A 6-37: if the fault condition was detected while loading
* a segment descriptor, the error code contains a segment selecor to or
* IDT vector number for the descriptor; otherwise the error code is 0.
* Since currently there is no such case to inject #GP due to loading a
* segment decriptor, set the error code to 0.
*/
exec_vmwrite(VMX_ENTRY_EXCEPTION_ERROR_CODE, 0);
/* GP vector = 13 */ /* GP vector = 13 */
exec_vmwrite(VMX_ENTRY_INT_INFO_FIELD, exec_vmwrite(VMX_ENTRY_INT_INFO_FIELD,
VMX_INT_INFO_VALID | 13); VMX_INT_INFO_VALID |
((VMX_INT_TYPE_HW_EXP | EXCEPTION_ERROR_CODE_VALID) <<8) | 13);
return 0; return 0;
} }
@ -337,8 +345,7 @@ int acrn_do_intr_process(struct vcpu *vcpu)
exec_vmwrite(VMX_ENTRY_INT_INFO_FIELD, exec_vmwrite(VMX_ENTRY_INT_INFO_FIELD,
VMX_INT_INFO_VALID | VMX_INT_INFO_VALID |
((exception_type[vector] & 15) << 8) (exception_type[vector] << 8) | (vector & 0xFF));
| (vector & 0xFF));
vcpu->arch_vcpu.exception_info.exception = -1; vcpu->arch_vcpu.exception_info.exception = -1;
@ -361,24 +368,23 @@ int acrn_do_intr_process(struct vcpu *vcpu)
} }
/* Guest interruptable or not */ /* Guest interruptable or not */
if (!is_guest_irq_enabled(vcpu)) { if (is_guest_irq_enabled(vcpu)) {
/* interrupt window unavailable */
goto INTR_WIN;
}
/* Inject external interrupt first */ /* Inject external interrupt first */
if (bitmap_test_and_clear(ACRN_REQUEST_EXTINT, pending_intr_bits)) { if (bitmap_test_and_clear(ACRN_REQUEST_EXTINT,
pending_intr_bits)) {
/* has pending external interrupts */ /* has pending external interrupts */
ret = vcpu_do_pending_extint(vcpu); ret = vcpu_do_pending_extint(vcpu);
goto INTR_WIN; goto INTR_WIN;
} }
/* Inject vLAPIC vectors */ /* Inject vLAPIC vectors */
if (bitmap_test_and_clear(ACRN_REQUEST_EVENT, pending_intr_bits)) { if (bitmap_test_and_clear(ACRN_REQUEST_EVENT,
pending_intr_bits)) {
/* has pending vLAPIC interrupts */ /* has pending vLAPIC interrupts */
ret = vcpu_do_pending_event(vcpu); ret = vcpu_do_pending_event(vcpu);
goto INTR_WIN; goto INTR_WIN;
} }
}
/* Inject GP event */ /* Inject GP event */
if (bitmap_test_and_clear(ACRN_REQUEST_GP, pending_intr_bits)) { if (bitmap_test_and_clear(ACRN_REQUEST_GP, pending_intr_bits)) {