diff options
Diffstat (limited to 'arch/x86/kvm/vmx.c')
-rw-r--r-- | arch/x86/kvm/vmx.c | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 85904fa41f03..3acbe194e525 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -61,6 +61,8 @@ module_param_named(unrestricted_guest, | |||
61 | static int __read_mostly emulate_invalid_guest_state = 0; | 61 | static int __read_mostly emulate_invalid_guest_state = 0; |
62 | module_param(emulate_invalid_guest_state, bool, S_IRUGO); | 62 | module_param(emulate_invalid_guest_state, bool, S_IRUGO); |
63 | 63 | ||
64 | #define RMODE_GUEST_OWNED_EFLAGS_BITS (~(X86_EFLAGS_IOPL | X86_EFLAGS_VM)) | ||
65 | |||
64 | /* | 66 | /* |
65 | * These 2 parameters are used to config the controls for Pause-Loop Exiting: | 67 | * These 2 parameters are used to config the controls for Pause-Loop Exiting: |
66 | * ple_gap: upper bound on the amount of time between two successive | 68 | * ple_gap: upper bound on the amount of time between two successive |
@@ -115,7 +117,7 @@ struct vcpu_vmx { | |||
115 | } host_state; | 117 | } host_state; |
116 | struct { | 118 | struct { |
117 | int vm86_active; | 119 | int vm86_active; |
118 | u8 save_iopl; | 120 | ulong save_rflags; |
119 | struct kvm_save_segment { | 121 | struct kvm_save_segment { |
120 | u16 selector; | 122 | u16 selector; |
121 | unsigned long base; | 123 | unsigned long base; |
@@ -787,18 +789,23 @@ static void vmx_fpu_deactivate(struct kvm_vcpu *vcpu) | |||
787 | 789 | ||
788 | static unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu) | 790 | static unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu) |
789 | { | 791 | { |
790 | unsigned long rflags; | 792 | unsigned long rflags, save_rflags; |
791 | 793 | ||
792 | rflags = vmcs_readl(GUEST_RFLAGS); | 794 | rflags = vmcs_readl(GUEST_RFLAGS); |
793 | if (to_vmx(vcpu)->rmode.vm86_active) | 795 | if (to_vmx(vcpu)->rmode.vm86_active) { |
794 | rflags &= ~(unsigned long)(X86_EFLAGS_IOPL | X86_EFLAGS_VM); | 796 | rflags &= RMODE_GUEST_OWNED_EFLAGS_BITS; |
797 | save_rflags = to_vmx(vcpu)->rmode.save_rflags; | ||
798 | rflags |= save_rflags & ~RMODE_GUEST_OWNED_EFLAGS_BITS; | ||
799 | } | ||
795 | return rflags; | 800 | return rflags; |
796 | } | 801 | } |
797 | 802 | ||
798 | static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags) | 803 | static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags) |
799 | { | 804 | { |
800 | if (to_vmx(vcpu)->rmode.vm86_active) | 805 | if (to_vmx(vcpu)->rmode.vm86_active) { |
806 | to_vmx(vcpu)->rmode.save_rflags = rflags; | ||
801 | rflags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM; | 807 | rflags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM; |
808 | } | ||
802 | vmcs_writel(GUEST_RFLAGS, rflags); | 809 | vmcs_writel(GUEST_RFLAGS, rflags); |
803 | } | 810 | } |
804 | 811 | ||
@@ -1431,8 +1438,8 @@ static void enter_pmode(struct kvm_vcpu *vcpu) | |||
1431 | vmcs_write32(GUEST_TR_AR_BYTES, vmx->rmode.tr.ar); | 1438 | vmcs_write32(GUEST_TR_AR_BYTES, vmx->rmode.tr.ar); |
1432 | 1439 | ||
1433 | flags = vmcs_readl(GUEST_RFLAGS); | 1440 | flags = vmcs_readl(GUEST_RFLAGS); |
1434 | flags &= ~(X86_EFLAGS_IOPL | X86_EFLAGS_VM); | 1441 | flags &= RMODE_GUEST_OWNED_EFLAGS_BITS; |
1435 | flags |= (vmx->rmode.save_iopl << IOPL_SHIFT); | 1442 | flags |= vmx->rmode.save_rflags & ~RMODE_GUEST_OWNED_EFLAGS_BITS; |
1436 | vmcs_writel(GUEST_RFLAGS, flags); | 1443 | vmcs_writel(GUEST_RFLAGS, flags); |
1437 | 1444 | ||
1438 | vmcs_writel(GUEST_CR4, (vmcs_readl(GUEST_CR4) & ~X86_CR4_VME) | | 1445 | vmcs_writel(GUEST_CR4, (vmcs_readl(GUEST_CR4) & ~X86_CR4_VME) | |
@@ -1501,8 +1508,7 @@ static void enter_rmode(struct kvm_vcpu *vcpu) | |||
1501 | vmcs_write32(GUEST_TR_AR_BYTES, 0x008b); | 1508 | vmcs_write32(GUEST_TR_AR_BYTES, 0x008b); |
1502 | 1509 | ||
1503 | flags = vmcs_readl(GUEST_RFLAGS); | 1510 | flags = vmcs_readl(GUEST_RFLAGS); |
1504 | vmx->rmode.save_iopl | 1511 | vmx->rmode.save_rflags = flags; |
1505 | = (flags & X86_EFLAGS_IOPL) >> IOPL_SHIFT; | ||
1506 | 1512 | ||
1507 | flags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM; | 1513 | flags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM; |
1508 | 1514 | ||