diff options
-rw-r--r-- | arch/x86/include/asm/kvm_host.h | 2 | ||||
-rw-r--r-- | arch/x86/kvm/svm.c | 2 | ||||
-rw-r--r-- | arch/x86/kvm/vmx.c | 13 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 12 |
4 files changed, 16 insertions, 13 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 91631b8b2090..b23708450210 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h | |||
@@ -597,7 +597,7 @@ int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, int seg); | |||
597 | int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason, | 597 | int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason, |
598 | bool has_error_code, u32 error_code); | 598 | bool has_error_code, u32 error_code); |
599 | 599 | ||
600 | void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0); | 600 | int kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0); |
601 | void kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3); | 601 | void kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3); |
602 | void kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4); | 602 | void kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4); |
603 | void kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8); | 603 | void kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8); |
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 2ae0c3923293..6d1616d47c54 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -807,7 +807,7 @@ static void init_vmcb(struct vcpu_svm *svm) | |||
807 | * svm_set_cr0() sets PG and WP and clears NW and CD on save->cr0. | 807 | * svm_set_cr0() sets PG and WP and clears NW and CD on save->cr0. |
808 | */ | 808 | */ |
809 | svm->vcpu.arch.cr0 = X86_CR0_NW | X86_CR0_CD | X86_CR0_ET; | 809 | svm->vcpu.arch.cr0 = X86_CR0_NW | X86_CR0_CD | X86_CR0_ET; |
810 | kvm_set_cr0(&svm->vcpu, svm->vcpu.arch.cr0); | 810 | (void)kvm_set_cr0(&svm->vcpu, svm->vcpu.arch.cr0); |
811 | 811 | ||
812 | save->cr4 = X86_CR4_PAE; | 812 | save->cr4 = X86_CR4_PAE; |
813 | /* rdx = ?? */ | 813 | /* rdx = ?? */ |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 864a1b6d155a..1baf4b2d98ee 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -3157,11 +3157,20 @@ vmx_patch_hypercall(struct kvm_vcpu *vcpu, unsigned char *hypercall) | |||
3157 | hypercall[2] = 0xc1; | 3157 | hypercall[2] = 0xc1; |
3158 | } | 3158 | } |
3159 | 3159 | ||
3160 | static void complete_insn_gp(struct kvm_vcpu *vcpu, int err) | ||
3161 | { | ||
3162 | if (err) | ||
3163 | kvm_inject_gp(vcpu, 0); | ||
3164 | else | ||
3165 | skip_emulated_instruction(vcpu); | ||
3166 | } | ||
3167 | |||
3160 | static int handle_cr(struct kvm_vcpu *vcpu) | 3168 | static int handle_cr(struct kvm_vcpu *vcpu) |
3161 | { | 3169 | { |
3162 | unsigned long exit_qualification, val; | 3170 | unsigned long exit_qualification, val; |
3163 | int cr; | 3171 | int cr; |
3164 | int reg; | 3172 | int reg; |
3173 | int err; | ||
3165 | 3174 | ||
3166 | exit_qualification = vmcs_readl(EXIT_QUALIFICATION); | 3175 | exit_qualification = vmcs_readl(EXIT_QUALIFICATION); |
3167 | cr = exit_qualification & 15; | 3176 | cr = exit_qualification & 15; |
@@ -3172,8 +3181,8 @@ static int handle_cr(struct kvm_vcpu *vcpu) | |||
3172 | trace_kvm_cr_write(cr, val); | 3181 | trace_kvm_cr_write(cr, val); |
3173 | switch (cr) { | 3182 | switch (cr) { |
3174 | case 0: | 3183 | case 0: |
3175 | kvm_set_cr0(vcpu, val); | 3184 | err = kvm_set_cr0(vcpu, val); |
3176 | skip_emulated_instruction(vcpu); | 3185 | complete_insn_gp(vcpu, err); |
3177 | return 1; | 3186 | return 1; |
3178 | case 3: | 3187 | case 3: |
3179 | kvm_set_cr3(vcpu, val); | 3188 | kvm_set_cr3(vcpu, val); |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index b5e644701cc1..05e9b5dde646 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -425,7 +425,7 @@ out: | |||
425 | return changed; | 425 | return changed; |
426 | } | 426 | } |
427 | 427 | ||
428 | static int __kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) | 428 | int kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) |
429 | { | 429 | { |
430 | unsigned long old_cr0 = kvm_read_cr0(vcpu); | 430 | unsigned long old_cr0 = kvm_read_cr0(vcpu); |
431 | unsigned long update_bits = X86_CR0_PG | X86_CR0_WP | | 431 | unsigned long update_bits = X86_CR0_PG | X86_CR0_WP | |
@@ -468,17 +468,11 @@ static int __kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) | |||
468 | kvm_mmu_reset_context(vcpu); | 468 | kvm_mmu_reset_context(vcpu); |
469 | return 0; | 469 | return 0; |
470 | } | 470 | } |
471 | |||
472 | void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) | ||
473 | { | ||
474 | if (__kvm_set_cr0(vcpu, cr0)) | ||
475 | kvm_inject_gp(vcpu, 0); | ||
476 | } | ||
477 | EXPORT_SYMBOL_GPL(kvm_set_cr0); | 471 | EXPORT_SYMBOL_GPL(kvm_set_cr0); |
478 | 472 | ||
479 | void kvm_lmsw(struct kvm_vcpu *vcpu, unsigned long msw) | 473 | void kvm_lmsw(struct kvm_vcpu *vcpu, unsigned long msw) |
480 | { | 474 | { |
481 | kvm_set_cr0(vcpu, kvm_read_cr0_bits(vcpu, ~0x0eul) | (msw & 0x0f)); | 475 | (void)kvm_set_cr0(vcpu, kvm_read_cr0_bits(vcpu, ~0x0eul) | (msw & 0x0f)); |
482 | } | 476 | } |
483 | EXPORT_SYMBOL_GPL(kvm_lmsw); | 477 | EXPORT_SYMBOL_GPL(kvm_lmsw); |
484 | 478 | ||
@@ -3732,7 +3726,7 @@ static int emulator_set_cr(int cr, unsigned long val, struct kvm_vcpu *vcpu) | |||
3732 | 3726 | ||
3733 | switch (cr) { | 3727 | switch (cr) { |
3734 | case 0: | 3728 | case 0: |
3735 | res = __kvm_set_cr0(vcpu, mk_cr_64(kvm_read_cr0(vcpu), val)); | 3729 | res = kvm_set_cr0(vcpu, mk_cr_64(kvm_read_cr0(vcpu), val)); |
3736 | break; | 3730 | break; |
3737 | case 2: | 3731 | case 2: |
3738 | vcpu->arch.cr2 = val; | 3732 | vcpu->arch.cr2 = val; |