diff options
| author | Rodrigo Vivi <[email protected]> | 2018-07-23 09:13:12 -0700 | 
|---|---|---|
| committer | Rodrigo Vivi <[email protected]> | 2018-07-23 09:13:12 -0700 | 
| commit | c74a7469f97c0f40b46e82ee979f9fb1bb6e847c (patch) | |
| tree | f2690a1a916b73ef94657fbf0e0141ae57701825 /virt/kvm/arm/vgic/vgic-kvm-device.c | |
| parent | 6f15a7de86c8cf2dc09fc9e6d07047efa40ef809 (diff) | |
| parent | 500775074f88d9cf5416bed2ca19592812d62c41 (diff) | |
Merge drm/drm-next into drm-intel-next-queued
We need a backmerge to get DP_DPCD_REV_14 before we push other
i915 changes to dinq that could break compilation.
Signed-off-by: Rodrigo Vivi <[email protected]>
Diffstat (limited to 'virt/kvm/arm/vgic/vgic-kvm-device.c')
| -rw-r--r-- | virt/kvm/arm/vgic/vgic-kvm-device.c | 53 | 
1 files changed, 50 insertions, 3 deletions
| diff --git a/virt/kvm/arm/vgic/vgic-kvm-device.c b/virt/kvm/arm/vgic/vgic-kvm-device.c index 10ae6f394b71..6ada2432e37c 100644 --- a/virt/kvm/arm/vgic/vgic-kvm-device.c +++ b/virt/kvm/arm/vgic/vgic-kvm-device.c @@ -66,6 +66,7 @@ int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write)  	int r = 0;  	struct vgic_dist *vgic = &kvm->arch.vgic;  	phys_addr_t *addr_ptr, alignment; +	u64 undef_value = VGIC_ADDR_UNDEF;  	mutex_lock(&kvm->lock);  	switch (type) { @@ -84,16 +85,61 @@ int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write)  		addr_ptr = &vgic->vgic_dist_base;  		alignment = SZ_64K;  		break; -	case KVM_VGIC_V3_ADDR_TYPE_REDIST: +	case KVM_VGIC_V3_ADDR_TYPE_REDIST: { +		struct vgic_redist_region *rdreg; +  		r = vgic_check_type(kvm, KVM_DEV_TYPE_ARM_VGIC_V3);  		if (r)  			break;  		if (write) { -			r = vgic_v3_set_redist_base(kvm, *addr); +			r = vgic_v3_set_redist_base(kvm, 0, *addr, 0);  			goto out;  		} -		addr_ptr = &vgic->vgic_redist_base; +		rdreg = list_first_entry(&vgic->rd_regions, +					 struct vgic_redist_region, list); +		if (!rdreg) +			addr_ptr = &undef_value; +		else +			addr_ptr = &rdreg->base;  		break; +	} +	case KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION: +	{ +		struct vgic_redist_region *rdreg; +		u8 index; + +		r = vgic_check_type(kvm, KVM_DEV_TYPE_ARM_VGIC_V3); +		if (r) +			break; + +		index = *addr & KVM_VGIC_V3_RDIST_INDEX_MASK; + +		if (write) { +			gpa_t base = *addr & KVM_VGIC_V3_RDIST_BASE_MASK; +			u32 count = (*addr & KVM_VGIC_V3_RDIST_COUNT_MASK) +					>> KVM_VGIC_V3_RDIST_COUNT_SHIFT; +			u8 flags = (*addr & KVM_VGIC_V3_RDIST_FLAGS_MASK) +					>> KVM_VGIC_V3_RDIST_FLAGS_SHIFT; + +			if (!count || flags) +				r = -EINVAL; +			else +				r = vgic_v3_set_redist_base(kvm, index, +							    base, count); +			goto out; +		} + +		rdreg = vgic_v3_rdist_region_from_index(kvm, index); +		if (!rdreg) { +			r = -ENOENT; +			goto out; +		} + +		*addr = index; +		*addr |= rdreg->base; +		*addr |= (u64)rdreg->count << KVM_VGIC_V3_RDIST_COUNT_SHIFT; +		goto out; +	}  	default:  		r = -ENODEV;  	} @@ -665,6 +711,7 @@ static int vgic_v3_has_attr(struct kvm_device *dev,  		switch (attr->attr) {  		case KVM_VGIC_V3_ADDR_TYPE_DIST:  		case KVM_VGIC_V3_ADDR_TYPE_REDIST: +		case KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION:  			return 0;  		}  		break; |