diff options
-rw-r--r-- | Documentation/kvm/api.txt | 11 | ||||
-rw-r--r-- | arch/x86/include/asm/kvm.h | 7 | ||||
-rw-r--r-- | arch/x86/include/asm/kvm_emulate.h | 3 | ||||
-rw-r--r-- | arch/x86/kvm/emulate.c | 4 | ||||
-rw-r--r-- | arch/x86/kvm/svm.c | 2 | ||||
-rw-r--r-- | arch/x86/kvm/vmx.c | 8 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 12 | ||||
-rw-r--r-- | include/linux/kvm.h | 1 |
8 files changed, 34 insertions, 14 deletions
diff --git a/Documentation/kvm/api.txt b/Documentation/kvm/api.txt index beb444a95013..9e5de5a1c4ef 100644 --- a/Documentation/kvm/api.txt +++ b/Documentation/kvm/api.txt | |||
@@ -656,6 +656,7 @@ struct kvm_clock_data { | |||
656 | 4.29 KVM_GET_VCPU_EVENTS | 656 | 4.29 KVM_GET_VCPU_EVENTS |
657 | 657 | ||
658 | Capability: KVM_CAP_VCPU_EVENTS | 658 | Capability: KVM_CAP_VCPU_EVENTS |
659 | Extended by: KVM_CAP_INTR_SHADOW | ||
659 | Architectures: x86 | 660 | Architectures: x86 |
660 | Type: vm ioctl | 661 | Type: vm ioctl |
661 | Parameters: struct kvm_vcpu_event (out) | 662 | Parameters: struct kvm_vcpu_event (out) |
@@ -676,7 +677,7 @@ struct kvm_vcpu_events { | |||
676 | __u8 injected; | 677 | __u8 injected; |
677 | __u8 nr; | 678 | __u8 nr; |
678 | __u8 soft; | 679 | __u8 soft; |
679 | __u8 pad; | 680 | __u8 shadow; |
680 | } interrupt; | 681 | } interrupt; |
681 | struct { | 682 | struct { |
682 | __u8 injected; | 683 | __u8 injected; |
@@ -688,9 +689,13 @@ struct kvm_vcpu_events { | |||
688 | __u32 flags; | 689 | __u32 flags; |
689 | }; | 690 | }; |
690 | 691 | ||
692 | KVM_VCPUEVENT_VALID_SHADOW may be set in the flags field to signal that | ||
693 | interrupt.shadow contains a valid state. Otherwise, this field is undefined. | ||
694 | |||
691 | 4.30 KVM_SET_VCPU_EVENTS | 695 | 4.30 KVM_SET_VCPU_EVENTS |
692 | 696 | ||
693 | Capability: KVM_CAP_VCPU_EVENTS | 697 | Capability: KVM_CAP_VCPU_EVENTS |
698 | Extended by: KVM_CAP_INTR_SHADOW | ||
694 | Architectures: x86 | 699 | Architectures: x86 |
695 | Type: vm ioctl | 700 | Type: vm ioctl |
696 | Parameters: struct kvm_vcpu_event (in) | 701 | Parameters: struct kvm_vcpu_event (in) |
@@ -709,6 +714,10 @@ current in-kernel state. The bits are: | |||
709 | KVM_VCPUEVENT_VALID_NMI_PENDING - transfer nmi.pending to the kernel | 714 | KVM_VCPUEVENT_VALID_NMI_PENDING - transfer nmi.pending to the kernel |
710 | KVM_VCPUEVENT_VALID_SIPI_VECTOR - transfer sipi_vector | 715 | KVM_VCPUEVENT_VALID_SIPI_VECTOR - transfer sipi_vector |
711 | 716 | ||
717 | If KVM_CAP_INTR_SHADOW is available, KVM_VCPUEVENT_VALID_SHADOW can be set in | ||
718 | the flags field to signal that interrupt.shadow contains a valid state and | ||
719 | shall be written into the VCPU. | ||
720 | |||
712 | 721 | ||
713 | 5. The kvm_run structure | 722 | 5. The kvm_run structure |
714 | 723 | ||
diff --git a/arch/x86/include/asm/kvm.h b/arch/x86/include/asm/kvm.h index f46b79f6c16c..fb6117063ea3 100644 --- a/arch/x86/include/asm/kvm.h +++ b/arch/x86/include/asm/kvm.h | |||
@@ -257,6 +257,11 @@ struct kvm_reinject_control { | |||
257 | /* When set in flags, include corresponding fields on KVM_SET_VCPU_EVENTS */ | 257 | /* When set in flags, include corresponding fields on KVM_SET_VCPU_EVENTS */ |
258 | #define KVM_VCPUEVENT_VALID_NMI_PENDING 0x00000001 | 258 | #define KVM_VCPUEVENT_VALID_NMI_PENDING 0x00000001 |
259 | #define KVM_VCPUEVENT_VALID_SIPI_VECTOR 0x00000002 | 259 | #define KVM_VCPUEVENT_VALID_SIPI_VECTOR 0x00000002 |
260 | #define KVM_VCPUEVENT_VALID_SHADOW 0x00000004 | ||
261 | |||
262 | /* Interrupt shadow states */ | ||
263 | #define KVM_X86_SHADOW_INT_MOV_SS 0x01 | ||
264 | #define KVM_X86_SHADOW_INT_STI 0x02 | ||
260 | 265 | ||
261 | /* for KVM_GET/SET_VCPU_EVENTS */ | 266 | /* for KVM_GET/SET_VCPU_EVENTS */ |
262 | struct kvm_vcpu_events { | 267 | struct kvm_vcpu_events { |
@@ -271,7 +276,7 @@ struct kvm_vcpu_events { | |||
271 | __u8 injected; | 276 | __u8 injected; |
272 | __u8 nr; | 277 | __u8 nr; |
273 | __u8 soft; | 278 | __u8 soft; |
274 | __u8 pad; | 279 | __u8 shadow; |
275 | } interrupt; | 280 | } interrupt; |
276 | struct { | 281 | struct { |
277 | __u8 injected; | 282 | __u8 injected; |
diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h index 7a6f54fa13ba..2666d7ac3229 100644 --- a/arch/x86/include/asm/kvm_emulate.h +++ b/arch/x86/include/asm/kvm_emulate.h | |||
@@ -153,9 +153,6 @@ struct decode_cache { | |||
153 | struct fetch_cache fetch; | 153 | struct fetch_cache fetch; |
154 | }; | 154 | }; |
155 | 155 | ||
156 | #define X86_SHADOW_INT_MOV_SS 1 | ||
157 | #define X86_SHADOW_INT_STI 2 | ||
158 | |||
159 | struct x86_emulate_ctxt { | 156 | struct x86_emulate_ctxt { |
160 | /* Register state before/after emulation. */ | 157 | /* Register state before/after emulation. */ |
161 | struct kvm_vcpu *vcpu; | 158 | struct kvm_vcpu *vcpu; |
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 35f7acd4a91f..c9f604b0819c 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -2128,7 +2128,7 @@ special_insn: | |||
2128 | } | 2128 | } |
2129 | 2129 | ||
2130 | if (c->modrm_reg == VCPU_SREG_SS) | 2130 | if (c->modrm_reg == VCPU_SREG_SS) |
2131 | toggle_interruptibility(ctxt, X86_SHADOW_INT_MOV_SS); | 2131 | toggle_interruptibility(ctxt, KVM_X86_SHADOW_INT_MOV_SS); |
2132 | 2132 | ||
2133 | rc = kvm_load_segment_descriptor(ctxt->vcpu, sel, c->modrm_reg); | 2133 | rc = kvm_load_segment_descriptor(ctxt->vcpu, sel, c->modrm_reg); |
2134 | 2134 | ||
@@ -2366,7 +2366,7 @@ special_insn: | |||
2366 | if (emulator_bad_iopl(ctxt)) | 2366 | if (emulator_bad_iopl(ctxt)) |
2367 | kvm_inject_gp(ctxt->vcpu, 0); | 2367 | kvm_inject_gp(ctxt->vcpu, 0); |
2368 | else { | 2368 | else { |
2369 | toggle_interruptibility(ctxt, X86_SHADOW_INT_STI); | 2369 | toggle_interruptibility(ctxt, KVM_X86_SHADOW_INT_STI); |
2370 | ctxt->eflags |= X86_EFLAGS_IF; | 2370 | ctxt->eflags |= X86_EFLAGS_IF; |
2371 | c->dst.type = OP_NONE; /* Disable writeback. */ | 2371 | c->dst.type = OP_NONE; /* Disable writeback. */ |
2372 | } | 2372 | } |
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 294bbca34173..bd8f52f0823f 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -265,7 +265,7 @@ static u32 svm_get_interrupt_shadow(struct kvm_vcpu *vcpu, int mask) | |||
265 | u32 ret = 0; | 265 | u32 ret = 0; |
266 | 266 | ||
267 | if (svm->vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK) | 267 | if (svm->vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK) |
268 | ret |= X86_SHADOW_INT_STI | X86_SHADOW_INT_MOV_SS; | 268 | ret |= KVM_X86_SHADOW_INT_STI | KVM_X86_SHADOW_INT_MOV_SS; |
269 | return ret & mask; | 269 | return ret & mask; |
270 | } | 270 | } |
271 | 271 | ||
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 68f895b00450..61f03980adae 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -846,9 +846,9 @@ static u32 vmx_get_interrupt_shadow(struct kvm_vcpu *vcpu, int mask) | |||
846 | int ret = 0; | 846 | int ret = 0; |
847 | 847 | ||
848 | if (interruptibility & GUEST_INTR_STATE_STI) | 848 | if (interruptibility & GUEST_INTR_STATE_STI) |
849 | ret |= X86_SHADOW_INT_STI; | 849 | ret |= KVM_X86_SHADOW_INT_STI; |
850 | if (interruptibility & GUEST_INTR_STATE_MOV_SS) | 850 | if (interruptibility & GUEST_INTR_STATE_MOV_SS) |
851 | ret |= X86_SHADOW_INT_MOV_SS; | 851 | ret |= KVM_X86_SHADOW_INT_MOV_SS; |
852 | 852 | ||
853 | return ret & mask; | 853 | return ret & mask; |
854 | } | 854 | } |
@@ -860,9 +860,9 @@ static void vmx_set_interrupt_shadow(struct kvm_vcpu *vcpu, int mask) | |||
860 | 860 | ||
861 | interruptibility &= ~(GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS); | 861 | interruptibility &= ~(GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS); |
862 | 862 | ||
863 | if (mask & X86_SHADOW_INT_MOV_SS) | 863 | if (mask & KVM_X86_SHADOW_INT_MOV_SS) |
864 | interruptibility |= GUEST_INTR_STATE_MOV_SS; | 864 | interruptibility |= GUEST_INTR_STATE_MOV_SS; |
865 | if (mask & X86_SHADOW_INT_STI) | 865 | else if (mask & KVM_X86_SHADOW_INT_STI) |
866 | interruptibility |= GUEST_INTR_STATE_STI; | 866 | interruptibility |= GUEST_INTR_STATE_STI; |
867 | 867 | ||
868 | if ((interruptibility != interruptibility_old)) | 868 | if ((interruptibility != interruptibility_old)) |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 2b1c9f2fb8dd..84ffd95ee198 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -2111,6 +2111,9 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu, | |||
2111 | vcpu->arch.interrupt.pending && !vcpu->arch.interrupt.soft; | 2111 | vcpu->arch.interrupt.pending && !vcpu->arch.interrupt.soft; |
2112 | events->interrupt.nr = vcpu->arch.interrupt.nr; | 2112 | events->interrupt.nr = vcpu->arch.interrupt.nr; |
2113 | events->interrupt.soft = 0; | 2113 | events->interrupt.soft = 0; |
2114 | events->interrupt.shadow = | ||
2115 | kvm_x86_ops->get_interrupt_shadow(vcpu, | ||
2116 | KVM_X86_SHADOW_INT_MOV_SS | KVM_X86_SHADOW_INT_STI); | ||
2114 | 2117 | ||
2115 | events->nmi.injected = vcpu->arch.nmi_injected; | 2118 | events->nmi.injected = vcpu->arch.nmi_injected; |
2116 | events->nmi.pending = vcpu->arch.nmi_pending; | 2119 | events->nmi.pending = vcpu->arch.nmi_pending; |
@@ -2119,7 +2122,8 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu, | |||
2119 | events->sipi_vector = vcpu->arch.sipi_vector; | 2122 | events->sipi_vector = vcpu->arch.sipi_vector; |
2120 | 2123 | ||
2121 | events->flags = (KVM_VCPUEVENT_VALID_NMI_PENDING | 2124 | events->flags = (KVM_VCPUEVENT_VALID_NMI_PENDING |
2122 | | KVM_VCPUEVENT_VALID_SIPI_VECTOR); | 2125 | | KVM_VCPUEVENT_VALID_SIPI_VECTOR |
2126 | | KVM_VCPUEVENT_VALID_SHADOW); | ||
2123 | 2127 | ||
2124 | vcpu_put(vcpu); | 2128 | vcpu_put(vcpu); |
2125 | } | 2129 | } |
@@ -2128,7 +2132,8 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu, | |||
2128 | struct kvm_vcpu_events *events) | 2132 | struct kvm_vcpu_events *events) |
2129 | { | 2133 | { |
2130 | if (events->flags & ~(KVM_VCPUEVENT_VALID_NMI_PENDING | 2134 | if (events->flags & ~(KVM_VCPUEVENT_VALID_NMI_PENDING |
2131 | | KVM_VCPUEVENT_VALID_SIPI_VECTOR)) | 2135 | | KVM_VCPUEVENT_VALID_SIPI_VECTOR |
2136 | | KVM_VCPUEVENT_VALID_SHADOW)) | ||
2132 | return -EINVAL; | 2137 | return -EINVAL; |
2133 | 2138 | ||
2134 | vcpu_load(vcpu); | 2139 | vcpu_load(vcpu); |
@@ -2143,6 +2148,9 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu, | |||
2143 | vcpu->arch.interrupt.soft = events->interrupt.soft; | 2148 | vcpu->arch.interrupt.soft = events->interrupt.soft; |
2144 | if (vcpu->arch.interrupt.pending && irqchip_in_kernel(vcpu->kvm)) | 2149 | if (vcpu->arch.interrupt.pending && irqchip_in_kernel(vcpu->kvm)) |
2145 | kvm_pic_clear_isr_ack(vcpu->kvm); | 2150 | kvm_pic_clear_isr_ack(vcpu->kvm); |
2151 | if (events->flags & KVM_VCPUEVENT_VALID_SHADOW) | ||
2152 | kvm_x86_ops->set_interrupt_shadow(vcpu, | ||
2153 | events->interrupt.shadow); | ||
2146 | 2154 | ||
2147 | vcpu->arch.nmi_injected = events->nmi.injected; | 2155 | vcpu->arch.nmi_injected = events->nmi.injected; |
2148 | if (events->flags & KVM_VCPUEVENT_VALID_NMI_PENDING) | 2156 | if (events->flags & KVM_VCPUEVENT_VALID_NMI_PENDING) |
diff --git a/include/linux/kvm.h b/include/linux/kvm.h index 360f85e8c435..48516a2a0b84 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h | |||
@@ -502,6 +502,7 @@ struct kvm_ioeventfd { | |||
502 | #define KVM_CAP_HYPERV_SPIN 46 | 502 | #define KVM_CAP_HYPERV_SPIN 46 |
503 | #define KVM_CAP_PCI_SEGMENT 47 | 503 | #define KVM_CAP_PCI_SEGMENT 47 |
504 | #define KVM_CAP_PPC_PAIRED_SINGLES 48 | 504 | #define KVM_CAP_PPC_PAIRED_SINGLES 48 |
505 | #define KVM_CAP_INTR_SHADOW 49 | ||
505 | #define KVM_CAP_X86_ROBUST_SINGLESTEP 51 | 506 | #define KVM_CAP_X86_ROBUST_SINGLESTEP 51 |
506 | 507 | ||
507 | #ifdef KVM_CAP_IRQ_ROUTING | 508 | #ifdef KVM_CAP_IRQ_ROUTING |