diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-06-20 16:50:37 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-06-20 16:50:37 -0400 |
commit | b3e978337b25b042aa653652a029e3d798814c12 (patch) | |
tree | f03c4b0b6d9eadb4cef3daa8c1f9920415cdcefe | |
parent | e929387449cf631e96840296a01922be1ef3c832 (diff) | |
parent | b21e31b253048b7f9768ca7cc270e67765fd6ba2 (diff) |
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull kvm fixes from Paolo Bonzini:
"Fixes for ARM and x86, plus selftest patches and nicer structs for
nested state save/restore"
* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm:
KVM: nVMX: reorganize initial steps of vmx_set_nested_state
KVM: arm/arm64: Fix emulated ptimer irq injection
tests: kvm: Check for a kernel warning
kvm: tests: Sort tests in the Makefile alphabetically
KVM: x86/mmu: Allocate PAE root array when using SVM's 32-bit NPT
KVM: x86: Modify struct kvm_nested_state to have explicit fields for data
KVM: fix typo in documentation
KVM: nVMX: use correct clean fields when copying from eVMCS
KVM: arm/arm64: vgic: Fix kvm_device leak in vgic_its_destroy
KVM: arm64: Filter out invalid core register IDs in KVM_GET_REG_LIST
KVM: arm64: Implement vq_present() as a macro
-rw-r--r-- | Documentation/virtual/kvm/api.txt | 48 | ||||
-rw-r--r-- | arch/arm64/kvm/guest.c | 65 | ||||
-rw-r--r-- | arch/x86/include/uapi/asm/kvm.h | 33 | ||||
-rw-r--r-- | arch/x86/kvm/mmu.c | 16 | ||||
-rw-r--r-- | arch/x86/kvm/vmx/nested.c | 103 | ||||
-rw-r--r-- | arch/x86/kvm/vmx/vmcs12.h | 5 | ||||
-rw-r--r-- | tools/arch/x86/include/uapi/asm/kvm.h | 2 | ||||
-rw-r--r-- | tools/testing/selftests/kvm/.gitignore | 1 | ||||
-rw-r--r-- | tools/testing/selftests/kvm/Makefile | 21 | ||||
-rw-r--r-- | tools/testing/selftests/kvm/include/kvm_util.h | 2 | ||||
-rw-r--r-- | tools/testing/selftests/kvm/include/x86_64/processor.h | 2 | ||||
-rw-r--r-- | tools/testing/selftests/kvm/lib/kvm_util.c | 36 | ||||
-rw-r--r-- | tools/testing/selftests/kvm/lib/x86_64/processor.c | 16 | ||||
-rw-r--r-- | tools/testing/selftests/kvm/x86_64/mmio_warning_test.c | 126 | ||||
-rw-r--r-- | tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c | 68 | ||||
-rw-r--r-- | virt/kvm/arm/arch_timer.c | 5 | ||||
-rw-r--r-- | virt/kvm/arm/vgic/vgic-its.c | 1 |
17 files changed, 405 insertions, 145 deletions
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index ba6c42c576dd..2a4531bb06bd 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt | |||
@@ -1079,7 +1079,7 @@ yet and must be cleared on entry. | |||
1079 | 1079 | ||
1080 | 4.35 KVM_SET_USER_MEMORY_REGION | 1080 | 4.35 KVM_SET_USER_MEMORY_REGION |
1081 | 1081 | ||
1082 | Capability: KVM_CAP_USER_MEM | 1082 | Capability: KVM_CAP_USER_MEMORY |
1083 | Architectures: all | 1083 | Architectures: all |
1084 | Type: vm ioctl | 1084 | Type: vm ioctl |
1085 | Parameters: struct kvm_userspace_memory_region (in) | 1085 | Parameters: struct kvm_userspace_memory_region (in) |
@@ -3857,43 +3857,59 @@ Type: vcpu ioctl | |||
3857 | Parameters: struct kvm_nested_state (in/out) | 3857 | Parameters: struct kvm_nested_state (in/out) |
3858 | Returns: 0 on success, -1 on error | 3858 | Returns: 0 on success, -1 on error |
3859 | Errors: | 3859 | Errors: |
3860 | E2BIG: the total state size (including the fixed-size part of struct | 3860 | E2BIG: the total state size exceeds the value of 'size' specified by |
3861 | kvm_nested_state) exceeds the value of 'size' specified by | ||
3862 | the user; the size required will be written into size. | 3861 | the user; the size required will be written into size. |
3863 | 3862 | ||
3864 | struct kvm_nested_state { | 3863 | struct kvm_nested_state { |
3865 | __u16 flags; | 3864 | __u16 flags; |
3866 | __u16 format; | 3865 | __u16 format; |
3867 | __u32 size; | 3866 | __u32 size; |
3867 | |||
3868 | union { | 3868 | union { |
3869 | struct kvm_vmx_nested_state vmx; | 3869 | struct kvm_vmx_nested_state_hdr vmx; |
3870 | struct kvm_svm_nested_state svm; | 3870 | struct kvm_svm_nested_state_hdr svm; |
3871 | |||
3872 | /* Pad the header to 128 bytes. */ | ||
3871 | __u8 pad[120]; | 3873 | __u8 pad[120]; |
3872 | }; | 3874 | } hdr; |
3873 | __u8 data[0]; | 3875 | |
3876 | union { | ||
3877 | struct kvm_vmx_nested_state_data vmx[0]; | ||
3878 | struct kvm_svm_nested_state_data svm[0]; | ||
3879 | } data; | ||
3874 | }; | 3880 | }; |
3875 | 3881 | ||
3876 | #define KVM_STATE_NESTED_GUEST_MODE 0x00000001 | 3882 | #define KVM_STATE_NESTED_GUEST_MODE 0x00000001 |
3877 | #define KVM_STATE_NESTED_RUN_PENDING 0x00000002 | 3883 | #define KVM_STATE_NESTED_RUN_PENDING 0x00000002 |
3884 | #define KVM_STATE_NESTED_EVMCS 0x00000004 | ||
3878 | 3885 | ||
3879 | #define KVM_STATE_NESTED_SMM_GUEST_MODE 0x00000001 | 3886 | #define KVM_STATE_NESTED_FORMAT_VMX 0 |
3880 | #define KVM_STATE_NESTED_SMM_VMXON 0x00000002 | 3887 | #define KVM_STATE_NESTED_FORMAT_SVM 1 |
3881 | 3888 | ||
3882 | struct kvm_vmx_nested_state { | 3889 | #define KVM_STATE_NESTED_VMX_VMCS_SIZE 0x1000 |
3890 | |||
3891 | #define KVM_STATE_NESTED_VMX_SMM_GUEST_MODE 0x00000001 | ||
3892 | #define KVM_STATE_NESTED_VMX_SMM_VMXON 0x00000002 | ||
3893 | |||
3894 | struct kvm_vmx_nested_state_hdr { | ||
3883 | __u64 vmxon_pa; | 3895 | __u64 vmxon_pa; |
3884 | __u64 vmcs_pa; | 3896 | __u64 vmcs12_pa; |
3885 | 3897 | ||
3886 | struct { | 3898 | struct { |
3887 | __u16 flags; | 3899 | __u16 flags; |
3888 | } smm; | 3900 | } smm; |
3889 | }; | 3901 | }; |
3890 | 3902 | ||
3903 | struct kvm_vmx_nested_state_data { | ||
3904 | __u8 vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE]; | ||
3905 | __u8 shadow_vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE]; | ||
3906 | }; | ||
3907 | |||
3891 | This ioctl copies the vcpu's nested virtualization state from the kernel to | 3908 | This ioctl copies the vcpu's nested virtualization state from the kernel to |
3892 | userspace. | 3909 | userspace. |
3893 | 3910 | ||
3894 | The maximum size of the state, including the fixed-size part of struct | 3911 | The maximum size of the state can be retrieved by passing KVM_CAP_NESTED_STATE |
3895 | kvm_nested_state, can be retrieved by passing KVM_CAP_NESTED_STATE to | 3912 | to the KVM_CHECK_EXTENSION ioctl(). |
3896 | the KVM_CHECK_EXTENSION ioctl(). | ||
3897 | 3913 | ||
3898 | 4.115 KVM_SET_NESTED_STATE | 3914 | 4.115 KVM_SET_NESTED_STATE |
3899 | 3915 | ||
@@ -3903,8 +3919,8 @@ Type: vcpu ioctl | |||
3903 | Parameters: struct kvm_nested_state (in) | 3919 | Parameters: struct kvm_nested_state (in) |
3904 | Returns: 0 on success, -1 on error | 3920 | Returns: 0 on success, -1 on error |
3905 | 3921 | ||
3906 | This copies the vcpu's kvm_nested_state struct from userspace to the kernel. For | 3922 | This copies the vcpu's kvm_nested_state struct from userspace to the kernel. |
3907 | the definition of struct kvm_nested_state, see KVM_GET_NESTED_STATE. | 3923 | For the definition of struct kvm_nested_state, see KVM_GET_NESTED_STATE. |
3908 | 3924 | ||
3909 | 4.116 KVM_(UN)REGISTER_COALESCED_MMIO | 3925 | 4.116 KVM_(UN)REGISTER_COALESCED_MMIO |
3910 | 3926 | ||
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c index 3ae2f82fca46..c8aa00179363 100644 --- a/arch/arm64/kvm/guest.c +++ b/arch/arm64/kvm/guest.c | |||
@@ -70,10 +70,8 @@ static u64 core_reg_offset_from_id(u64 id) | |||
70 | return id & ~(KVM_REG_ARCH_MASK | KVM_REG_SIZE_MASK | KVM_REG_ARM_CORE); | 70 | return id & ~(KVM_REG_ARCH_MASK | KVM_REG_SIZE_MASK | KVM_REG_ARM_CORE); |
71 | } | 71 | } |
72 | 72 | ||
73 | static int validate_core_offset(const struct kvm_vcpu *vcpu, | 73 | static int core_reg_size_from_offset(const struct kvm_vcpu *vcpu, u64 off) |
74 | const struct kvm_one_reg *reg) | ||
75 | { | 74 | { |
76 | u64 off = core_reg_offset_from_id(reg->id); | ||
77 | int size; | 75 | int size; |
78 | 76 | ||
79 | switch (off) { | 77 | switch (off) { |
@@ -103,8 +101,7 @@ static int validate_core_offset(const struct kvm_vcpu *vcpu, | |||
103 | return -EINVAL; | 101 | return -EINVAL; |
104 | } | 102 | } |
105 | 103 | ||
106 | if (KVM_REG_SIZE(reg->id) != size || | 104 | if (!IS_ALIGNED(off, size / sizeof(__u32))) |
107 | !IS_ALIGNED(off, size / sizeof(__u32))) | ||
108 | return -EINVAL; | 105 | return -EINVAL; |
109 | 106 | ||
110 | /* | 107 | /* |
@@ -115,6 +112,21 @@ static int validate_core_offset(const struct kvm_vcpu *vcpu, | |||
115 | if (vcpu_has_sve(vcpu) && core_reg_offset_is_vreg(off)) | 112 | if (vcpu_has_sve(vcpu) && core_reg_offset_is_vreg(off)) |
116 | return -EINVAL; | 113 | return -EINVAL; |
117 | 114 | ||
115 | return size; | ||
116 | } | ||
117 | |||
118 | static int validate_core_offset(const struct kvm_vcpu *vcpu, | ||
119 | const struct kvm_one_reg *reg) | ||
120 | { | ||
121 | u64 off = core_reg_offset_from_id(reg->id); | ||
122 | int size = core_reg_size_from_offset(vcpu, off); | ||
123 | |||
124 | if (size < 0) | ||
125 | return -EINVAL; | ||
126 | |||
127 | if (KVM_REG_SIZE(reg->id) != size) | ||
128 | return -EINVAL; | ||
129 | |||
118 | return 0; | 130 | return 0; |
119 | } | 131 | } |
120 | 132 | ||
@@ -207,13 +219,7 @@ out: | |||
207 | 219 | ||
208 | #define vq_word(vq) (((vq) - SVE_VQ_MIN) / 64) | 220 | #define vq_word(vq) (((vq) - SVE_VQ_MIN) / 64) |
209 | #define vq_mask(vq) ((u64)1 << ((vq) - SVE_VQ_MIN) % 64) | 221 | #define vq_mask(vq) ((u64)1 << ((vq) - SVE_VQ_MIN) % 64) |
210 | 222 | #define vq_present(vqs, vq) ((vqs)[vq_word(vq)] & vq_mask(vq)) | |
211 | static bool vq_present( | ||
212 | const u64 (*const vqs)[KVM_ARM64_SVE_VLS_WORDS], | ||
213 | unsigned int vq) | ||
214 | { | ||
215 | return (*vqs)[vq_word(vq)] & vq_mask(vq); | ||
216 | } | ||
217 | 223 | ||
218 | static int get_sve_vls(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) | 224 | static int get_sve_vls(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) |
219 | { | 225 | { |
@@ -258,7 +264,7 @@ static int set_sve_vls(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) | |||
258 | 264 | ||
259 | max_vq = 0; | 265 | max_vq = 0; |
260 | for (vq = SVE_VQ_MIN; vq <= SVE_VQ_MAX; ++vq) | 266 | for (vq = SVE_VQ_MIN; vq <= SVE_VQ_MAX; ++vq) |
261 | if (vq_present(&vqs, vq)) | 267 | if (vq_present(vqs, vq)) |
262 | max_vq = vq; | 268 | max_vq = vq; |
263 | 269 | ||
264 | if (max_vq > sve_vq_from_vl(kvm_sve_max_vl)) | 270 | if (max_vq > sve_vq_from_vl(kvm_sve_max_vl)) |
@@ -272,7 +278,7 @@ static int set_sve_vls(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) | |||
272 | * maximum: | 278 | * maximum: |
273 | */ | 279 | */ |
274 | for (vq = SVE_VQ_MIN; vq <= max_vq; ++vq) | 280 | for (vq = SVE_VQ_MIN; vq <= max_vq; ++vq) |
275 | if (vq_present(&vqs, vq) != sve_vq_available(vq)) | 281 | if (vq_present(vqs, vq) != sve_vq_available(vq)) |
276 | return -EINVAL; | 282 | return -EINVAL; |
277 | 283 | ||
278 | /* Can't run with no vector lengths at all: */ | 284 | /* Can't run with no vector lengths at all: */ |
@@ -453,19 +459,34 @@ static int copy_core_reg_indices(const struct kvm_vcpu *vcpu, | |||
453 | { | 459 | { |
454 | unsigned int i; | 460 | unsigned int i; |
455 | int n = 0; | 461 | int n = 0; |
456 | const u64 core_reg = KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE; | ||
457 | 462 | ||
458 | for (i = 0; i < sizeof(struct kvm_regs) / sizeof(__u32); i++) { | 463 | for (i = 0; i < sizeof(struct kvm_regs) / sizeof(__u32); i++) { |
459 | /* | 464 | u64 reg = KVM_REG_ARM64 | KVM_REG_ARM_CORE | i; |
460 | * The KVM_REG_ARM64_SVE regs must be used instead of | 465 | int size = core_reg_size_from_offset(vcpu, i); |
461 | * KVM_REG_ARM_CORE for accessing the FPSIMD V-registers on | 466 | |
462 | * SVE-enabled vcpus: | 467 | if (size < 0) |
463 | */ | 468 | continue; |
464 | if (vcpu_has_sve(vcpu) && core_reg_offset_is_vreg(i)) | 469 | |
470 | switch (size) { | ||
471 | case sizeof(__u32): | ||
472 | reg |= KVM_REG_SIZE_U32; | ||
473 | break; | ||
474 | |||
475 | case sizeof(__u64): | ||
476 | reg |= KVM_REG_SIZE_U64; | ||
477 | break; | ||
478 | |||
479 | case sizeof(__uint128_t): | ||
480 | reg |= KVM_REG_SIZE_U128; | ||
481 | break; | ||
482 | |||
483 | default: | ||
484 | WARN_ON(1); | ||
465 | continue; | 485 | continue; |
486 | } | ||
466 | 487 | ||
467 | if (uindices) { | 488 | if (uindices) { |
468 | if (put_user(core_reg | i, uindices)) | 489 | if (put_user(reg, uindices)) |
469 | return -EFAULT; | 490 | return -EFAULT; |
470 | uindices++; | 491 | uindices++; |
471 | } | 492 | } |
diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kvm.h index 7a0e64ccd6ff..d6ab5b4d15e5 100644 --- a/arch/x86/include/uapi/asm/kvm.h +++ b/arch/x86/include/uapi/asm/kvm.h | |||
@@ -383,6 +383,9 @@ struct kvm_sync_regs { | |||
383 | #define KVM_X86_QUIRK_LAPIC_MMIO_HOLE (1 << 2) | 383 | #define KVM_X86_QUIRK_LAPIC_MMIO_HOLE (1 << 2) |
384 | #define KVM_X86_QUIRK_OUT_7E_INC_RIP (1 << 3) | 384 | #define KVM_X86_QUIRK_OUT_7E_INC_RIP (1 << 3) |
385 | 385 | ||
386 | #define KVM_STATE_NESTED_FORMAT_VMX 0 | ||
387 | #define KVM_STATE_NESTED_FORMAT_SVM 1 /* unused */ | ||
388 | |||
386 | #define KVM_STATE_NESTED_GUEST_MODE 0x00000001 | 389 | #define KVM_STATE_NESTED_GUEST_MODE 0x00000001 |
387 | #define KVM_STATE_NESTED_RUN_PENDING 0x00000002 | 390 | #define KVM_STATE_NESTED_RUN_PENDING 0x00000002 |
388 | #define KVM_STATE_NESTED_EVMCS 0x00000004 | 391 | #define KVM_STATE_NESTED_EVMCS 0x00000004 |
@@ -390,9 +393,16 @@ struct kvm_sync_regs { | |||
390 | #define KVM_STATE_NESTED_SMM_GUEST_MODE 0x00000001 | 393 | #define KVM_STATE_NESTED_SMM_GUEST_MODE 0x00000001 |
391 | #define KVM_STATE_NESTED_SMM_VMXON 0x00000002 | 394 | #define KVM_STATE_NESTED_SMM_VMXON 0x00000002 |
392 | 395 | ||
393 | struct kvm_vmx_nested_state { | 396 | #define KVM_STATE_NESTED_VMX_VMCS_SIZE 0x1000 |
397 | |||
398 | struct kvm_vmx_nested_state_data { | ||
399 | __u8 vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE]; | ||
400 | __u8 shadow_vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE]; | ||
401 | }; | ||
402 | |||
403 | struct kvm_vmx_nested_state_hdr { | ||
394 | __u64 vmxon_pa; | 404 | __u64 vmxon_pa; |
395 | __u64 vmcs_pa; | 405 | __u64 vmcs12_pa; |
396 | 406 | ||
397 | struct { | 407 | struct { |
398 | __u16 flags; | 408 | __u16 flags; |
@@ -401,24 +411,25 @@ struct kvm_vmx_nested_state { | |||
401 | 411 | ||
402 | /* for KVM_CAP_NESTED_STATE */ | 412 | /* for KVM_CAP_NESTED_STATE */ |
403 | struct kvm_nested_state { | 413 | struct kvm_nested_state { |
404 | /* KVM_STATE_* flags */ | ||
405 | __u16 flags; | 414 | __u16 flags; |
406 | |||
407 | /* 0 for VMX, 1 for SVM. */ | ||
408 | __u16 format; | 415 | __u16 format; |
409 | |||
410 | /* 128 for SVM, 128 + VMCS size for VMX. */ | ||
411 | __u32 size; | 416 | __u32 size; |
412 | 417 | ||
413 | union { | 418 | union { |
414 | /* VMXON, VMCS */ | 419 | struct kvm_vmx_nested_state_hdr vmx; |
415 | struct kvm_vmx_nested_state vmx; | ||
416 | 420 | ||
417 | /* Pad the header to 128 bytes. */ | 421 | /* Pad the header to 128 bytes. */ |
418 | __u8 pad[120]; | 422 | __u8 pad[120]; |
419 | }; | 423 | } hdr; |
420 | 424 | ||
421 | __u8 data[0]; | 425 | /* |
426 | * Define data region as 0 bytes to preserve backwards-compatability | ||
427 | * to old definition of kvm_nested_state in order to avoid changing | ||
428 | * KVM_{GET,PUT}_NESTED_STATE ioctl values. | ||
429 | */ | ||
430 | union { | ||
431 | struct kvm_vmx_nested_state_data vmx[0]; | ||
432 | } data; | ||
422 | }; | 433 | }; |
423 | 434 | ||
424 | #endif /* _ASM_X86_KVM_H */ | 435 | #endif /* _ASM_X86_KVM_H */ |
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 1e9ba81accba..d3c3d5e5ffd4 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c | |||
@@ -5602,14 +5602,18 @@ static int alloc_mmu_pages(struct kvm_vcpu *vcpu) | |||
5602 | struct page *page; | 5602 | struct page *page; |
5603 | int i; | 5603 | int i; |
5604 | 5604 | ||
5605 | if (tdp_enabled) | ||
5606 | return 0; | ||
5607 | |||
5608 | /* | 5605 | /* |
5609 | * When emulating 32-bit mode, cr3 is only 32 bits even on x86_64. | 5606 | * When using PAE paging, the four PDPTEs are treated as 'root' pages, |
5610 | * Therefore we need to allocate shadow page tables in the first | 5607 | * while the PDP table is a per-vCPU construct that's allocated at MMU |
5611 | * 4GB of memory, which happens to fit the DMA32 zone. | 5608 | * creation. When emulating 32-bit mode, cr3 is only 32 bits even on |
5609 | * x86_64. Therefore we need to allocate the PDP table in the first | ||
5610 | * 4GB of memory, which happens to fit the DMA32 zone. Except for | ||
5611 | * SVM's 32-bit NPT support, TDP paging doesn't use PAE paging and can | ||
5612 | * skip allocating the PDP table. | ||
5612 | */ | 5613 | */ |
5614 | if (tdp_enabled && kvm_x86_ops->get_tdp_level(vcpu) > PT32E_ROOT_LEVEL) | ||
5615 | return 0; | ||
5616 | |||
5613 | page = alloc_page(GFP_KERNEL_ACCOUNT | __GFP_DMA32); | 5617 | page = alloc_page(GFP_KERNEL_ACCOUNT | __GFP_DMA32); |
5614 | if (!page) | 5618 | if (!page) |
5615 | return -ENOMEM; | 5619 | return -ENOMEM; |
diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 1032f068f0b9..5f9c1a200201 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c | |||
@@ -1397,7 +1397,7 @@ static int copy_enlightened_to_vmcs12(struct vcpu_vmx *vmx) | |||
1397 | } | 1397 | } |
1398 | 1398 | ||
1399 | if (unlikely(!(evmcs->hv_clean_fields & | 1399 | if (unlikely(!(evmcs->hv_clean_fields & |
1400 | HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_PROC))) { | 1400 | HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_EXCPN))) { |
1401 | vmcs12->exception_bitmap = evmcs->exception_bitmap; | 1401 | vmcs12->exception_bitmap = evmcs->exception_bitmap; |
1402 | } | 1402 | } |
1403 | 1403 | ||
@@ -1437,7 +1437,7 @@ static int copy_enlightened_to_vmcs12(struct vcpu_vmx *vmx) | |||
1437 | } | 1437 | } |
1438 | 1438 | ||
1439 | if (unlikely(!(evmcs->hv_clean_fields & | 1439 | if (unlikely(!(evmcs->hv_clean_fields & |
1440 | HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_GRP1))) { | 1440 | HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_GRP1))) { |
1441 | vmcs12->pin_based_vm_exec_control = | 1441 | vmcs12->pin_based_vm_exec_control = |
1442 | evmcs->pin_based_vm_exec_control; | 1442 | evmcs->pin_based_vm_exec_control; |
1443 | vmcs12->vm_exit_controls = evmcs->vm_exit_controls; | 1443 | vmcs12->vm_exit_controls = evmcs->vm_exit_controls; |
@@ -5226,14 +5226,16 @@ static int vmx_get_nested_state(struct kvm_vcpu *vcpu, | |||
5226 | struct vmcs12 *vmcs12; | 5226 | struct vmcs12 *vmcs12; |
5227 | struct kvm_nested_state kvm_state = { | 5227 | struct kvm_nested_state kvm_state = { |
5228 | .flags = 0, | 5228 | .flags = 0, |
5229 | .format = 0, | 5229 | .format = KVM_STATE_NESTED_FORMAT_VMX, |
5230 | .size = sizeof(kvm_state), | 5230 | .size = sizeof(kvm_state), |
5231 | .vmx.vmxon_pa = -1ull, | 5231 | .hdr.vmx.vmxon_pa = -1ull, |
5232 | .vmx.vmcs_pa = -1ull, | 5232 | .hdr.vmx.vmcs12_pa = -1ull, |
5233 | }; | 5233 | }; |
5234 | struct kvm_vmx_nested_state_data __user *user_vmx_nested_state = | ||
5235 | &user_kvm_nested_state->data.vmx[0]; | ||
5234 | 5236 | ||
5235 | if (!vcpu) | 5237 | if (!vcpu) |
5236 | return kvm_state.size + 2 * VMCS12_SIZE; | 5238 | return kvm_state.size + sizeof(*user_vmx_nested_state); |
5237 | 5239 | ||
5238 | vmx = to_vmx(vcpu); | 5240 | vmx = to_vmx(vcpu); |
5239 | vmcs12 = get_vmcs12(vcpu); | 5241 | vmcs12 = get_vmcs12(vcpu); |
@@ -5243,23 +5245,23 @@ static int vmx_get_nested_state(struct kvm_vcpu *vcpu, | |||
5243 | 5245 | ||
5244 | if (nested_vmx_allowed(vcpu) && | 5246 | if (nested_vmx_allowed(vcpu) && |
5245 | (vmx->nested.vmxon || vmx->nested.smm.vmxon)) { | 5247 | (vmx->nested.vmxon || vmx->nested.smm.vmxon)) { |
5246 | kvm_state.vmx.vmxon_pa = vmx->nested.vmxon_ptr; | 5248 | kvm_state.hdr.vmx.vmxon_pa = vmx->nested.vmxon_ptr; |
5247 | kvm_state.vmx.vmcs_pa = vmx->nested.current_vmptr; | 5249 | kvm_state.hdr.vmx.vmcs12_pa = vmx->nested.current_vmptr; |
5248 | 5250 | ||
5249 | if (vmx_has_valid_vmcs12(vcpu)) { | 5251 | if (vmx_has_valid_vmcs12(vcpu)) { |
5250 | kvm_state.size += VMCS12_SIZE; | 5252 | kvm_state.size += sizeof(user_vmx_nested_state->vmcs12); |
5251 | 5253 | ||
5252 | if (is_guest_mode(vcpu) && | 5254 | if (is_guest_mode(vcpu) && |
5253 | nested_cpu_has_shadow_vmcs(vmcs12) && | 5255 | nested_cpu_has_shadow_vmcs(vmcs12) && |
5254 | vmcs12->vmcs_link_pointer != -1ull) | 5256 | vmcs12->vmcs_link_pointer != -1ull) |
5255 | kvm_state.size += VMCS12_SIZE; | 5257 | kvm_state.size += sizeof(user_vmx_nested_state->shadow_vmcs12); |
5256 | } | 5258 | } |
5257 | 5259 | ||
5258 | if (vmx->nested.smm.vmxon) | 5260 | if (vmx->nested.smm.vmxon) |
5259 | kvm_state.vmx.smm.flags |= KVM_STATE_NESTED_SMM_VMXON; | 5261 | kvm_state.hdr.vmx.smm.flags |= KVM_STATE_NESTED_SMM_VMXON; |
5260 | 5262 | ||
5261 | if (vmx->nested.smm.guest_mode) | 5263 | if (vmx->nested.smm.guest_mode) |
5262 | kvm_state.vmx.smm.flags |= KVM_STATE_NESTED_SMM_GUEST_MODE; | 5264 | kvm_state.hdr.vmx.smm.flags |= KVM_STATE_NESTED_SMM_GUEST_MODE; |
5263 | 5265 | ||
5264 | if (is_guest_mode(vcpu)) { | 5266 | if (is_guest_mode(vcpu)) { |
5265 | kvm_state.flags |= KVM_STATE_NESTED_GUEST_MODE; | 5267 | kvm_state.flags |= KVM_STATE_NESTED_GUEST_MODE; |
@@ -5294,16 +5296,19 @@ static int vmx_get_nested_state(struct kvm_vcpu *vcpu, | |||
5294 | copy_shadow_to_vmcs12(vmx); | 5296 | copy_shadow_to_vmcs12(vmx); |
5295 | } | 5297 | } |
5296 | 5298 | ||
5299 | BUILD_BUG_ON(sizeof(user_vmx_nested_state->vmcs12) < VMCS12_SIZE); | ||
5300 | BUILD_BUG_ON(sizeof(user_vmx_nested_state->shadow_vmcs12) < VMCS12_SIZE); | ||
5301 | |||
5297 | /* | 5302 | /* |
5298 | * Copy over the full allocated size of vmcs12 rather than just the size | 5303 | * Copy over the full allocated size of vmcs12 rather than just the size |
5299 | * of the struct. | 5304 | * of the struct. |
5300 | */ | 5305 | */ |
5301 | if (copy_to_user(user_kvm_nested_state->data, vmcs12, VMCS12_SIZE)) | 5306 | if (copy_to_user(user_vmx_nested_state->vmcs12, vmcs12, VMCS12_SIZE)) |
5302 | return -EFAULT; | 5307 | return -EFAULT; |
5303 | 5308 | ||
5304 | if (nested_cpu_has_shadow_vmcs(vmcs12) && | 5309 | if (nested_cpu_has_shadow_vmcs(vmcs12) && |
5305 | vmcs12->vmcs_link_pointer != -1ull) { | 5310 | vmcs12->vmcs_link_pointer != -1ull) { |
5306 | if (copy_to_user(user_kvm_nested_state->data + VMCS12_SIZE, | 5311 | if (copy_to_user(user_vmx_nested_state->shadow_vmcs12, |
5307 | get_shadow_vmcs12(vcpu), VMCS12_SIZE)) | 5312 | get_shadow_vmcs12(vcpu), VMCS12_SIZE)) |
5308 | return -EFAULT; | 5313 | return -EFAULT; |
5309 | } | 5314 | } |
@@ -5331,33 +5336,35 @@ static int vmx_set_nested_state(struct kvm_vcpu *vcpu, | |||
5331 | struct vcpu_vmx *vmx = to_vmx(vcpu); | 5336 | struct vcpu_vmx *vmx = to_vmx(vcpu); |
5332 | struct vmcs12 *vmcs12; | 5337 | struct vmcs12 *vmcs12; |
5333 | u32 exit_qual; | 5338 | u32 exit_qual; |
5339 | struct kvm_vmx_nested_state_data __user *user_vmx_nested_state = | ||
5340 | &user_kvm_nested_state->data.vmx[0]; | ||
5334 | int ret; | 5341 | int ret; |
5335 | 5342 | ||
5336 | if (kvm_state->format != 0) | 5343 | if (kvm_state->format != KVM_STATE_NESTED_FORMAT_VMX) |
5337 | return -EINVAL; | 5344 | return -EINVAL; |
5338 | 5345 | ||
5339 | if (!nested_vmx_allowed(vcpu)) | 5346 | if (kvm_state->hdr.vmx.vmxon_pa == -1ull) { |
5340 | return kvm_state->vmx.vmxon_pa == -1ull ? 0 : -EINVAL; | 5347 | if (kvm_state->hdr.vmx.smm.flags) |
5341 | |||
5342 | if (kvm_state->vmx.vmxon_pa == -1ull) { | ||
5343 | if (kvm_state->vmx.smm.flags) | ||
5344 | return -EINVAL; | 5348 | return -EINVAL; |
5345 | 5349 | ||
5346 | if (kvm_state->vmx.vmcs_pa != -1ull) | 5350 | if (kvm_state->hdr.vmx.vmcs12_pa != -1ull) |
5347 | return -EINVAL; | 5351 | return -EINVAL; |
5348 | 5352 | ||
5349 | vmx_leave_nested(vcpu); | 5353 | if (kvm_state->flags & ~KVM_STATE_NESTED_EVMCS) |
5350 | return 0; | 5354 | return -EINVAL; |
5351 | } | 5355 | } else { |
5356 | if (!nested_vmx_allowed(vcpu)) | ||
5357 | return -EINVAL; | ||
5352 | 5358 | ||
5353 | if (!page_address_valid(vcpu, kvm_state->vmx.vmxon_pa)) | 5359 | if (!page_address_valid(vcpu, kvm_state->hdr.vmx.vmxon_pa)) |
5354 | return -EINVAL; | 5360 | return -EINVAL; |
5361 | } | ||
5355 | 5362 | ||
5356 | if ((kvm_state->vmx.smm.flags & KVM_STATE_NESTED_SMM_GUEST_MODE) && | 5363 | if ((kvm_state->hdr.vmx.smm.flags & KVM_STATE_NESTED_SMM_GUEST_MODE) && |
5357 | (kvm_state->flags & KVM_STATE_NESTED_GUEST_MODE)) | 5364 | (kvm_state->flags & KVM_STATE_NESTED_GUEST_MODE)) |
5358 | return -EINVAL; | 5365 | return -EINVAL; |
5359 | 5366 | ||
5360 | if (kvm_state->vmx.smm.flags & | 5367 | if (kvm_state->hdr.vmx.smm.flags & |
5361 | ~(KVM_STATE_NESTED_SMM_GUEST_MODE | KVM_STATE_NESTED_SMM_VMXON)) | 5368 | ~(KVM_STATE_NESTED_SMM_GUEST_MODE | KVM_STATE_NESTED_SMM_VMXON)) |
5362 | return -EINVAL; | 5369 | return -EINVAL; |
5363 | 5370 | ||
@@ -5366,21 +5373,25 @@ static int vmx_set_nested_state(struct kvm_vcpu *vcpu, | |||
5366 | * nor can VMLAUNCH/VMRESUME be pending. Outside SMM, SMM flags | 5373 | * nor can VMLAUNCH/VMRESUME be pending. Outside SMM, SMM flags |
5367 | * must be zero. | 5374 | * must be zero. |
5368 | */ | 5375 | */ |
5369 | if (is_smm(vcpu) ? kvm_state->flags : kvm_state->vmx.smm.flags) | 5376 | if (is_smm(vcpu) ? kvm_state->flags : kvm_state->hdr.vmx.smm.flags) |
5370 | return -EINVAL; | 5377 | return -EINVAL; |
5371 | 5378 | ||
5372 | if ((kvm_state->vmx.smm.flags & KVM_STATE_NESTED_SMM_GUEST_MODE) && | 5379 | if ((kvm_state->hdr.vmx.smm.flags & KVM_STATE_NESTED_SMM_GUEST_MODE) && |
5373 | !(kvm_state->vmx.smm.flags & KVM_STATE_NESTED_SMM_VMXON)) | 5380 | !(kvm_state->hdr.vmx.smm.flags & KVM_STATE_NESTED_SMM_VMXON)) |
5374 | return -EINVAL; | 5381 | return -EINVAL; |
5375 | 5382 | ||
5376 | vmx_leave_nested(vcpu); | 5383 | vmx_leave_nested(vcpu); |
5377 | if (kvm_state->vmx.vmxon_pa == -1ull) | 5384 | if (kvm_state->flags & KVM_STATE_NESTED_EVMCS) { |
5378 | return 0; | 5385 | if (!nested_vmx_allowed(vcpu)) |
5386 | return -EINVAL; | ||
5379 | 5387 | ||
5380 | if (kvm_state->flags & KVM_STATE_NESTED_EVMCS) | ||
5381 | nested_enable_evmcs(vcpu, NULL); | 5388 | nested_enable_evmcs(vcpu, NULL); |
5389 | } | ||
5390 | |||
5391 | if (kvm_state->hdr.vmx.vmxon_pa == -1ull) | ||
5392 | return 0; | ||
5382 | 5393 | ||
5383 | vmx->nested.vmxon_ptr = kvm_state->vmx.vmxon_pa; | 5394 | vmx->nested.vmxon_ptr = kvm_state->hdr.vmx.vmxon_pa; |
5384 | ret = enter_vmx_operation(vcpu); | 5395 | ret = enter_vmx_operation(vcpu); |
5385 | if (ret) | 5396 | if (ret) |
5386 | return ret; | 5397 | return ret; |
@@ -5389,12 +5400,12 @@ static int vmx_set_nested_state(struct kvm_vcpu *vcpu, | |||
5389 | if (kvm_state->size < sizeof(*kvm_state) + sizeof(*vmcs12)) | 5400 | if (kvm_state->size < sizeof(*kvm_state) + sizeof(*vmcs12)) |
5390 | return 0; | 5401 | return 0; |
5391 | 5402 | ||
5392 | if (kvm_state->vmx.vmcs_pa != -1ull) { | 5403 | if (kvm_state->hdr.vmx.vmcs12_pa != -1ull) { |
5393 | if (kvm_state->vmx.vmcs_pa == kvm_state->vmx.vmxon_pa || | 5404 | if (kvm_state->hdr.vmx.vmcs12_pa == kvm_state->hdr.vmx.vmxon_pa || |
5394 | !page_address_valid(vcpu, kvm_state->vmx.vmcs_pa)) | 5405 | !page_address_valid(vcpu, kvm_state->hdr.vmx.vmcs12_pa)) |
5395 | return -EINVAL; | 5406 | return -EINVAL; |
5396 | 5407 | ||
5397 | set_current_vmptr(vmx, kvm_state->vmx.vmcs_pa); | 5408 | set_current_vmptr(vmx, kvm_state->hdr.vmx.vmcs12_pa); |
5398 | } else if (kvm_state->flags & KVM_STATE_NESTED_EVMCS) { | 5409 | } else if (kvm_state->flags & KVM_STATE_NESTED_EVMCS) { |
5399 | /* | 5410 | /* |
5400 | * Sync eVMCS upon entry as we may not have | 5411 | * Sync eVMCS upon entry as we may not have |
@@ -5405,16 +5416,16 @@ static int vmx_set_nested_state(struct kvm_vcpu *vcpu, | |||
5405 | return -EINVAL; | 5416 | return -EINVAL; |
5406 | } | 5417 | } |
5407 | 5418 | ||
5408 | if (kvm_state->vmx.smm.flags & KVM_STATE_NESTED_SMM_VMXON) { | 5419 | if (kvm_state->hdr.vmx.smm.flags & KVM_STATE_NESTED_SMM_VMXON) { |
5409 | vmx->nested.smm.vmxon = true; | 5420 | vmx->nested.smm.vmxon = true; |
5410 | vmx->nested.vmxon = false; | 5421 | vmx->nested.vmxon = false; |
5411 | 5422 | ||
5412 | if (kvm_state->vmx.smm.flags & KVM_STATE_NESTED_SMM_GUEST_MODE) | 5423 | if (kvm_state->hdr.vmx.smm.flags & KVM_STATE_NESTED_SMM_GUEST_MODE) |
5413 | vmx->nested.smm.guest_mode = true; | 5424 | vmx->nested.smm.guest_mode = true; |
5414 | } | 5425 | } |
5415 | 5426 | ||
5416 | vmcs12 = get_vmcs12(vcpu); | 5427 | vmcs12 = get_vmcs12(vcpu); |
5417 | if (copy_from_user(vmcs12, user_kvm_nested_state->data, sizeof(*vmcs12))) | 5428 | if (copy_from_user(vmcs12, user_vmx_nested_state->vmcs12, sizeof(*vmcs12))) |
5418 | return -EFAULT; | 5429 | return -EFAULT; |
5419 | 5430 | ||
5420 | if (vmcs12->hdr.revision_id != VMCS12_REVISION) | 5431 | if (vmcs12->hdr.revision_id != VMCS12_REVISION) |
@@ -5431,12 +5442,14 @@ static int vmx_set_nested_state(struct kvm_vcpu *vcpu, | |||
5431 | vmcs12->vmcs_link_pointer != -1ull) { | 5442 | vmcs12->vmcs_link_pointer != -1ull) { |
5432 | struct vmcs12 *shadow_vmcs12 = get_shadow_vmcs12(vcpu); | 5443 | struct vmcs12 *shadow_vmcs12 = get_shadow_vmcs12(vcpu); |
5433 | 5444 | ||
5434 | if (kvm_state->size < sizeof(*kvm_state) + VMCS12_SIZE + sizeof(*vmcs12)) | 5445 | if (kvm_state->size < |
5446 | sizeof(*kvm_state) + | ||
5447 | sizeof(user_vmx_nested_state->vmcs12) + sizeof(*shadow_vmcs12)) | ||
5435 | goto error_guest_mode; | 5448 | goto error_guest_mode; |
5436 | 5449 | ||
5437 | if (copy_from_user(shadow_vmcs12, | 5450 | if (copy_from_user(shadow_vmcs12, |
5438 | user_kvm_nested_state->data + VMCS12_SIZE, | 5451 | user_vmx_nested_state->shadow_vmcs12, |
5439 | sizeof(*vmcs12))) { | 5452 | sizeof(*shadow_vmcs12))) { |
5440 | ret = -EFAULT; | 5453 | ret = -EFAULT; |
5441 | goto error_guest_mode; | 5454 | goto error_guest_mode; |
5442 | } | 5455 | } |
diff --git a/arch/x86/kvm/vmx/vmcs12.h b/arch/x86/kvm/vmx/vmcs12.h index 3a742428ad17..337718fc8a36 100644 --- a/arch/x86/kvm/vmx/vmcs12.h +++ b/arch/x86/kvm/vmx/vmcs12.h | |||
@@ -201,9 +201,10 @@ struct __packed vmcs12 { | |||
201 | /* | 201 | /* |
202 | * VMCS12_SIZE is the number of bytes L1 should allocate for the VMXON region | 202 | * VMCS12_SIZE is the number of bytes L1 should allocate for the VMXON region |
203 | * and any VMCS region. Although only sizeof(struct vmcs12) are used by the | 203 | * and any VMCS region. Although only sizeof(struct vmcs12) are used by the |
204 | * current implementation, 4K are reserved to avoid future complications. | 204 | * current implementation, 4K are reserved to avoid future complications and |
205 | * to preserve userspace ABI. | ||
205 | */ | 206 | */ |
206 | #define VMCS12_SIZE 0x1000 | 207 | #define VMCS12_SIZE KVM_STATE_NESTED_VMX_VMCS_SIZE |
207 | 208 | ||
208 | /* | 209 | /* |
209 | * VMCS12_MAX_FIELD_INDEX is the highest index value used in any | 210 | * VMCS12_MAX_FIELD_INDEX is the highest index value used in any |
diff --git a/tools/arch/x86/include/uapi/asm/kvm.h b/tools/arch/x86/include/uapi/asm/kvm.h index 7a0e64ccd6ff..24a8cd229df6 100644 --- a/tools/arch/x86/include/uapi/asm/kvm.h +++ b/tools/arch/x86/include/uapi/asm/kvm.h | |||
@@ -392,7 +392,7 @@ struct kvm_sync_regs { | |||
392 | 392 | ||
393 | struct kvm_vmx_nested_state { | 393 | struct kvm_vmx_nested_state { |
394 | __u64 vmxon_pa; | 394 | __u64 vmxon_pa; |
395 | __u64 vmcs_pa; | 395 | __u64 vmcs12_pa; |
396 | 396 | ||
397 | struct { | 397 | struct { |
398 | __u16 flags; | 398 | __u16 flags; |
diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftests/kvm/.gitignore index df1bf9230a74..41266af0d3dc 100644 --- a/tools/testing/selftests/kvm/.gitignore +++ b/tools/testing/selftests/kvm/.gitignore | |||
@@ -2,6 +2,7 @@ | |||
2 | /x86_64/evmcs_test | 2 | /x86_64/evmcs_test |
3 | /x86_64/hyperv_cpuid | 3 | /x86_64/hyperv_cpuid |
4 | /x86_64/kvm_create_max_vcpus | 4 | /x86_64/kvm_create_max_vcpus |
5 | /x86_64/mmio_warning_test | ||
5 | /x86_64/platform_info_test | 6 | /x86_64/platform_info_test |
6 | /x86_64/set_sregs_test | 7 | /x86_64/set_sregs_test |
7 | /x86_64/smm_test | 8 | /x86_64/smm_test |
diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile index 41280dc06297..62afd0b43074 100644 --- a/tools/testing/selftests/kvm/Makefile +++ b/tools/testing/selftests/kvm/Makefile | |||
@@ -11,23 +11,24 @@ LIBKVM = lib/assert.c lib/elf.c lib/io.c lib/kvm_util.c lib/ucall.c lib/sparsebi | |||
11 | LIBKVM_x86_64 = lib/x86_64/processor.c lib/x86_64/vmx.c | 11 | LIBKVM_x86_64 = lib/x86_64/processor.c lib/x86_64/vmx.c |
12 | LIBKVM_aarch64 = lib/aarch64/processor.c | 12 | LIBKVM_aarch64 = lib/aarch64/processor.c |
13 | 13 | ||
14 | TEST_GEN_PROGS_x86_64 = x86_64/platform_info_test | 14 | TEST_GEN_PROGS_x86_64 = x86_64/cr4_cpuid_sync_test |
15 | TEST_GEN_PROGS_x86_64 += x86_64/set_sregs_test | ||
16 | TEST_GEN_PROGS_x86_64 += x86_64/sync_regs_test | ||
17 | TEST_GEN_PROGS_x86_64 += x86_64/vmx_tsc_adjust_test | ||
18 | TEST_GEN_PROGS_x86_64 += x86_64/cr4_cpuid_sync_test | ||
19 | TEST_GEN_PROGS_x86_64 += x86_64/state_test | ||
20 | TEST_GEN_PROGS_x86_64 += x86_64/evmcs_test | 15 | TEST_GEN_PROGS_x86_64 += x86_64/evmcs_test |
21 | TEST_GEN_PROGS_x86_64 += x86_64/hyperv_cpuid | 16 | TEST_GEN_PROGS_x86_64 += x86_64/hyperv_cpuid |
22 | TEST_GEN_PROGS_x86_64 += x86_64/vmx_close_while_nested_test | ||
23 | TEST_GEN_PROGS_x86_64 += x86_64/smm_test | ||
24 | TEST_GEN_PROGS_x86_64 += x86_64/kvm_create_max_vcpus | 17 | TEST_GEN_PROGS_x86_64 += x86_64/kvm_create_max_vcpus |
18 | TEST_GEN_PROGS_x86_64 += x86_64/mmio_warning_test | ||
19 | TEST_GEN_PROGS_x86_64 += x86_64/platform_info_test | ||
20 | TEST_GEN_PROGS_x86_64 += x86_64/set_sregs_test | ||
21 | TEST_GEN_PROGS_x86_64 += x86_64/smm_test | ||
22 | TEST_GEN_PROGS_x86_64 += x86_64/state_test | ||
23 | TEST_GEN_PROGS_x86_64 += x86_64/sync_regs_test | ||
24 | TEST_GEN_PROGS_x86_64 += x86_64/vmx_close_while_nested_test | ||
25 | TEST_GEN_PROGS_x86_64 += x86_64/vmx_set_nested_state_test | 25 | TEST_GEN_PROGS_x86_64 += x86_64/vmx_set_nested_state_test |
26 | TEST_GEN_PROGS_x86_64 += dirty_log_test | 26 | TEST_GEN_PROGS_x86_64 += x86_64/vmx_tsc_adjust_test |
27 | TEST_GEN_PROGS_x86_64 += clear_dirty_log_test | 27 | TEST_GEN_PROGS_x86_64 += clear_dirty_log_test |
28 | TEST_GEN_PROGS_x86_64 += dirty_log_test | ||
28 | 29 | ||
29 | TEST_GEN_PROGS_aarch64 += dirty_log_test | ||
30 | TEST_GEN_PROGS_aarch64 += clear_dirty_log_test | 30 | TEST_GEN_PROGS_aarch64 += clear_dirty_log_test |
31 | TEST_GEN_PROGS_aarch64 += dirty_log_test | ||
31 | 32 | ||
32 | TEST_GEN_PROGS += $(TEST_GEN_PROGS_$(UNAME_M)) | 33 | TEST_GEN_PROGS += $(TEST_GEN_PROGS_$(UNAME_M)) |
33 | LIBKVM += $(LIBKVM_$(UNAME_M)) | 34 | LIBKVM += $(LIBKVM_$(UNAME_M)) |
diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h index a5a4b28f14d8..bd8eb5579028 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h | |||
@@ -139,6 +139,8 @@ struct kvm_vm *vm_create_default(uint32_t vcpuid, uint64_t extra_mem_size, | |||
139 | void *guest_code); | 139 | void *guest_code); |
140 | void vm_vcpu_add_default(struct kvm_vm *vm, uint32_t vcpuid, void *guest_code); | 140 | void vm_vcpu_add_default(struct kvm_vm *vm, uint32_t vcpuid, void *guest_code); |
141 | 141 | ||
142 | bool vm_is_unrestricted_guest(struct kvm_vm *vm); | ||
143 | |||
142 | struct kvm_userspace_memory_region * | 144 | struct kvm_userspace_memory_region * |
143 | kvm_userspace_memory_region_find(struct kvm_vm *vm, uint64_t start, | 145 | kvm_userspace_memory_region_find(struct kvm_vm *vm, uint64_t start, |
144 | uint64_t end); | 146 | uint64_t end); |
diff --git a/tools/testing/selftests/kvm/include/x86_64/processor.h b/tools/testing/selftests/kvm/include/x86_64/processor.h index 6063d5b2f356..af4d26de32d1 100644 --- a/tools/testing/selftests/kvm/include/x86_64/processor.h +++ b/tools/testing/selftests/kvm/include/x86_64/processor.h | |||
@@ -303,6 +303,8 @@ static inline unsigned long get_xmm(int n) | |||
303 | return 0; | 303 | return 0; |
304 | } | 304 | } |
305 | 305 | ||
306 | bool is_intel_cpu(void); | ||
307 | |||
306 | struct kvm_x86_state; | 308 | struct kvm_x86_state; |
307 | struct kvm_x86_state *vcpu_save_state(struct kvm_vm *vm, uint32_t vcpuid); | 309 | struct kvm_x86_state *vcpu_save_state(struct kvm_vm *vm, uint32_t vcpuid); |
308 | void vcpu_load_state(struct kvm_vm *vm, uint32_t vcpuid, | 310 | void vcpu_load_state(struct kvm_vm *vm, uint32_t vcpuid, |
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c index 633b22df46a4..267f2353e4ab 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c | |||
@@ -1583,3 +1583,39 @@ void *addr_gva2hva(struct kvm_vm *vm, vm_vaddr_t gva) | |||
1583 | { | 1583 | { |
1584 | return addr_gpa2hva(vm, addr_gva2gpa(vm, gva)); | 1584 | return addr_gpa2hva(vm, addr_gva2gpa(vm, gva)); |
1585 | } | 1585 | } |
1586 | |||
1587 | /* | ||
1588 | * Is Unrestricted Guest | ||
1589 | * | ||
1590 | * Input Args: | ||
1591 | * vm - Virtual Machine | ||
1592 | * | ||
1593 | * Output Args: None | ||
1594 | * | ||
1595 | * Return: True if the unrestricted guest is set to 'Y', otherwise return false. | ||
1596 | * | ||
1597 | * Check if the unrestricted guest flag is enabled. | ||
1598 | */ | ||
1599 | bool vm_is_unrestricted_guest(struct kvm_vm *vm) | ||
1600 | { | ||
1601 | char val = 'N'; | ||
1602 | size_t count; | ||
1603 | FILE *f; | ||
1604 | |||
1605 | if (vm == NULL) { | ||
1606 | /* Ensure that the KVM vendor-specific module is loaded. */ | ||
1607 | f = fopen(KVM_DEV_PATH, "r"); | ||
1608 | TEST_ASSERT(f != NULL, "Error in opening KVM dev file: %d", | ||
1609 | errno); | ||
1610 | fclose(f); | ||
1611 | } | ||
1612 | |||
1613 | f = fopen("/sys/module/kvm_intel/parameters/unrestricted_guest", "r"); | ||
1614 | if (f) { | ||
1615 | count = fread(&val, sizeof(char), 1, f); | ||
1616 | TEST_ASSERT(count == 1, "Unable to read from param file."); | ||
1617 | fclose(f); | ||
1618 | } | ||
1619 | |||
1620 | return val == 'Y'; | ||
1621 | } | ||
diff --git a/tools/testing/selftests/kvm/lib/x86_64/processor.c b/tools/testing/selftests/kvm/lib/x86_64/processor.c index 21f3040d90cb..2fe78bdf3bee 100644 --- a/tools/testing/selftests/kvm/lib/x86_64/processor.c +++ b/tools/testing/selftests/kvm/lib/x86_64/processor.c | |||
@@ -1137,3 +1137,19 @@ void vcpu_load_state(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_x86_state *s | |||
1137 | r); | 1137 | r); |
1138 | } | 1138 | } |
1139 | } | 1139 | } |
1140 | |||
1141 | bool is_intel_cpu(void) | ||
1142 | { | ||
1143 | int eax, ebx, ecx, edx; | ||
1144 | const uint32_t *chunk; | ||
1145 | const int leaf = 0; | ||
1146 | |||
1147 | __asm__ __volatile__( | ||
1148 | "cpuid" | ||
1149 | : /* output */ "=a"(eax), "=b"(ebx), | ||
1150 | "=c"(ecx), "=d"(edx) | ||
1151 | : /* input */ "0"(leaf), "2"(0)); | ||
1152 | |||
1153 | chunk = (const uint32_t *)("GenuineIntel"); | ||
1154 | return (ebx == chunk[0] && edx == chunk[1] && ecx == chunk[2]); | ||
1155 | } | ||
diff --git a/tools/testing/selftests/kvm/x86_64/mmio_warning_test.c b/tools/testing/selftests/kvm/x86_64/mmio_warning_test.c new file mode 100644 index 000000000000..00bb97d76000 --- /dev/null +++ b/tools/testing/selftests/kvm/x86_64/mmio_warning_test.c | |||
@@ -0,0 +1,126 @@ | |||
1 | /* | ||
2 | * mmio_warning_test | ||
3 | * | ||
4 | * Copyright (C) 2019, Google LLC. | ||
5 | * | ||
6 | * This work is licensed under the terms of the GNU GPL, version 2. | ||
7 | * | ||
8 | * Test that we don't get a kernel warning when we call KVM_RUN after a | ||
9 | * triple fault occurs. To get the triple fault to occur we call KVM_RUN | ||
10 | * on a VCPU that hasn't been properly setup. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #define _GNU_SOURCE | ||
15 | #include <fcntl.h> | ||
16 | #include <kvm_util.h> | ||
17 | #include <linux/kvm.h> | ||
18 | #include <processor.h> | ||
19 | #include <pthread.h> | ||
20 | #include <stdio.h> | ||
21 | #include <stdlib.h> | ||
22 | #include <string.h> | ||
23 | #include <sys/ioctl.h> | ||
24 | #include <sys/mman.h> | ||
25 | #include <sys/stat.h> | ||
26 | #include <sys/types.h> | ||
27 | #include <sys/wait.h> | ||
28 | #include <test_util.h> | ||
29 | #include <unistd.h> | ||
30 | |||
31 | #define NTHREAD 4 | ||
32 | #define NPROCESS 5 | ||
33 | |||
34 | struct thread_context { | ||
35 | int kvmcpu; | ||
36 | struct kvm_run *run; | ||
37 | }; | ||
38 | |||
39 | void *thr(void *arg) | ||
40 | { | ||
41 | struct thread_context *tc = (struct thread_context *)arg; | ||
42 | int res; | ||
43 | int kvmcpu = tc->kvmcpu; | ||
44 | struct kvm_run *run = tc->run; | ||
45 | |||
46 | res = ioctl(kvmcpu, KVM_RUN, 0); | ||
47 | printf("ret1=%d exit_reason=%d suberror=%d\n", | ||
48 | res, run->exit_reason, run->internal.suberror); | ||
49 | |||
50 | return 0; | ||
51 | } | ||
52 | |||
53 | void test(void) | ||
54 | { | ||
55 | int i, kvm, kvmvm, kvmcpu; | ||
56 | pthread_t th[NTHREAD]; | ||
57 | struct kvm_run *run; | ||
58 | struct thread_context tc; | ||
59 | |||
60 | kvm = open("/dev/kvm", O_RDWR); | ||
61 | TEST_ASSERT(kvm != -1, "failed to open /dev/kvm"); | ||
62 | kvmvm = ioctl(kvm, KVM_CREATE_VM, 0); | ||
63 | TEST_ASSERT(kvmvm != -1, "KVM_CREATE_VM failed"); | ||
64 | kvmcpu = ioctl(kvmvm, KVM_CREATE_VCPU, 0); | ||
65 | TEST_ASSERT(kvmcpu != -1, "KVM_CREATE_VCPU failed"); | ||
66 | run = (struct kvm_run *)mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, | ||
67 | kvmcpu, 0); | ||
68 | tc.kvmcpu = kvmcpu; | ||
69 | tc.run = run; | ||
70 | srand(getpid()); | ||
71 | for (i = 0; i < NTHREAD; i++) { | ||
72 | pthread_create(&th[i], NULL, thr, (void *)(uintptr_t)&tc); | ||
73 | usleep(rand() % 10000); | ||
74 | } | ||
75 | for (i = 0; i < NTHREAD; i++) | ||
76 | pthread_join(th[i], NULL); | ||
77 | } | ||
78 | |||
79 | int get_warnings_count(void) | ||
80 | { | ||
81 | int warnings; | ||
82 | FILE *f; | ||
83 | |||
84 | f = popen("dmesg | grep \"WARNING:\" | wc -l", "r"); | ||
85 | fscanf(f, "%d", &warnings); | ||
86 | fclose(f); | ||
87 | |||
88 | return warnings; | ||
89 | } | ||
90 | |||
91 | int main(void) | ||
92 | { | ||
93 | int warnings_before, warnings_after; | ||
94 | |||
95 | if (!is_intel_cpu()) { | ||
96 | printf("Must be run on an Intel CPU, skipping test\n"); | ||
97 | exit(KSFT_SKIP); | ||
98 | } | ||
99 | |||
100 | if (vm_is_unrestricted_guest(NULL)) { | ||
101 | printf("Unrestricted guest must be disabled, skipping test\n"); | ||
102 | exit(KSFT_SKIP); | ||
103 | } | ||
104 | |||
105 | warnings_before = get_warnings_count(); | ||
106 | |||
107 | for (int i = 0; i < NPROCESS; ++i) { | ||
108 | int status; | ||
109 | int pid = fork(); | ||
110 | |||
111 | if (pid < 0) | ||
112 | exit(1); | ||
113 | if (pid == 0) { | ||
114 | test(); | ||
115 | exit(0); | ||
116 | } | ||
117 | while (waitpid(pid, &status, __WALL) != pid) | ||
118 | ; | ||
119 | } | ||
120 | |||
121 | warnings_after = get_warnings_count(); | ||
122 | TEST_ASSERT(warnings_before == warnings_after, | ||
123 | "Warnings found in kernel. Run 'dmesg' to inspect them."); | ||
124 | |||
125 | return 0; | ||
126 | } | ||
diff --git a/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c b/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c index 9d62e2c7e024..e64ca20b315a 100644 --- a/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c +++ b/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c | |||
@@ -75,7 +75,7 @@ void set_revision_id_for_vmcs12(struct kvm_nested_state *state, | |||
75 | u32 vmcs12_revision) | 75 | u32 vmcs12_revision) |
76 | { | 76 | { |
77 | /* Set revision_id in vmcs12 to vmcs12_revision. */ | 77 | /* Set revision_id in vmcs12 to vmcs12_revision. */ |
78 | memcpy(state->data, &vmcs12_revision, sizeof(u32)); | 78 | memcpy(&state->data, &vmcs12_revision, sizeof(u32)); |
79 | } | 79 | } |
80 | 80 | ||
81 | void set_default_state(struct kvm_nested_state *state) | 81 | void set_default_state(struct kvm_nested_state *state) |
@@ -95,9 +95,9 @@ void set_default_vmx_state(struct kvm_nested_state *state, int size) | |||
95 | KVM_STATE_NESTED_EVMCS; | 95 | KVM_STATE_NESTED_EVMCS; |
96 | state->format = 0; | 96 | state->format = 0; |
97 | state->size = size; | 97 | state->size = size; |
98 | state->vmx.vmxon_pa = 0x1000; | 98 | state->hdr.vmx.vmxon_pa = 0x1000; |
99 | state->vmx.vmcs_pa = 0x2000; | 99 | state->hdr.vmx.vmcs12_pa = 0x2000; |
100 | state->vmx.smm.flags = 0; | 100 | state->hdr.vmx.smm.flags = 0; |
101 | set_revision_id_for_vmcs12(state, VMCS12_REVISION); | 101 | set_revision_id_for_vmcs12(state, VMCS12_REVISION); |
102 | } | 102 | } |
103 | 103 | ||
@@ -123,39 +123,47 @@ void test_vmx_nested_state(struct kvm_vm *vm) | |||
123 | /* | 123 | /* |
124 | * We cannot virtualize anything if the guest does not have VMX | 124 | * We cannot virtualize anything if the guest does not have VMX |
125 | * enabled. We expect KVM_SET_NESTED_STATE to return 0 if vmxon_pa | 125 | * enabled. We expect KVM_SET_NESTED_STATE to return 0 if vmxon_pa |
126 | * is set to -1ull. | 126 | * is set to -1ull, but the flags must be zero. |
127 | */ | 127 | */ |
128 | set_default_vmx_state(state, state_sz); | 128 | set_default_vmx_state(state, state_sz); |
129 | state->vmx.vmxon_pa = -1ull; | 129 | state->hdr.vmx.vmxon_pa = -1ull; |
130 | test_nested_state_expect_einval(vm, state); | ||
131 | |||
132 | state->hdr.vmx.vmcs12_pa = -1ull; | ||
133 | state->flags = KVM_STATE_NESTED_EVMCS; | ||
134 | test_nested_state_expect_einval(vm, state); | ||
135 | |||
136 | state->flags = 0; | ||
130 | test_nested_state(vm, state); | 137 | test_nested_state(vm, state); |
131 | 138 | ||
132 | /* Enable VMX in the guest CPUID. */ | 139 | /* Enable VMX in the guest CPUID. */ |
133 | vcpu_set_cpuid(vm, VCPU_ID, kvm_get_supported_cpuid()); | 140 | vcpu_set_cpuid(vm, VCPU_ID, kvm_get_supported_cpuid()); |
134 | 141 | ||
135 | /* It is invalid to have vmxon_pa == -1ull and SMM flags non-zero. */ | 142 | /* |
143 | * Setting vmxon_pa == -1ull and vmcs_pa == -1ull exits early without | ||
144 | * setting the nested state but flags other than eVMCS must be clear. | ||
145 | */ | ||
136 | set_default_vmx_state(state, state_sz); | 146 | set_default_vmx_state(state, state_sz); |
137 | state->vmx.vmxon_pa = -1ull; | 147 | state->hdr.vmx.vmxon_pa = -1ull; |
138 | state->vmx.smm.flags = 1; | 148 | state->hdr.vmx.vmcs12_pa = -1ull; |
139 | test_nested_state_expect_einval(vm, state); | 149 | test_nested_state_expect_einval(vm, state); |
140 | 150 | ||
141 | /* It is invalid to have vmxon_pa == -1ull and vmcs_pa != -1ull. */ | 151 | state->flags = KVM_STATE_NESTED_EVMCS; |
142 | set_default_vmx_state(state, state_sz); | 152 | test_nested_state(vm, state); |
143 | state->vmx.vmxon_pa = -1ull; | 153 | |
144 | state->vmx.vmcs_pa = 0; | 154 | /* It is invalid to have vmxon_pa == -1ull and SMM flags non-zero. */ |
155 | state->hdr.vmx.smm.flags = 1; | ||
145 | test_nested_state_expect_einval(vm, state); | 156 | test_nested_state_expect_einval(vm, state); |
146 | 157 | ||
147 | /* | 158 | /* It is invalid to have vmxon_pa == -1ull and vmcs_pa != -1ull. */ |
148 | * Setting vmxon_pa == -1ull and vmcs_pa == -1ull exits early without | ||
149 | * setting the nested state. | ||
150 | */ | ||
151 | set_default_vmx_state(state, state_sz); | 159 | set_default_vmx_state(state, state_sz); |
152 | state->vmx.vmxon_pa = -1ull; | 160 | state->hdr.vmx.vmxon_pa = -1ull; |
153 | state->vmx.vmcs_pa = -1ull; | 161 | state->flags = 0; |
154 | test_nested_state(vm, state); | 162 | test_nested_state_expect_einval(vm, state); |
155 | 163 | ||
156 | /* It is invalid to have vmxon_pa set to a non-page aligned address. */ | 164 | /* It is invalid to have vmxon_pa set to a non-page aligned address. */ |
157 | set_default_vmx_state(state, state_sz); | 165 | set_default_vmx_state(state, state_sz); |
158 | state->vmx.vmxon_pa = 1; | 166 | state->hdr.vmx.vmxon_pa = 1; |
159 | test_nested_state_expect_einval(vm, state); | 167 | test_nested_state_expect_einval(vm, state); |
160 | 168 | ||
161 | /* | 169 | /* |
@@ -165,7 +173,7 @@ void test_vmx_nested_state(struct kvm_vm *vm) | |||
165 | set_default_vmx_state(state, state_sz); | 173 | set_default_vmx_state(state, state_sz); |
166 | state->flags = KVM_STATE_NESTED_GUEST_MODE | | 174 | state->flags = KVM_STATE_NESTED_GUEST_MODE | |
167 | KVM_STATE_NESTED_RUN_PENDING; | 175 | KVM_STATE_NESTED_RUN_PENDING; |
168 | state->vmx.smm.flags = KVM_STATE_NESTED_SMM_GUEST_MODE; | 176 | state->hdr.vmx.smm.flags = KVM_STATE_NESTED_SMM_GUEST_MODE; |
169 | test_nested_state_expect_einval(vm, state); | 177 | test_nested_state_expect_einval(vm, state); |
170 | 178 | ||
171 | /* | 179 | /* |
@@ -174,14 +182,14 @@ void test_vmx_nested_state(struct kvm_vm *vm) | |||
174 | * KVM_STATE_NESTED_SMM_VMXON | 182 | * KVM_STATE_NESTED_SMM_VMXON |
175 | */ | 183 | */ |
176 | set_default_vmx_state(state, state_sz); | 184 | set_default_vmx_state(state, state_sz); |
177 | state->vmx.smm.flags = ~(KVM_STATE_NESTED_SMM_GUEST_MODE | | 185 | state->hdr.vmx.smm.flags = ~(KVM_STATE_NESTED_SMM_GUEST_MODE | |
178 | KVM_STATE_NESTED_SMM_VMXON); | 186 | KVM_STATE_NESTED_SMM_VMXON); |
179 | test_nested_state_expect_einval(vm, state); | 187 | test_nested_state_expect_einval(vm, state); |
180 | 188 | ||
181 | /* Outside SMM, SMM flags must be zero. */ | 189 | /* Outside SMM, SMM flags must be zero. */ |
182 | set_default_vmx_state(state, state_sz); | 190 | set_default_vmx_state(state, state_sz); |
183 | state->flags = 0; | 191 | state->flags = 0; |
184 | state->vmx.smm.flags = KVM_STATE_NESTED_SMM_GUEST_MODE; | 192 | state->hdr.vmx.smm.flags = KVM_STATE_NESTED_SMM_GUEST_MODE; |
185 | test_nested_state_expect_einval(vm, state); | 193 | test_nested_state_expect_einval(vm, state); |
186 | 194 | ||
187 | /* Size must be large enough to fit kvm_nested_state and vmcs12. */ | 195 | /* Size must be large enough to fit kvm_nested_state and vmcs12. */ |
@@ -191,8 +199,8 @@ void test_vmx_nested_state(struct kvm_vm *vm) | |||
191 | 199 | ||
192 | /* vmxon_pa cannot be the same address as vmcs_pa. */ | 200 | /* vmxon_pa cannot be the same address as vmcs_pa. */ |
193 | set_default_vmx_state(state, state_sz); | 201 | set_default_vmx_state(state, state_sz); |
194 | state->vmx.vmxon_pa = 0; | 202 | state->hdr.vmx.vmxon_pa = 0; |
195 | state->vmx.vmcs_pa = 0; | 203 | state->hdr.vmx.vmcs12_pa = 0; |
196 | test_nested_state_expect_einval(vm, state); | 204 | test_nested_state_expect_einval(vm, state); |
197 | 205 | ||
198 | /* The revision id for vmcs12 must be VMCS12_REVISION. */ | 206 | /* The revision id for vmcs12 must be VMCS12_REVISION. */ |
@@ -205,16 +213,16 @@ void test_vmx_nested_state(struct kvm_vm *vm) | |||
205 | * it again. | 213 | * it again. |
206 | */ | 214 | */ |
207 | set_default_vmx_state(state, state_sz); | 215 | set_default_vmx_state(state, state_sz); |
208 | state->vmx.vmxon_pa = -1ull; | 216 | state->hdr.vmx.vmxon_pa = -1ull; |
209 | state->vmx.vmcs_pa = -1ull; | 217 | state->hdr.vmx.vmcs12_pa = -1ull; |
210 | state->flags = 0; | 218 | state->flags = 0; |
211 | test_nested_state(vm, state); | 219 | test_nested_state(vm, state); |
212 | vcpu_nested_state_get(vm, VCPU_ID, state); | 220 | vcpu_nested_state_get(vm, VCPU_ID, state); |
213 | TEST_ASSERT(state->size >= sizeof(*state) && state->size <= state_sz, | 221 | TEST_ASSERT(state->size >= sizeof(*state) && state->size <= state_sz, |
214 | "Size must be between %d and %d. The size returned was %d.", | 222 | "Size must be between %d and %d. The size returned was %d.", |
215 | sizeof(*state), state_sz, state->size); | 223 | sizeof(*state), state_sz, state->size); |
216 | TEST_ASSERT(state->vmx.vmxon_pa == -1ull, "vmxon_pa must be -1ull."); | 224 | TEST_ASSERT(state->hdr.vmx.vmxon_pa == -1ull, "vmxon_pa must be -1ull."); |
217 | TEST_ASSERT(state->vmx.vmcs_pa == -1ull, "vmcs_pa must be -1ull."); | 225 | TEST_ASSERT(state->hdr.vmx.vmcs12_pa == -1ull, "vmcs_pa must be -1ull."); |
218 | 226 | ||
219 | free(state); | 227 | free(state); |
220 | } | 228 | } |
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c index 05ddb6293b79..1be486d5d7cb 100644 --- a/virt/kvm/arm/arch_timer.c +++ b/virt/kvm/arm/arch_timer.c | |||
@@ -309,14 +309,15 @@ static void kvm_timer_update_irq(struct kvm_vcpu *vcpu, bool new_level, | |||
309 | } | 309 | } |
310 | } | 310 | } |
311 | 311 | ||
312 | /* Only called for a fully emulated timer */ | ||
312 | static void timer_emulate(struct arch_timer_context *ctx) | 313 | static void timer_emulate(struct arch_timer_context *ctx) |
313 | { | 314 | { |
314 | bool should_fire = kvm_timer_should_fire(ctx); | 315 | bool should_fire = kvm_timer_should_fire(ctx); |
315 | 316 | ||
316 | trace_kvm_timer_emulate(ctx, should_fire); | 317 | trace_kvm_timer_emulate(ctx, should_fire); |
317 | 318 | ||
318 | if (should_fire) { | 319 | if (should_fire != ctx->irq.level) { |
319 | kvm_timer_update_irq(ctx->vcpu, true, ctx); | 320 | kvm_timer_update_irq(ctx->vcpu, should_fire, ctx); |
320 | return; | 321 | return; |
321 | } | 322 | } |
322 | 323 | ||
diff --git a/virt/kvm/arm/vgic/vgic-its.c b/virt/kvm/arm/vgic/vgic-its.c index 44ceaccb18cf..8c9fe831bce4 100644 --- a/virt/kvm/arm/vgic/vgic-its.c +++ b/virt/kvm/arm/vgic/vgic-its.c | |||
@@ -1734,6 +1734,7 @@ static void vgic_its_destroy(struct kvm_device *kvm_dev) | |||
1734 | 1734 | ||
1735 | mutex_unlock(&its->its_lock); | 1735 | mutex_unlock(&its->its_lock); |
1736 | kfree(its); | 1736 | kfree(its); |
1737 | kfree(kvm_dev);/* alloc by kvm_ioctl_create_device, free by .destroy */ | ||
1737 | } | 1738 | } |
1738 | 1739 | ||
1739 | static int vgic_its_has_attr_regs(struct kvm_device *dev, | 1740 | static int vgic_its_has_attr_regs(struct kvm_device *dev, |