diff options
Diffstat (limited to 'virt/kvm/kvm_main.c')
| -rw-r--r-- | virt/kvm/kvm_main.c | 27 | 
1 files changed, 22 insertions, 5 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index a25a73147f71..8db1d9361993 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -66,8 +66,8 @@  MODULE_AUTHOR("Qumranet");  MODULE_LICENSE("GPL"); -/* halt polling only reduces halt latency by 5-7 us, 500us is enough */ -static unsigned int halt_poll_ns = 500000; +/* Architectures should define their poll value according to the halt latency */ +static unsigned int halt_poll_ns = KVM_HALT_POLL_NS_DEFAULT;  module_param(halt_poll_ns, uint, S_IRUGO | S_IWUSR);  /* Default doubles per-vcpu halt_poll_ns. */ @@ -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;  }  |