aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/virtual/kvm/api.txt2
-rw-r--r--arch/arm/include/asm/kvm_mmu.h1
-rw-r--r--arch/arm/kvm/arm.c30
-rw-r--r--arch/arm/kvm/handle_exit.c2
-rw-r--r--arch/arm/kvm/mmu.c24
-rw-r--r--arch/arm/kvm/psci.c11
-rw-r--r--arch/arm64/include/asm/kvm_mmu.h1
7 files changed, 41 insertions, 30 deletions
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index a8cdc7b72281..366bf4b47ef4 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2327,7 +2327,7 @@ current state. "addr" is ignored.
2327Capability: basic 2327Capability: basic
2328Architectures: arm, arm64 2328Architectures: arm, arm64
2329Type: vcpu ioctl 2329Type: vcpu ioctl
2330Parameters: struct struct kvm_vcpu_init (in) 2330Parameters: struct kvm_vcpu_init (in)
2331Returns: 0 on success; -1 on error 2331Returns: 0 on success; -1 on error
2332Errors: 2332Errors:
2333  EINVAL:    the target is unknown, or the combination of features is invalid. 2333  EINVAL:    the target is unknown, or the combination of features is invalid.
diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h
index 77de4a41cc50..2d122adcdb22 100644
--- a/arch/arm/include/asm/kvm_mmu.h
+++ b/arch/arm/include/asm/kvm_mmu.h
@@ -140,6 +140,7 @@ static inline void coherent_icache_guest_page(struct kvm *kvm, hva_t hva,
140} 140}
141 141
142#define kvm_flush_dcache_to_poc(a,l) __cpuc_flush_dcache_area((a), (l)) 142#define kvm_flush_dcache_to_poc(a,l) __cpuc_flush_dcache_area((a), (l))
143#define kvm_virt_to_phys(x) virt_to_idmap((unsigned long)(x))
143 144
144#endif /* !__ASSEMBLY__ */ 145#endif /* !__ASSEMBLY__ */
145 146
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
705static 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
714long kvm_arch_vcpu_ioctl(struct file *filp, 723long 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
31typedef int (*exit_handle_fn)(struct kvm_vcpu *, struct kvm_run *); 29typedef int (*exit_handle_fn)(struct kvm_vcpu *, struct kvm_run *);
32 30
33static int handle_svc_hyp(struct kvm_vcpu *vcpu, struct kvm_run *run) 31static 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(&current->mm->mmap_sem); 682 up_read(&current->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;
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index 680f74e67497..7f1f9408ff66 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -136,6 +136,7 @@ static inline void coherent_icache_guest_page(struct kvm *kvm, hva_t hva,
136} 136}
137 137
138#define kvm_flush_dcache_to_poc(a,l) __flush_dcache_area((a), (l)) 138#define kvm_flush_dcache_to_poc(a,l) __flush_dcache_area((a), (l))
139#define kvm_virt_to_phys(x) __virt_to_phys((unsigned long)(x))
139 140
140#endif /* __ASSEMBLY__ */ 141#endif /* __ASSEMBLY__ */
141#endif /* __ARM64_KVM_MMU_H__ */ 142#endif /* __ARM64_KVM_MMU_H__ */