diff options
Diffstat (limited to 'virt/kvm/kvm_main.c')
| -rw-r--r-- | virt/kvm/kvm_main.c | 23 | 
1 files changed, 20 insertions, 3 deletions
| diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index a25a73147f71..04146a2e1d81 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -2004,6 +2004,7 @@ void kvm_vcpu_block(struct kvm_vcpu *vcpu)  	if (vcpu->halt_poll_ns) {  		ktime_t stop = ktime_add_ns(ktime_get(), vcpu->halt_poll_ns); +		++vcpu->stat.halt_attempted_poll;  		do {  			/*  			 * This sets KVM_REQ_UNHALT if an interrupt @@ -2043,7 +2044,8 @@ out:  		else if (vcpu->halt_poll_ns < halt_poll_ns &&  			block_ns < halt_poll_ns)  			grow_halt_poll_ns(vcpu); -	} +	} else +		vcpu->halt_poll_ns = 0;  	trace_kvm_vcpu_wakeup(block_ns, waited);  } @@ -3156,10 +3158,25 @@ static void kvm_io_bus_destroy(struct kvm_io_bus *bus)  static inline int kvm_io_bus_cmp(const struct kvm_io_range *r1,  				 const struct kvm_io_range *r2)  { -	if (r1->addr < r2->addr) +	gpa_t addr1 = r1->addr; +	gpa_t addr2 = r2->addr; + +	if (addr1 < addr2)  		return -1; -	if (r1->addr + r1->len > r2->addr + r2->len) + +	/* If r2->len == 0, match the exact address.  If r2->len != 0, +	 * accept any overlapping write.  Any order is acceptable for +	 * overlapping ranges, because kvm_io_bus_get_first_dev ensures +	 * we process all of them. +	 */ +	if (r2->len) { +		addr1 += r1->len; +		addr2 += r2->len; +	} + +	if (addr1 > addr2)  		return 1; +  	return 0;  } |