Merge remote-tracking branches 'regulator/fix/anatop', 'regulator/fix/gpio', 'regulat...
[firefly-linux-kernel-4.4.55.git] / virt / kvm / kvm_main.c
index eb4c9d2849dc76b18e92ccba55f1a36cc8b1b08b..04146a2e1d8191e3e152954824594555884f5f6d 100644 (file)
@@ -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
@@ -3157,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;
 }