summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--virt/kvm/coalesced_mmio.c42
1 files changed, 27 insertions, 15 deletions
diff --git a/virt/kvm/coalesced_mmio.c b/virt/kvm/coalesced_mmio.c
index fc8487564d1f..ae075dc0890d 100644
--- a/virt/kvm/coalesced_mmio.c
+++ b/virt/kvm/coalesced_mmio.c
@@ -25,23 +25,8 @@ static int coalesced_mmio_in_range(struct kvm_coalesced_mmio_dev *dev,
gpa_t addr, int len)
{
struct kvm_coalesced_mmio_zone *zone;
- struct kvm_coalesced_mmio_ring *ring;
- unsigned avail;
int i;
- /* Are we able to batch it ? */
-
- /* last is the first free entry
- * check if we don't meet the first used entry
- * there is always one unused entry in the buffer
- */
- ring = dev->kvm->coalesced_mmio_ring;
- avail = (ring->first - ring->last - 1) % KVM_COALESCED_MMIO_MAX;
- if (avail < KVM_MAX_VCPUS) {
- /* full */
- return 0;
- }
-
/* is it in a batchable area ? */
for (i = 0; i < dev->nb_zones; i++) {
@@ -58,16 +43,43 @@ static int coalesced_mmio_in_range(struct kvm_coalesced_mmio_dev *dev,
return 0;
}
+static int coalesced_mmio_has_room(struct kvm_coalesced_mmio_dev *dev)
+{
+ struct kvm_coalesced_mmio_ring *ring;
+ unsigned avail;
+
+ /* Are we able to batch it ? */
+
+ /* last is the first free entry
+ * check if we don't meet the first used entry
+ * there is always one unused entry in the buffer
+ */
+ ring = dev->kvm->coalesced_mmio_ring;
+ avail = (ring->first - ring->last - 1) % KVM_COALESCED_MMIO_MAX;
+ if (avail == 0) {
+ /* full */
+ return 0;
+ }
+
+ return 1;
+}
+
static int coalesced_mmio_write(struct kvm_io_device *this,
gpa_t addr, int len, const void *val)
{
struct kvm_coalesced_mmio_dev *dev = to_mmio(this);
struct kvm_coalesced_mmio_ring *ring = dev->kvm->coalesced_mmio_ring;
+
if (!coalesced_mmio_in_range(dev, addr, len))
return -EOPNOTSUPP;
spin_lock(&dev->lock);
+ if (!coalesced_mmio_has_room(dev)) {
+ spin_unlock(&dev->lock);
+ return -EOPNOTSUPP;
+ }
+
/* copy data in first free entry of the ring */
ring->coalesced_mmio[ring->last].phys_addr = addr;