diff options
Diffstat (limited to 'arch/s390/kvm/interrupt.c')
| -rw-r--r-- | arch/s390/kvm/interrupt.c | 15 | 
1 files changed, 11 insertions, 4 deletions
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index 82162867f378..9dde4d7d8704 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c @@ -14,6 +14,7 @@  #include <linux/kvm_host.h>  #include <linux/hrtimer.h>  #include <linux/mmu_context.h> +#include <linux/nospec.h>  #include <linux/signal.h>  #include <linux/slab.h>  #include <linux/bitmap.h> @@ -2307,6 +2308,7 @@ static struct s390_io_adapter *get_io_adapter(struct kvm *kvm, unsigned int id)  {  	if (id >= MAX_S390_IO_ADAPTERS)  		return NULL; +	id = array_index_nospec(id, MAX_S390_IO_ADAPTERS);  	return kvm->arch.adapters[id];  } @@ -2320,8 +2322,13 @@ static int register_io_adapter(struct kvm_device *dev,  			   (void __user *)attr->addr, sizeof(adapter_info)))  		return -EFAULT; -	if ((adapter_info.id >= MAX_S390_IO_ADAPTERS) || -	    (dev->kvm->arch.adapters[adapter_info.id] != NULL)) +	if (adapter_info.id >= MAX_S390_IO_ADAPTERS) +		return -EINVAL; + +	adapter_info.id = array_index_nospec(adapter_info.id, +					     MAX_S390_IO_ADAPTERS); + +	if (dev->kvm->arch.adapters[adapter_info.id] != NULL)  		return -EINVAL;  	adapter = kzalloc(sizeof(*adapter), GFP_KERNEL); @@ -2376,7 +2383,7 @@ static int kvm_s390_adapter_map(struct kvm *kvm, unsigned int id, __u64 addr)  		ret = -EFAULT;  		goto out;  	} -	ret = get_user_pages_fast(map->addr, 1, 1, &map->page); +	ret = get_user_pages_fast(map->addr, 1, FOLL_WRITE, &map->page);  	if (ret < 0)  		goto out;  	BUG_ON(ret != 1); @@ -3194,7 +3201,7 @@ out:  }  EXPORT_SYMBOL_GPL(kvm_s390_gisc_unregister); -static void gib_alert_irq_handler(struct airq_struct *airq) +static void gib_alert_irq_handler(struct airq_struct *airq, bool floating)  {  	inc_irq_stat(IRQIO_GAL);  	process_gib_alert_list();  |