Skip to contentSkip to conversation

kvm: allow arbitrarily sized mmio ioeventfd

PATCH Applied Michael S. Tsirkin 4 participants 6 messages Mar 20, 2012 – Mar 22, 2012

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 kvm: allow arbitrarily sized mmio ioeventfd

We use a 2 byte ioeventfd for virtio memory,
add support for this.

---
 hw/ivshmem.c |    8 ++++----
 kvm-all.c    |   15 ++++++++-------
 kvm-stub.c   |    2 +-
 kvm.h        |    3 ++-
 4 files changed, 15 insertions(+), 13 deletions(-)
hw/ivshmem.c +4 -4
index 5ebf840..f02530c 100644
@@ -354,8 +354,8 @@ static void close_guest_eventfds(IVShmemState *s, int posn)
     guest_curr_max = s->peers[posn].nb_eventfds;
 
     for (i = 0; i < guest_curr_max; i++) {
-        kvm_set_ioeventfd_mmio_long(s->peers[posn].eventfds[i],
-                    s->mmio_addr + DOORBELL, (posn << 16) | i, 0);
+        kvm_set_ioeventfd_mmio(s->peers[posn].eventfds[i],
+                    s->mmio_addr + DOORBELL, (posn << 16) | i, 0, 4);
         close(s->peers[posn].eventfds[i]);
     }
 
