mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	KVM: arm/arm64: Fix GICv4 ITS initialization issues
We should only try to initialize GICv4 data structures on a GICv4 capable system. Move the vgic_supports_direct_msis() check inito vgic_v4_init() so that any KVM VGIC initialization path does not fail on non-GICv4 systems. Also be slightly more strict in the checking of the return value in vgic_its_create, and only error out on negative return values from the vgic_v4_init() function. This is important because the kvm device code only treats negative values as errors and only cleans up in this case. Errornously treating a positive return value as an error from the vgic_v4_init() function can lead to NULL pointer dereferences, as has recently been observed. Acked-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
This commit is contained in:
		
							parent
							
								
									ed8703a506
								
							
						
					
					
						commit
						3d1ad640f8
					
				
					 3 changed files with 7 additions and 6 deletions
				
			
		| 
						 | 
					@ -285,11 +285,9 @@ int vgic_init(struct kvm *kvm)
 | 
				
			||||||
	if (ret)
 | 
						if (ret)
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (vgic_supports_direct_msis(kvm)) {
 | 
						ret = vgic_v4_init(kvm);
 | 
				
			||||||
		ret = vgic_v4_init(kvm);
 | 
						if (ret)
 | 
				
			||||||
		if (ret)
 | 
							goto out;
 | 
				
			||||||
			goto out;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	kvm_for_each_vcpu(i, vcpu, kvm)
 | 
						kvm_for_each_vcpu(i, vcpu, kvm)
 | 
				
			||||||
		kvm_vgic_vcpu_enable(vcpu);
 | 
							kvm_vgic_vcpu_enable(vcpu);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1673,7 +1673,7 @@ static int vgic_its_create(struct kvm_device *dev, u32 type)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (vgic_initialized(dev->kvm)) {
 | 
						if (vgic_initialized(dev->kvm)) {
 | 
				
			||||||
		int ret = vgic_v4_init(dev->kvm);
 | 
							int ret = vgic_v4_init(dev->kvm);
 | 
				
			||||||
		if (ret) {
 | 
							if (ret < 0) {
 | 
				
			||||||
			kfree(its);
 | 
								kfree(its);
 | 
				
			||||||
			return ret;
 | 
								return ret;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -118,6 +118,9 @@ int vgic_v4_init(struct kvm *kvm)
 | 
				
			||||||
	struct kvm_vcpu *vcpu;
 | 
						struct kvm_vcpu *vcpu;
 | 
				
			||||||
	int i, nr_vcpus, ret;
 | 
						int i, nr_vcpus, ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!vgic_supports_direct_msis(kvm))
 | 
				
			||||||
 | 
							return 0; /* Nothing to see here... move along. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (dist->its_vm.vpes)
 | 
						if (dist->its_vm.vpes)
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue