0009-kvm-nVMX-Enforce-cpl-0-for-VMX-instructions.patch 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
  2. From: Felix Wilhelm <[email protected]>
  3. Date: Mon, 11 Jun 2018 09:43:44 +0200
  4. Subject: [PATCH] kvm: nVMX: Enforce cpl=0 for VMX instructions
  5. VMX instructions executed inside a L1 VM will always trigger a VM exit
  6. even when executed with cpl 3. This means we must perform the
  7. privilege check in software.
  8. Fixes: 70f3aac964ae("kvm: nVMX: Remove superfluous VMX instruction fault checks")
  9. Cc: [email protected]
  10. Signed-off-by: Felix Wilhelm <[email protected]>
  11. Signed-off-by: Paolo Bonzini <[email protected]>
  12. Signed-off-by: Thomas Lamprecht <[email protected]>
  13. ---
  14. arch/x86/kvm/vmx.c | 15 +++++++++++++--
  15. 1 file changed, 13 insertions(+), 2 deletions(-)
  16. diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
  17. index 1a5617fc8b6a..5c8bd2d61080 100644
  18. --- a/arch/x86/kvm/vmx.c
  19. +++ b/arch/x86/kvm/vmx.c
  20. @@ -7575,6 +7575,12 @@ static int handle_vmon(struct kvm_vcpu *vcpu)
  21. return 1;
  22. }
  23. + /* CPL=0 must be checked manually. */
  24. + if (vmx_get_cpl(vcpu)) {
  25. + kvm_queue_exception(vcpu, UD_VECTOR);
  26. + return 1;
  27. + }
  28. +
  29. if (vmx->nested.vmxon) {
  30. nested_vmx_failValid(vcpu, VMXERR_VMXON_IN_VMX_ROOT_OPERATION);
  31. return kvm_skip_emulated_instruction(vcpu);
  32. @@ -7634,6 +7640,11 @@ static int handle_vmon(struct kvm_vcpu *vcpu)
  33. */
  34. static int nested_vmx_check_permission(struct kvm_vcpu *vcpu)
  35. {
  36. + if (vmx_get_cpl(vcpu)) {
  37. + kvm_queue_exception(vcpu, UD_VECTOR);
  38. + return 0;
  39. + }
  40. +
  41. if (!to_vmx(vcpu)->nested.vmxon) {
  42. kvm_queue_exception(vcpu, UD_VECTOR);
  43. return 0;
  44. @@ -7967,7 +7978,7 @@ static int handle_vmread(struct kvm_vcpu *vcpu)
  45. if (get_vmx_mem_address(vcpu, exit_qualification,
  46. vmx_instruction_info, true, &gva))
  47. return 1;
  48. - /* _system ok, as hardware has verified cpl=0 */
  49. + /* _system ok, nested_vmx_check_permission has verified cpl=0 */
  50. kvm_write_guest_virt_system(&vcpu->arch.emulate_ctxt, gva,
  51. &field_value, (is_long_mode(vcpu) ? 8 : 4), NULL);
  52. }
  53. @@ -8110,7 +8121,7 @@ static int handle_vmptrst(struct kvm_vcpu *vcpu)
  54. if (get_vmx_mem_address(vcpu, exit_qualification,
  55. vmx_instruction_info, true, &vmcs_gva))
  56. return 1;
  57. - /* ok to use *_system, as hardware has verified cpl=0 */
  58. + /* *_system ok, nested_vmx_check_permission has verified cpl=0 */
  59. if (kvm_write_guest_virt_system(&vcpu->arch.emulate_ctxt, vmcs_gva,
  60. (void *)&to_vmx(vcpu)->nested.current_vmptr,
  61. sizeof(u64), &e)) {