@@ -500,8 +500,8 @@ static void ivshmem_read(void *opaque, const uint8_t * buf, int flags)
     }
 
     if (ivshmem_has_feature(s, IVSHMEM_IOEVENTFD)) {
-        if (kvm_set_ioeventfd_mmio_long(incoming_fd, s->mmio_addr + DOORBELL,
-                        (incoming_posn << 16) | guest_max_eventfd, 1) < 0) {
+        if (kvm_set_ioeventfd_mmio(incoming_fd, s->mmio_addr + DOORBELL,
+                        (incoming_posn << 16) | guest_max_eventfd, 1, 4) < 0) {
             fprintf(stderr, "ivshmem: ioeventfd not available\n");
         }
     }
kvm-all.c +8 -7
index 42e5e23..bcf0dbe 100644
@@ -744,10 +744,10 @@ static void kvm_mem_ioeventfd_add(MemoryRegionSection *section,
 {
     int r;
 
-    assert(match_data && section->size == 4);
+    assert(match_data && section->size <= 8);
 
-    r = kvm_set_ioeventfd_mmio_long(fd, section->offset_within_address_space,
-                                    data, true);
+    r = kvm_set_ioeventfd_mmio(fd, section->offset_within_address_space,
+                               data, true, section->size);
     if (r < 0) {
         abort();
     }
@@ -758,8 +758,8 @@ static void kvm_mem_ioeventfd_del(MemoryRegionSection *section,
 {
     int r;
 
-    r = kvm_set_ioeventfd_mmio_long(fd, section->offset_within_address_space,
-                                    data, false);
+    r = kvm_set_ioeventfd_mmio(fd, section->offset_within_address_space,
+                               data, false, section->size);
     if (r < 0) {
         abort();
     }
@@ -1639,14 +1639,15 @@ int kvm_set_signal_mask(CPUArchState *env, const sigset_t *sigset)
     return r;
 }
 
-int kvm_set_ioeventfd_mmio_long(int fd, uint32_t addr, uint32_t val, bool assign)
+int kvm_set_ioeventfd_mmio(int fd, uint32_t addr, uint32_t val, bool assign,
+                           uint32_t size)
 {
     int ret;
     struct kvm_ioeventfd iofd;
 
     iofd.datamatch = val;
     iofd.addr = addr;
-    iofd.len = 4;
+    iofd.len = size;
     iofd.flags = KVM_IOEVENTFD_FLAG_DATAMATCH;
     iofd.fd = fd;
 
kvm-stub.c +1 -1
index 69a1228..0d426db 100644
@@ -120,7 +120,7 @@ int kvm_set_ioeventfd_pio_word(int fd, uint16_t addr, uint16_t val, bool assign)
     return -ENOSYS;
 }
 
-int kvm_set_ioeventfd_mmio_long(int fd, uint32_t adr, uint32_t val, bool assign)
+int kvm_set_ioeventfd_mmio(int fd, uint32_t adr, uint32_t val, bool assign, uint32_t len)
 {
     return -ENOSYS;
 }
kvm.h +2 -1
index 330f17b..9bdbdb0 100644
@@ -210,7 +210,8 @@ int kvm_physical_memory_addr_from_host(KVMState *s, void *ram_addr,
 #endif
 
 #endif
-int kvm_set_ioeventfd_mmio_long(int fd, uint32_t adr, uint32_t val, bool assign);
+int kvm_set_ioeventfd_mmio(int fd, uint32_t adr, uint32_t val, bool assign,
+                           uint32_t size);
 
 int kvm_set_ioeventfd_pio_word(int fd, uint16_t adr, uint16_t val, bool assign);
 #endif
Signature · 1 line
1.7.9.111.gf3fb0
Reviewed-by on v1 1/1
#1 lore raw

----- Original Message -----

Quoted 4 lines

We use a 2 byte ioeventfd for virtio memory,
add support for this.

Quoted 134 lines
---
 hw/ivshmem.c |    8 ++++----
 kvm-all.c    |   15 ++++++++-------
 kvm-stub.c   |    2 +-
 kvm.h        |    3 ++-
 4 files changed, 15 insertions(+), 13 deletions(-)
hw/ivshmem.c +2 -2
index 5ebf840..f02530c 100644
@@ -354,8 +354,8 @@ static void close_guest_eventfds(IVShmemState *s,
 int posn)
     guest_curr_max = s->peers[posn].nb_eventfds;
 
     for (i = 0; i < guest_curr_max; i++) {
-        kvm_set_ioeventfd_mmio_long(s->peers[posn].eventfds[i],
-                    s->mmio_addr + DOORBELL, (posn << 16) | i, 0);
+        kvm_set_ioeventfd_mmio(s->peers[posn].eventfds[i],
+                    s->mmio_addr + DOORBELL, (posn << 16) | i, 0,
 4);
         close(s->peers[posn].eventfds[i]);
     }
hw/ivshmem.c +1 -2
@@ -500,8 +500,8 @@ static void ivshmem_read(void *opaque, const
 uint8_t * buf, int flags)
     }
 
     if (ivshmem_has_feature(s, IVSHMEM_IOEVENTFD)) {
-        if (kvm_set_ioeventfd_mmio_long(incoming_fd, s->mmio_addr +
 DOORBELL,
-                        (incoming_posn << 16) | guest_max_eventfd,
 1) < 0) {
+        if (kvm_set_ioeventfd_mmio(incoming_fd, s->mmio_addr +

DOORBELL,
+ (incoming_posn << 16) | guest_max_eventfd,

1, 4) < 0) {
             fprintf(stderr, "ivshmem: ioeventfd not available\n");
         }
     }
kvm-all.c +3 -3
index 42e5e23..bcf0dbe 100644
@@ -744,10 +744,10 @@ static void
 kvm_mem_ioeventfd_add(MemoryRegionSection *section,
 {
     int r;
 
-    assert(match_data && section->size == 4);
+    assert(match_data && section->size <= 8);
 
-    r = kvm_set_ioeventfd_mmio_long(fd,
 section->offset_within_address_space,
-                                    data, true);
+    r = kvm_set_ioeventfd_mmio(fd,
 section->offset_within_address_space,
+                               data, true, section->size);
     if (r < 0) {
         abort();
     }
kvm-all.c +2 -2
@@ -758,8 +758,8 @@ static void
 kvm_mem_ioeventfd_del(MemoryRegionSection *section,
 {
     int r;
 
-    r = kvm_set_ioeventfd_mmio_long(fd,
 section->offset_within_address_space,
-                                    data, false);
+    r = kvm_set_ioeventfd_mmio(fd,
 section->offset_within_address_space,
+                               data, false, section->size);
     if (r < 0) {
         abort();
     }
kvm-all.c +3 -2
@@ -1639,14 +1639,15 @@ int kvm_set_signal_mask(CPUArchState *env,
 const sigset_t *sigset)
     return r;
 }
 
-int kvm_set_ioeventfd_mmio_long(int fd, uint32_t addr, uint32_t val,
 bool assign)
+int kvm_set_ioeventfd_mmio(int fd, uint32_t addr, uint32_t val, bool
 assign,
+                           uint32_t size)
 {
     int ret;
     struct kvm_ioeventfd iofd;
 
     iofd.datamatch = val;
     iofd.addr = addr;
-    iofd.len = 4;
+    iofd.len = size;
     iofd.flags = KVM_IOEVENTFD_FLAG_DATAMATCH;
     iofd.fd = fd;
kvm-stub.c +1 -1
index 69a1228..0d426db 100644
@@ -120,7 +120,7 @@ int kvm_set_ioeventfd_pio_word(int fd, uint16_t
 addr, uint16_t val, bool assign)
     return -ENOSYS;
 }
 
-int kvm_set_ioeventfd_mmio_long(int fd, uint32_t adr, uint32_t val,
 bool assign)
+int kvm_set_ioeventfd_mmio(int fd, uint32_t adr, uint32_t val, bool
 assign, uint32_t len)
 {
     return -ENOSYS;

}

kvm.h +2 -1
index 330f17b..9bdbdb0 100644
@@ -210,7 +210,8 @@ int kvm_physical_memory_addr_from_host(KVMState
 *s, void *ram_addr,
 #endif
 
 #endif
-int kvm_set_ioeventfd_mmio_long(int fd, uint32_t adr, uint32_t val,
 bool assign);
+int kvm_set_ioeventfd_mmio(int fd, uint32_t adr, uint32_t val, bool
 assign,
+                           uint32_t size);

int kvm_set_ioeventfd_pio_word(int fd, uint16_t adr, uint16_t val, bool assign);
#endif
--
1.7.9.111.gf3fb0

#2 lore raw
In reply to Michael S. Tsirkin
Quoted 42 lines · Michael S. Tsirkin

We use a 2 byte ioeventfd for virtio memory,
add support for this.

---
 hw/ivshmem.c |    8 ++++----
 kvm-all.c    |   15 ++++++++-------
 kvm-stub.c   |    2 +-
 kvm.h        |    3 ++-
 4 files changed, 15 insertions(+), 13 deletions(-)
hw/ivshmem.c +4 -4
index 5ebf840..f02530c 100644
@@ -354,8 +354,8 @@ static void close_guest_eventfds(IVShmemState *s, int posn)
     guest_curr_max = s->peers[posn].nb_eventfds;
 
     for (i = 0; i < guest_curr_max; i++) {
-        kvm_set_ioeventfd_mmio_long(s->peers[posn].eventfds[i],
-                    s->mmio_addr + DOORBELL, (posn << 16) | i, 0);
+        kvm_set_ioeventfd_mmio(s->peers[posn].eventfds[i],
+                    s->mmio_addr + DOORBELL, (posn << 16) | i, 0, 4);
         close(s->peers[posn].eventfds[i]);
     }
 
@@ -500,8 +500,8 @@ static void ivshmem_read(void *opaque, const uint8_t * buf, int flags)
     }
 
     if (ivshmem_has_feature(s, IVSHMEM_IOEVENTFD)) {
-        if (kvm_set_ioeventfd_mmio_long(incoming_fd, s->mmio_addr + DOORBELL,
-                        (incoming_posn << 16) | guest_max_eventfd, 1) < 0) {
+        if (kvm_set_ioeventfd_mmio(incoming_fd, s->mmio_addr + DOORBELL,
+                        (incoming_posn << 16) | guest_max_eventfd, 1, 4) < 0) {
             fprintf(stderr, "ivshmem: ioeventfd not available\n");
         }
     }
kvm-all.c +0 -0
index 42e5e23..bcf0dbe 100644

kvm-all.c static void kvm_mem_ioeventfd_add(MemoryRegionSection *section, · line 747

Quoted 5 lines
kvm-all.c +1 -1
@@ -744,10 +744,10 @@ static void kvm_mem_ioeventfd_add(MemoryRegionSection *section,
 {
     int r;
 
-    assert(match_data && section->size == 4);
+    assert(match_data && section->size <= 8);

Probably nitpicking, but does it also work with non-power-of-two sizes?

Jan

Signature · 2 lines
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux
#3 lore raw
Quoted 46 lines · Jan Kiszka
Quoted 45 lines · Michael S. Tsirkin

We use a 2 byte ioeventfd for virtio memory,
add support for this.

---
 hw/ivshmem.c |    8 ++++----
 kvm-all.c    |   15 ++++++++-------
 kvm-stub.c   |    2 +-
 kvm.h        |    3 ++-
 4 files changed, 15 insertions(+), 13 deletions(-)
hw/ivshmem.c +4 -4
index 5ebf840..f02530c 100644
@@ -354,8 +354,8 @@ static void close_guest_eventfds(IVShmemState *s, int posn)
     guest_curr_max = s->peers[posn].nb_eventfds;
 
     for (i = 0; i < guest_curr_max; i++) {
-        kvm_set_ioeventfd_mmio_long(s->peers[posn].eventfds[i],
-                    s->mmio_addr + DOORBELL, (posn << 16) | i, 0);
+        kvm_set_ioeventfd_mmio(s->peers[posn].eventfds[i],
+                    s->mmio_addr + DOORBELL, (posn << 16) | i, 0, 4);
         close(s->peers[posn].eventfds[i]);
     }
 
@@ -500,8 +500,8 @@ static void ivshmem_read(void *opaque, const uint8_t * buf, int flags)
     }
 
     if (ivshmem_has_feature(s, IVSHMEM_IOEVENTFD)) {
-        if (kvm_set_ioeventfd_mmio_long(incoming_fd, s->mmio_addr + DOORBELL,
-                        (incoming_posn << 16) | guest_max_eventfd, 1) < 0) {
+        if (kvm_set_ioeventfd_mmio(incoming_fd, s->mmio_addr + DOORBELL,
+                        (incoming_posn << 16) | guest_max_eventfd, 1, 4) < 0) {
             fprintf(stderr, "ivshmem: ioeventfd not available\n");
         }
     }
kvm-all.c +0 -0
index 42e5e23..bcf0dbe 100644
@@ -744,10 +744,10 @@ static void kvm_mem_ioeventfd_add(MemoryRegionSection *section,
 {
     int r;
 
Quoted 5 lines

kvm-all.c static void kvm_mem_ioeventfd_add(MemoryRegionSection *section, · line 747

Quoted 2 lines
kvm-all.c +1 -1
-    assert(match_data && section->size == 4);
+    assert(match_data && section->size <= 8);

Probably nitpicking, but does it also work with non-power-of-two sizes?

It won't, but it's hard to generate 3-byte writes (not impossible though).

Signature · 1 line
error compiling committee.c: too many arguments to function
#4 lore raw
In reply to Michael S. Tsirkin
Quoted 42 lines · Michael S. Tsirkin

We use a 2 byte ioeventfd for virtio memory,
add support for this.

---
 hw/ivshmem.c |    8 ++++----
 kvm-all.c    |   15 ++++++++-------
 kvm-stub.c   |    2 +-
 kvm.h        |    3 ++-
 4 files changed, 15 insertions(+), 13 deletions(-)
hw/ivshmem.c +4 -4
index 5ebf840..f02530c 100644
@@ -354,8 +354,8 @@ static void close_guest_eventfds(IVShmemState *s, int posn)
     guest_curr_max = s->peers[posn].nb_eventfds;
 
     for (i = 0; i < guest_curr_max; i++) {
-        kvm_set_ioeventfd_mmio_long(s->peers[posn].eventfds[i],
-                    s->mmio_addr + DOORBELL, (posn << 16) | i, 0);
+        kvm_set_ioeventfd_mmio(s->peers[posn].eventfds[i],
+                    s->mmio_addr + DOORBELL, (posn << 16) | i, 0, 4);
         close(s->peers[posn].eventfds[i]);
     }
 
@@ -500,8 +500,8 @@ static void ivshmem_read(void *opaque, const uint8_t * buf, int flags)
     }
 
     if (ivshmem_has_feature(s, IVSHMEM_IOEVENTFD)) {
-        if (kvm_set_ioeventfd_mmio_long(incoming_fd, s->mmio_addr + DOORBELL,
-                        (incoming_posn << 16) | guest_max_eventfd, 1) < 0) {
+        if (kvm_set_ioeventfd_mmio(incoming_fd, s->mmio_addr + DOORBELL,
+                        (incoming_posn << 16) | guest_max_eventfd, 1, 4) < 0) {
             fprintf(stderr, "ivshmem: ioeventfd not available\n");
         }
     }
kvm-all.c +0 -0
index 42e5e23..bcf0dbe 100644

kvm-all.c static void kvm_mem_ioeventfd_add(MemoryRegionSection *section, · line 747

Quoted 5 lines
kvm-all.c +1 -1
@@ -744,10 +744,10 @@ static void kvm_mem_ioeventfd_add(MemoryRegionSection *section,
 {
     int r;
 
-    assert(match_data && section->size == 4);
+    assert(match_data && section->size <= 8);

Probably nitpicking, but does it also work with non-power-of-two sizes?

Jan

Signature · 2 lines
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux
Applied
#5 lore raw
In reply to Michael S. Tsirkin
Quoted 4 lines · Michael S. Tsirkin

We use a 2 byte ioeventfd for virtio memory,
add support for this.

Applied, thanks.

Signature · 1 line
error compiling committee.c: too many arguments to function