aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/include/asm/kvm_host.h1
-rw-r--r--arch/arm/kvm/arm.c8
-rw-r--r--arch/arm64/include/asm/kvm_host.h3
-rw-r--r--include/kvm/arm_vgic.h8
-rw-r--r--virt/kvm/arm/vgic-v2.c1
-rw-r--r--virt/kvm/arm/vgic-v3.c1
-rw-r--r--virt/kvm/arm/vgic.c16
7 files changed, 38 insertions, 0 deletions
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index 2fa51740edc2..bde494654bcc 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -68,6 +68,7 @@ struct kvm_arch {
68 68
69 /* Interrupt controller */ 69 /* Interrupt controller */
70 struct vgic_dist vgic; 70 struct vgic_dist vgic;
71 int max_vcpus;
71}; 72};
72 73
73#define KVM_NR_MEM_OBJS 40 74#define KVM_NR_MEM_OBJS 40
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 3a51ffca75e3..6fbfa5fff05d 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -132,6 +132,9 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
132 /* Mark the initial VMID generation invalid */ 132 /* Mark the initial VMID generation invalid */
133 kvm->arch.vmid_gen = 0; 133 kvm->arch.vmid_gen = 0;
134 134
135 /* The maximum number of VCPUs is limited by the host's GIC model */
136 kvm->arch.max_vcpus = kvm_vgic_get_max_vcpus();
137
135 return ret; 138 return ret;
136out_free_stage2_pgd: 139out_free_stage2_pgd:
137 kvm_free_stage2_pgd(kvm); 140 kvm_free_stage2_pgd(kvm);
@@ -218,6 +221,11 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id)
218 goto out; 221 goto out;
219 } 222 }
220 223
224 if (id >= kvm->arch.max_vcpus) {
225 err = -EINVAL;
226 goto out;
227 }
228
221 vcpu = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL); 229 vcpu = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL);
222 if (!vcpu) { 230 if (!vcpu) {
223 err = -ENOMEM; 231 err = -ENOMEM;
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index ff8ee3ec32f4..2c49aa4ac818 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -59,6 +59,9 @@ struct kvm_arch {
59 /* VTTBR value associated with above pgd and vmid */ 59 /* VTTBR value associated with above pgd and vmid */
60 u64 vttbr; 60 u64 vttbr;
61 61
62 /* The maximum number of vCPUs depends on the used GIC model */
63 int max_vcpus;
64
62 /* Interrupt controller */ 65 /* Interrupt controller */
63 struct vgic_dist vgic; 66 struct vgic_dist vgic;
64 67
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index dd243969bfc3..1c0e9dbabe6d 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -33,6 +33,7 @@
33#define VGIC_V2_MAX_LRS (1 << 6) 33#define VGIC_V2_MAX_LRS (1 << 6)
34#define VGIC_V3_MAX_LRS 16 34#define VGIC_V3_MAX_LRS 16
35#define VGIC_MAX_IRQS 1024 35#define VGIC_MAX_IRQS 1024
36#define VGIC_V2_MAX_CPUS 8
36 37
37/* Sanity checks... */ 38/* Sanity checks... */
38#if (KVM_MAX_VCPUS > 8) 39#if (KVM_MAX_VCPUS > 8)
@@ -132,6 +133,7 @@ struct vgic_params {
132 unsigned int maint_irq; 133 unsigned int maint_irq;
133 /* Virtual control interface base address */ 134 /* Virtual control interface base address */
134 void __iomem *vctrl_base; 135 void __iomem *vctrl_base;
136 int max_gic_vcpus;
135}; 137};
136 138
137struct vgic_vm_ops { 139struct vgic_vm_ops {
@@ -289,6 +291,7 @@ struct kvm_exit_mmio;
289int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write); 291int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write);
290int kvm_vgic_hyp_init(void); 292int kvm_vgic_hyp_init(void);
291int kvm_vgic_map_resources(struct kvm *kvm); 293int kvm_vgic_map_resources(struct kvm *kvm);
294int kvm_vgic_get_max_vcpus(void);
292int kvm_vgic_create(struct kvm *kvm, u32 type); 295int kvm_vgic_create(struct kvm *kvm, u32 type);
293void kvm_vgic_destroy(struct kvm *kvm); 296void kvm_vgic_destroy(struct kvm *kvm);
294void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu); 297void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu);
@@ -393,6 +396,11 @@ static inline bool vgic_ready(struct kvm *kvm)
393{ 396{
394 return true; 397 return true;
395} 398}
399
400static inline int kvm_vgic_get_max_vcpus(void)
401{
402 return KVM_MAX_VCPUS;
403}
396#endif 404#endif
397 405
398#endif 406#endif
diff --git a/virt/kvm/arm/vgic-v2.c b/virt/kvm/arm/vgic-v2.c
index e1cd3cb95903..e8b82b289844 100644
--- a/virt/kvm/arm/vgic-v2.c
+++ b/virt/kvm/arm/vgic-v2.c
@@ -237,6 +237,7 @@ int vgic_v2_probe(struct device_node *vgic_node,
237 vctrl_res.start, vgic->maint_irq); 237 vctrl_res.start, vgic->maint_irq);
238 238
239 vgic->type = VGIC_V2; 239 vgic->type = VGIC_V2;
240 vgic->max_gic_vcpus = VGIC_V2_MAX_CPUS;
240 *ops = &vgic_v2_ops; 241 *ops = &vgic_v2_ops;
241 *params = vgic; 242 *params = vgic;
242 goto out; 243 goto out;
diff --git a/virt/kvm/arm/vgic-v3.c b/virt/kvm/arm/vgic-v3.c
index d14c75f4a33b..ea39bad4b004 100644
--- a/virt/kvm/arm/vgic-v3.c
+++ b/virt/kvm/arm/vgic-v3.c
@@ -235,6 +235,7 @@ int vgic_v3_probe(struct device_node *vgic_node,
235 vgic->vcpu_base = vcpu_res.start; 235 vgic->vcpu_base = vcpu_res.start;
236 vgic->vctrl_base = NULL; 236 vgic->vctrl_base = NULL;
237 vgic->type = VGIC_V3; 237 vgic->type = VGIC_V3;
238 vgic->max_gic_vcpus = KVM_MAX_VCPUS;
238 239
239 kvm_info("%s@%llx IRQ%d\n", vgic_node->name, 240 kvm_info("%s@%llx IRQ%d\n", vgic_node->name,
240 vcpu_res.start, vgic->maint_irq); 241 vcpu_res.start, vgic->maint_irq);
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 1c3b75eb28f0..2126bf5b0035 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -1878,6 +1878,17 @@ static int vgic_vcpu_init_maps(struct kvm_vcpu *vcpu, int nr_irqs)
1878 return 0; 1878 return 0;
1879} 1879}
1880 1880
1881/**
1882 * kvm_vgic_get_max_vcpus - Get the maximum number of VCPUs allowed by HW
1883 *
1884 * The host's GIC naturally limits the maximum amount of VCPUs a guest
1885 * can use.
1886 */
1887int kvm_vgic_get_max_vcpus(void)
1888{
1889 return vgic->max_gic_vcpus;
1890}
1891
1881void kvm_vgic_destroy(struct kvm *kvm) 1892void kvm_vgic_destroy(struct kvm *kvm)
1882{ 1893{
1883 struct vgic_dist *dist = &kvm->arch.vgic; 1894 struct vgic_dist *dist = &kvm->arch.vgic;
@@ -2072,6 +2083,8 @@ static void vgic_v2_init_emulation(struct kvm *kvm)
2072 dist->vm_ops.add_sgi_source = vgic_v2_add_sgi_source; 2083 dist->vm_ops.add_sgi_source = vgic_v2_add_sgi_source;
2073 dist->vm_ops.init_model = vgic_v2_init_model; 2084 dist->vm_ops.init_model = vgic_v2_init_model;
2074 dist->vm_ops.map_resources = vgic_v2_map_resources; 2085 dist->vm_ops.map_resources = vgic_v2_map_resources;
2086
2087 kvm->arch.max_vcpus = VGIC_V2_MAX_CPUS;
2075} 2088}
2076 2089
2077static int init_vgic_model(struct kvm *kvm, int type) 2090static int init_vgic_model(struct kvm *kvm, int type)
@@ -2084,6 +2097,9 @@ static int init_vgic_model(struct kvm *kvm, int type)
2084 return -ENODEV; 2097 return -ENODEV;
2085 } 2098 }
2086 2099
2100 if (atomic_read(&kvm->online_vcpus) > kvm->arch.max_vcpus)
2101 return -E2BIG;
2102
2087 return 0; 2103 return 0;
2088} 2104}
2089 2105