diff options
author | Joerg Roedel <joerg.roedel@amd.com> | 2009-08-07 05:49:36 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-09-10 01:33:25 -0400 |
commit | 9c4e40b9949868928bd7fec67a4b0902d90e57ed (patch) | |
tree | a328b7aadb9c45455e2ae065e49d3debd049ee56 /arch/x86/kvm | |
parent | 4c2161aed55c294c4c42622455f067a4b3077b85 (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.c | 42 |
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, | |||
1497 | static int nested_svm_exit_handled(struct vcpu_svm *svm, bool kvm_override) | 1494 | static 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 | ||
1572 | static inline void copy_vmcb_control_area(struct vmcb *dst_vmcb, struct vmcb *from_vmcb) | 1571 | static 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); |