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 @@ | |||
66 | MODULE_AUTHOR("Qumranet"); | 66 | MODULE_AUTHOR("Qumranet"); |
67 | MODULE_LICENSE("GPL"); | 67 | MODULE_LICENSE("GPL"); |
68 | 68 | ||
69 | /* halt polling only reduces halt latency by 5-7 us, 500us is enough */ | 69 | /* Architectures should define their poll value according to the halt latency */ |
70 | static unsigned int halt_poll_ns = 500000; | 70 | static unsigned int halt_poll_ns = KVM_HALT_POLL_NS_DEFAULT; |
71 | module_param(halt_poll_ns, uint, S_IRUGO | S_IWUSR); | 71 | module_param(halt_poll_ns, uint, S_IRUGO | S_IWUSR); |
72 | 72 | ||
73 | /* Default doubles per-vcpu halt_poll_ns. */ | 73 | /* Default doubles per-vcpu halt_poll_ns. */ |
@@ -2004,6 +2004,7 @@ void kvm_vcpu_block(struct kvm_vcpu *vcpu) | |||
2004 | if (vcpu->halt_poll_ns) { | 2004 | if (vcpu->halt_poll_ns) { |
2005 | ktime_t stop = ktime_add_ns(ktime_get(), vcpu->halt_poll_ns); | 2005 | ktime_t stop = ktime_add_ns(ktime_get(), vcpu->halt_poll_ns); |
2006 | 2006 | ||
2007 | ++vcpu->stat.halt_attempted_poll; | ||
2007 | do { | 2008 | do { |
2008 | /* | 2009 | /* |
2009 | * This sets KVM_REQ_UNHALT if an interrupt | 2010 | * This sets KVM_REQ_UNHALT if an interrupt |
@@ -2043,7 +2044,8 @@ out: | |||
2043 | else if (vcpu->halt_poll_ns < halt_poll_ns && | 2044 | else if (vcpu->halt_poll_ns < halt_poll_ns && |
2044 | block_ns < halt_poll_ns) | 2045 | block_ns < halt_poll_ns) |
2045 | grow_halt_poll_ns(vcpu); | 2046 | grow_halt_poll_ns(vcpu); |
2046 | } | 2047 | } else |
2048 | vcpu->halt_poll_ns = 0; | ||
2047 | 2049 | ||
2048 | trace_kvm_vcpu_wakeup(block_ns, waited); | 2050 | trace_kvm_vcpu_wakeup(block_ns, waited); |
2049 | } | 2051 | } |
@@ -3156,10 +3158,25 @@ static void kvm_io_bus_destroy(struct kvm_io_bus *bus) | |||
3156 | static inline int kvm_io_bus_cmp(const struct kvm_io_range *r1, | 3158 | static inline int kvm_io_bus_cmp(const struct kvm_io_range *r1, |
3157 | const struct kvm_io_range *r2) | 3159 | const struct kvm_io_range *r2) |
3158 | { | 3160 | { |
3159 | if (r1->addr < r2->addr) | 3161 | gpa_t addr1 = r1->addr; |
3162 | gpa_t addr2 = r2->addr; | ||
3163 | |||
3164 | if (addr1 < addr2) | ||
3160 | return -1; | 3165 | return -1; |
3161 | if (r1->addr + r1->len > r2->addr + r2->len) | 3166 | |
3167 | /* If r2->len == 0, match the exact address. If r2->len != 0, | ||
3168 | * accept any overlapping write. Any order is acceptable for | ||
3169 | * overlapping ranges, because kvm_io_bus_get_first_dev ensures | ||
3170 | * we process all of them. | ||
3171 | */ | ||
3172 | if (r2->len) { | ||
3173 | addr1 += r1->len; | ||
3174 | addr2 += r2->len; | ||
3175 | } | ||
3176 | |||
3177 | if (addr1 > addr2) | ||
3162 | return 1; | 3178 | return 1; |
3179 | |||
3163 | return 0; | 3180 | return 0; |
3164 | } | 3181 | } |
3165 | 3182 | ||