aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm
diff options
context:
space:
mode:
authorJoerg Roedel <joerg.roedel@amd.com>2009-08-07 05:49:36 -0400
committerAvi Kivity <avi@redhat.com>2009-09-10 01:33:25 -0400
commit9c4e40b9949868928bd7fec67a4b0902d90e57ed (patch)
treea328b7aadb9c45455e2ae065e49d3debd049ee56 /arch/x86/kvm
parent4c2161aed55c294c4c42622455f067a4b3077b85 (diff)
KVM: SVM: do nested vmexit in nested_svm_exit_handled
If this function returns true a nested vmexit is required. Move that vmexit into the nested_svm_exit_handled function. This also simplifies the handling of nested #pf intercepts in this function. Signed-off-by: Joerg Roedel <joerg.roedel@amd.com> Acked-by: Alexander Graf <agraf@suse.de> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm')
-rw-r--r--arch/x86/kvm/svm.c42
1 files changed, 19 insertions, 23 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index bdd73fd9a75c..3bb6d4b92b34 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -1366,8 +1366,6 @@ static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
1366 svm->vmcb->control.exit_info_2 = svm->vcpu.arch.cr2; 1366 svm->vmcb->control.exit_info_2 = svm->vcpu.arch.cr2;
1367 if (nested_svm_exit_handled(svm, false)) { 1367 if (nested_svm_exit_handled(svm, false)) {
1368 nsvm_printk("VMexit -> EXCP 0x%x\n", nr); 1368 nsvm_printk("VMexit -> EXCP 0x%x\n", nr);
1369
1370 nested_svm_vmexit(svm);
1371 return 1; 1369 return 1;
1372 } 1370 }
1373 } 1371 }
@@ -1388,7 +1386,6 @@ static inline int nested_svm_intr(struct vcpu_svm *svm)
1388 1386
1389 if (nested_svm_exit_handled(svm, false)) { 1387 if (nested_svm_exit_handled(svm, false)) {
1390 nsvm_printk("VMexit -> INTR\n"); 1388 nsvm_printk("VMexit -> INTR\n");
1391 nested_svm_vmexit(svm);
1392 return 1; 1389 return 1;
1393 } 1390 }
1394 } 1391 }
@@ -1497,15 +1494,7 @@ static int nested_svm_exit_handled_msr(struct vcpu_svm *svm,
1497static int nested_svm_exit_handled(struct vcpu_svm *svm, bool kvm_override) 1494static int nested_svm_exit_handled(struct vcpu_svm *svm, bool kvm_override)
1498{ 1495{
1499 u32 exit_code = svm->vmcb->control.exit_code; 1496 u32 exit_code = svm->vmcb->control.exit_code;
1500 1497 bool vmexit = false;
1501 switch (svm->vmcb->control.exit_code) {
1502 case SVM_EXIT_MSR:
1503 return nested_svm_do(svm, svm->nested.vmcb,
1504 svm->nested.vmcb_msrpm, NULL,
1505 nested_svm_exit_handled_msr);
1506 default:
1507 break;
1508 }
1509 1498
1510 if (kvm_override) { 1499 if (kvm_override) {
1511 switch (exit_code) { 1500 switch (exit_code) {
@@ -1528,45 +1517,55 @@ static int nested_svm_exit_handled(struct vcpu_svm *svm, bool kvm_override)
1528 } 1517 }
1529 1518
1530 switch (exit_code) { 1519 switch (exit_code) {
1520 case SVM_EXIT_MSR:
1521 if (nested_svm_do(svm, svm->nested.vmcb, svm->nested.vmcb_msrpm,
1522 NULL, nested_svm_exit_handled_msr))
1523 vmexit = true;
1524 break;
1531 case SVM_EXIT_READ_CR0 ... SVM_EXIT_READ_CR8: { 1525 case SVM_EXIT_READ_CR0 ... SVM_EXIT_READ_CR8: {
1532 u32 cr_bits = 1 << (exit_code - SVM_EXIT_READ_CR0); 1526 u32 cr_bits = 1 << (exit_code - SVM_EXIT_READ_CR0);
1533 if (svm->nested.intercept_cr_read & cr_bits) 1527 if (svm->nested.intercept_cr_read & cr_bits)
1534 return 1; 1528 vmexit = true;
1535 break; 1529 break;
1536 } 1530 }
1537 case SVM_EXIT_WRITE_CR0 ... SVM_EXIT_WRITE_CR8: { 1531 case SVM_EXIT_WRITE_CR0 ... SVM_EXIT_WRITE_CR8: {
1538 u32 cr_bits = 1 << (exit_code - SVM_EXIT_WRITE_CR0); 1532 u32 cr_bits = 1 << (exit_code - SVM_EXIT_WRITE_CR0);
1539 if (svm->nested.intercept_cr_write & cr_bits) 1533 if (svm->nested.intercept_cr_write & cr_bits)
1540 return 1; 1534 vmexit = true;
1541 break; 1535 break;
1542 } 1536 }
1543 case SVM_EXIT_READ_DR0 ... SVM_EXIT_READ_DR7: { 1537 case SVM_EXIT_READ_DR0 ... SVM_EXIT_READ_DR7: {
1544 u32 dr_bits = 1 << (exit_code - SVM_EXIT_READ_DR0); 1538 u32 dr_bits = 1 << (exit_code - SVM_EXIT_READ_DR0);
1545 if (svm->nested.intercept_dr_read & dr_bits) 1539 if (svm->nested.intercept_dr_read & dr_bits)
1546 return 1; 1540 vmexit = true;
1547 break; 1541 break;
1548 } 1542 }
1549 case SVM_EXIT_WRITE_DR0 ... SVM_EXIT_WRITE_DR7: { 1543 case SVM_EXIT_WRITE_DR0 ... SVM_EXIT_WRITE_DR7: {
1550 u32 dr_bits = 1 << (exit_code - SVM_EXIT_WRITE_DR0); 1544 u32 dr_bits = 1 << (exit_code - SVM_EXIT_WRITE_DR0);
1551 if (svm->nested.intercept_dr_write & dr_bits) 1545 if (svm->nested.intercept_dr_write & dr_bits)
1552 return 1; 1546 vmexit = true;
1553 break; 1547 break;
1554 } 1548 }
1555 case SVM_EXIT_EXCP_BASE ... SVM_EXIT_EXCP_BASE + 0x1f: { 1549 case SVM_EXIT_EXCP_BASE ... SVM_EXIT_EXCP_BASE + 0x1f: {
1556 u32 excp_bits = 1 << (exit_code - SVM_EXIT_EXCP_BASE); 1550 u32 excp_bits = 1 << (exit_code - SVM_EXIT_EXCP_BASE);
1557 if (svm->nested.intercept_exceptions & excp_bits) 1551 if (svm->nested.intercept_exceptions & excp_bits)
1558 return 1; 1552 vmexit = true;
1559 break; 1553 break;
1560 } 1554 }
1561 default: { 1555 default: {
1562 u64 exit_bits = 1ULL << (exit_code - SVM_EXIT_INTR); 1556 u64 exit_bits = 1ULL << (exit_code - SVM_EXIT_INTR);
1563 nsvm_printk("exit code: 0x%x\n", exit_code); 1557 nsvm_printk("exit code: 0x%x\n", exit_code);
1564 if (svm->nested.intercept & exit_bits) 1558 if (svm->nested.intercept & exit_bits)
1565 return 1; 1559 vmexit = true;
1566 } 1560 }
1567 } 1561 }
1568 1562
1569 return 0; 1563 if (vmexit) {
1564 nsvm_printk("#VMEXIT reason=%04x\n", exit_code);
1565 nested_svm_vmexit(svm);
1566 }
1567
1568 return vmexit;
1570} 1569}
1571 1570
1572static inline void copy_vmcb_control_area(struct vmcb *dst_vmcb, struct vmcb *from_vmcb) 1571static inline void copy_vmcb_control_area(struct vmcb *dst_vmcb, struct vmcb *from_vmcb)
@@ -2327,11 +2326,8 @@ static int handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
2327 nsvm_printk("nested handle_exit: 0x%x | 0x%lx | 0x%lx | 0x%lx\n", 2326 nsvm_printk("nested handle_exit: 0x%x | 0x%lx | 0x%lx | 0x%lx\n",
2328 exit_code, svm->vmcb->control.exit_info_1, 2327 exit_code, svm->vmcb->control.exit_info_1,
2329 svm->vmcb->control.exit_info_2, svm->vmcb->save.rip); 2328 svm->vmcb->control.exit_info_2, svm->vmcb->save.rip);
2330 if (nested_svm_exit_handled(svm, true)) { 2329 if (nested_svm_exit_handled(svm, true))
2331 nested_svm_vmexit(svm);
2332 nsvm_printk("-> #VMEXIT\n");
2333 return 1; 2330 return 1;
2334 }
2335 } 2331 }
2336 2332
2337 svm_complete_interrupts(svm); 2333 svm_complete_interrupts(svm);