diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2014-01-15 06:14:29 -0500 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2014-01-15 06:14:29 -0500 |
commit | ab53f22e2e2dbb60d4eb1b505776f03da4aa9bdc (patch) | |
tree | 6ebddac80d6f05c4ac58186227c062e94f55ada2 /arch/arm/kvm | |
parent | 4a55dd7273c95b4a19fbcf0ae1bbd1cfd09dfc36 (diff) | |
parent | 61466710de078c697106fa5b70ec7afc9feab520 (diff) |
Merge tag 'kvm-arm-for-3.14' of git://git.linaro.org/people/christoffer.dall/linux-kvm-arm into kvm-queue
Diffstat (limited to 'arch/arm/kvm')
-rw-r--r-- | arch/arm/kvm/arm.c | 30 | ||||
-rw-r--r-- | arch/arm/kvm/handle_exit.c | 2 | ||||
-rw-r--r-- | arch/arm/kvm/mmu.c | 24 | ||||
-rw-r--r-- | arch/arm/kvm/psci.c | 11 |
4 files changed, 38 insertions, 29 deletions
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index b92ff6d3e34b..2d4b4a8068c8 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c | |||
@@ -489,15 +489,6 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu) | |||
489 | return ret; | 489 | return ret; |
490 | } | 490 | } |
491 | 491 | ||
492 | /* | ||
493 | * Handle the "start in power-off" case by calling into the | ||
494 | * PSCI code. | ||
495 | */ | ||
496 | if (test_and_clear_bit(KVM_ARM_VCPU_POWER_OFF, vcpu->arch.features)) { | ||
497 | *vcpu_reg(vcpu, 0) = KVM_PSCI_FN_CPU_OFF; | ||
498 | kvm_psci_call(vcpu); | ||
499 | } | ||
500 | |||
501 | return 0; | 492 | return 0; |
502 | } | 493 | } |
503 | 494 | ||
@@ -711,6 +702,24 @@ int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_level, | |||
711 | return -EINVAL; | 702 | return -EINVAL; |
712 | } | 703 | } |
713 | 704 | ||
705 | static int kvm_arch_vcpu_ioctl_vcpu_init(struct kvm_vcpu *vcpu, | ||
706 | struct kvm_vcpu_init *init) | ||
707 | { | ||
708 | int ret; | ||
709 | |||
710 | ret = kvm_vcpu_set_target(vcpu, init); | ||
711 | if (ret) | ||
712 | return ret; | ||
713 | |||
714 | /* | ||
715 | * Handle the "start in power-off" case by marking the VCPU as paused. | ||
716 | */ | ||
717 | if (__test_and_clear_bit(KVM_ARM_VCPU_POWER_OFF, vcpu->arch.features)) | ||
718 | vcpu->arch.pause = true; | ||
719 | |||
720 | return 0; | ||
721 | } | ||
722 | |||
714 | long kvm_arch_vcpu_ioctl(struct file *filp, | 723 | long kvm_arch_vcpu_ioctl(struct file *filp, |
715 | unsigned int ioctl, unsigned long arg) | 724 | unsigned int ioctl, unsigned long arg) |
716 | { | 725 | { |
@@ -724,8 +733,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp, | |||
724 | if (copy_from_user(&init, argp, sizeof(init))) | 733 | if (copy_from_user(&init, argp, sizeof(init))) |
725 | return -EFAULT; | 734 | return -EFAULT; |
726 | 735 | ||
727 | return kvm_vcpu_set_target(vcpu, &init); | 736 | return kvm_arch_vcpu_ioctl_vcpu_init(vcpu, &init); |
728 | |||
729 | } | 737 | } |
730 | case KVM_SET_ONE_REG: | 738 | case KVM_SET_ONE_REG: |
731 | case KVM_GET_ONE_REG: { | 739 | case KVM_GET_ONE_REG: { |
diff --git a/arch/arm/kvm/handle_exit.c b/arch/arm/kvm/handle_exit.c index a92079011a83..0de91fc6de0f 100644 --- a/arch/arm/kvm/handle_exit.c +++ b/arch/arm/kvm/handle_exit.c | |||
@@ -26,8 +26,6 @@ | |||
26 | 26 | ||
27 | #include "trace.h" | 27 | #include "trace.h" |
28 | 28 | ||
29 | #include "trace.h" | ||
30 | |||
31 | typedef int (*exit_handle_fn)(struct kvm_vcpu *, struct kvm_run *); | 29 | typedef int (*exit_handle_fn)(struct kvm_vcpu *, struct kvm_run *); |
32 | 30 | ||
33 | static int handle_svc_hyp(struct kvm_vcpu *vcpu, struct kvm_run *run) | 31 | static int handle_svc_hyp(struct kvm_vcpu *vcpu, struct kvm_run *run) |
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c index 580906989db1..7789857d1470 100644 --- a/arch/arm/kvm/mmu.c +++ b/arch/arm/kvm/mmu.c | |||
@@ -667,14 +667,16 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, | |||
667 | gfn = (fault_ipa & PMD_MASK) >> PAGE_SHIFT; | 667 | gfn = (fault_ipa & PMD_MASK) >> PAGE_SHIFT; |
668 | } else { | 668 | } else { |
669 | /* | 669 | /* |
670 | * Pages belonging to VMAs not aligned to the PMD mapping | 670 | * Pages belonging to memslots that don't have the same |
671 | * granularity cannot be mapped using block descriptors even | 671 | * alignment for userspace and IPA cannot be mapped using |
672 | * if the pages belong to a THP for the process, because the | 672 | * block descriptors even if the pages belong to a THP for |
673 | * stage-2 block descriptor will cover more than a single THP | 673 | * the process, because the stage-2 block descriptor will |
674 | * and we loose atomicity for unmapping, updates, and splits | 674 | * cover more than a single THP and we loose atomicity for |
675 | * of the THP or other pages in the stage-2 block range. | 675 | * unmapping, updates, and splits of the THP or other pages |
676 | * in the stage-2 block range. | ||
676 | */ | 677 | */ |
677 | if (vma->vm_start & ~PMD_MASK) | 678 | if ((memslot->userspace_addr & ~PMD_MASK) != |
679 | ((memslot->base_gfn << PAGE_SHIFT) & ~PMD_MASK)) | ||
678 | force_pte = true; | 680 | force_pte = true; |
679 | } | 681 | } |
680 | up_read(¤t->mm->mmap_sem); | 682 | up_read(¤t->mm->mmap_sem); |
@@ -916,9 +918,9 @@ int kvm_mmu_init(void) | |||
916 | { | 918 | { |
917 | int err; | 919 | int err; |
918 | 920 | ||
919 | hyp_idmap_start = virt_to_phys(__hyp_idmap_text_start); | 921 | hyp_idmap_start = kvm_virt_to_phys(__hyp_idmap_text_start); |
920 | hyp_idmap_end = virt_to_phys(__hyp_idmap_text_end); | 922 | hyp_idmap_end = kvm_virt_to_phys(__hyp_idmap_text_end); |
921 | hyp_idmap_vector = virt_to_phys(__kvm_hyp_init); | 923 | hyp_idmap_vector = kvm_virt_to_phys(__kvm_hyp_init); |
922 | 924 | ||
923 | if ((hyp_idmap_start ^ hyp_idmap_end) & PAGE_MASK) { | 925 | if ((hyp_idmap_start ^ hyp_idmap_end) & PAGE_MASK) { |
924 | /* | 926 | /* |
@@ -945,7 +947,7 @@ int kvm_mmu_init(void) | |||
945 | */ | 947 | */ |
946 | kvm_flush_dcache_to_poc(init_bounce_page, len); | 948 | kvm_flush_dcache_to_poc(init_bounce_page, len); |
947 | 949 | ||
948 | phys_base = virt_to_phys(init_bounce_page); | 950 | phys_base = kvm_virt_to_phys(init_bounce_page); |
949 | hyp_idmap_vector += phys_base - hyp_idmap_start; | 951 | hyp_idmap_vector += phys_base - hyp_idmap_start; |
950 | hyp_idmap_start = phys_base; | 952 | hyp_idmap_start = phys_base; |
951 | hyp_idmap_end = phys_base + len; | 953 | hyp_idmap_end = phys_base + len; |
diff --git a/arch/arm/kvm/psci.c b/arch/arm/kvm/psci.c index 0881bf169fbc..448f60e8d23c 100644 --- a/arch/arm/kvm/psci.c +++ b/arch/arm/kvm/psci.c | |||
@@ -54,15 +54,15 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu) | |||
54 | } | 54 | } |
55 | } | 55 | } |
56 | 56 | ||
57 | if (!vcpu) | 57 | /* |
58 | * Make sure the caller requested a valid CPU and that the CPU is | ||
59 | * turned off. | ||
60 | */ | ||
61 | if (!vcpu || !vcpu->arch.pause) | ||
58 | return KVM_PSCI_RET_INVAL; | 62 | return KVM_PSCI_RET_INVAL; |
59 | 63 | ||
60 | target_pc = *vcpu_reg(source_vcpu, 2); | 64 | target_pc = *vcpu_reg(source_vcpu, 2); |
61 | 65 | ||
62 | wq = kvm_arch_vcpu_wq(vcpu); | ||
63 | if (!waitqueue_active(wq)) | ||
64 | return KVM_PSCI_RET_INVAL; | ||
65 | |||
66 | kvm_reset_vcpu(vcpu); | 66 | kvm_reset_vcpu(vcpu); |
67 | 67 | ||
68 | /* Gracefully handle Thumb2 entry point */ | 68 | /* Gracefully handle Thumb2 entry point */ |
@@ -79,6 +79,7 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu) | |||
79 | vcpu->arch.pause = false; | 79 | vcpu->arch.pause = false; |
80 | smp_mb(); /* Make sure the above is visible */ | 80 | smp_mb(); /* Make sure the above is visible */ |
81 | 81 | ||
82 | wq = kvm_arch_vcpu_wq(vcpu); | ||
82 | wake_up_interruptible(wq); | 83 | wake_up_interruptible(wq); |
83 | 84 | ||
84 | return KVM_PSCI_RET_SUCCESS; | 85 | return KVM_PSCI_RET_SUCCESS; |