On Wed, 2011-07-06 at 15:39 +0300, Avi Kivity wrote:
> On 07/06/2011 07:37 AM, Sasha Levin wrote:
> > The new flag allows passing a connected socket instead of an
> > eventfd to be notified of writes or reads to the specified memory region.
> >
> > Instead of signaling an event, On write - the value written to the memory
> > region is written to the pipe.
> > On read - a notification of the read is sent to the host, and a response
> > is expected with the value to be 'read'.
> >
> > Using a socket instead of an eventfd is usefull when any value can be
> > written to the memory region but we're interested in recieving the
> > actual value instead of just a notification.
> >
> > A simple example for practical use is the serial port. we are not
> > interested in an exit every time a char is written to the port, but
> > we do need to know what was written so we could handle it on the guest.
> >
> >
> >
> > @@ -534,6 +607,7 @@ ioeventfd_read(struct kvm_io_device *this, gpa_t addr, 
> > int len,
> >             void *val)
> >   {
> >     struct _ioeventfd *p = to_ioeventfd(this);
> > +   struct kvm_ioeventfd_data data;
> >
> >     /* Exit if signaling on reads isn't requested */
> >     if (!p->track_reads)
> > @@ -542,7 +616,21 @@ ioeventfd_read(struct kvm_io_device *this, gpa_t addr, 
> > int len,
> >     if (!ioeventfd_in_range(p, addr, len, val))
> >             return -EOPNOTSUPP;
> >
> > -   eventfd_signal(p->eventfd, 1);
> > +   data = (struct kvm_ioeventfd_data) {
> > +           .addr = addr,
> > +           .len = len,
> > +           .is_write = 0,
> > +   };
> > +
> > +   if (p->sock) {
> > +           socket_write(p->sock,&data, sizeof(data));
> > +           socket_read(p->sock,&data, sizeof(data));
> > +           set_val(val, len, data.data);
> > +   } else {
> > +           set_val(val, len, p->datamatch);
> > +           eventfd_signal(p->eventfd, 1);
> > +   }
> > +
> >     return 0;
> >   }
> 
> If there are two reads on the same ioeventfd range, then the responses 
> can mix up.  Need to make sure we get the right response.
> 
> Note that a mutex on the ioeventfd structure is insufficient, since the 
> same socket may be used for multiple ranges.
> 
> One way out is to require that sockets not be shared among vcpus (there 
> can be only one outstanding read per vcpu).  It seems heavy handed though.
> 

What about something as follows:

This requires an addition of a mutex to struct ioeventfd.

1. When adding a new ioeventfd, scan exiting ioeventfds (we already do
it anyway) and check whether another ioeventfd is using the socket
already.

2. If the existing ioeventfd doesn't have a mutex assigned, create a new
mutex and assign it to both ioeventfds.

3. If the existing ioeventfd already has a mutex assigned, copy it to
the new ioeventfd.

4. When removing an ioeventfd, do everything the other way around :)

This mutex can be used to lock the write/read pair.

-- 

Sasha.

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to