From patchwork Wed Jul 6 04:37:56 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sasha Levin X-Patchwork-Id: 948442 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.4) with ESMTP id p664cKYn006808 for ; Wed, 6 Jul 2011 04:38:20 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751856Ab1GFEiO (ORCPT ); Wed, 6 Jul 2011 00:38:14 -0400 Received: from mail-ww0-f44.google.com ([74.125.82.44]:58854 "EHLO mail-ww0-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751585Ab1GFEiM (ORCPT ); Wed, 6 Jul 2011 00:38:12 -0400 Received: by mail-ww0-f44.google.com with SMTP id 5so6552449wwe.1 for ; Tue, 05 Jul 2011 21:38:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=9Jlu57sbNSZdZS/xgWzlIu0VpJ022Lfq9giVShddOnQ=; b=LdY/FwDwwj/P2jguLCNWSpoP6G9xLnco0QGz/kVCgjwSdwU1cgIA85c+ixuUidnpYR K+MYrAhVoX5XC6x3jFdgrgmBxPmyPsVL4TpmsXS62V2jZ4Djl2d2GzLGOLr3290T0O2L kSlCdaQ4Y6JP70kcA3dIi5axA8hUr6rbp0aCI= Received: by 10.227.198.197 with SMTP id ep5mr7227052wbb.33.1309927091796; Tue, 05 Jul 2011 21:38:11 -0700 (PDT) Received: from localhost.localdomain ([31.210.184.221]) by mx.google.com with ESMTPS id gb1sm5766713wbb.54.2011.07.05.21.38.09 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 05 Jul 2011 21:38:11 -0700 (PDT) From: Sasha Levin To: kvm@vger.kernel.org Cc: Sasha Levin , Avi Kivity , Ingo Molnar , Marcelo Tosatti , "Michael S. Tsirkin" , Pekka Enberg Subject: [PATCH 3/5] ioeventfd: Introduce KVM_IOEVENTFD_FLAG_READ Date: Wed, 6 Jul 2011 07:37:56 +0300 Message-Id: <1309927078-5983-3-git-send-email-levinsasha928@gmail.com> X-Mailer: git-send-email 1.7.6 In-Reply-To: <1309927078-5983-1-git-send-email-levinsasha928@gmail.com> References: <1309927078-5983-1-git-send-email-levinsasha928@gmail.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Wed, 06 Jul 2011 04:38:21 +0000 (UTC) The new flag specifies whether reads from the address specified in the ioeventfd will raise the event like writes do. The read value will be the one passed in datamatch. Cc: Avi Kivity Cc: Ingo Molnar Cc: Marcelo Tosatti Cc: Michael S. Tsirkin Cc: Pekka Enberg Signed-off-by: Sasha Levin --- Documentation/virtual/kvm/api.txt | 5 +++++ include/linux/kvm.h | 2 ++ virt/kvm/eventfd.c | 24 ++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 0 deletions(-) diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index 7994840..8179bc1 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt @@ -1346,10 +1346,15 @@ The following flags are defined: #define KVM_IOEVENTFD_FLAG_DATAMATCH (1 << kvm_ioeventfd_flag_nr_datamatch) #define KVM_IOEVENTFD_FLAG_PIO (1 << kvm_ioeventfd_flag_nr_pio) #define KVM_IOEVENTFD_FLAG_DEASSIGN (1 << kvm_ioeventfd_flag_nr_deassign) +#define KVM_IOEVENTFD_FLAG_READ (1 << kvm_ioeventfd_flag_nr_read) If datamatch flag is set, the event will be signaled only if the written value to the registered address is equal to datamatch in struct kvm_ioeventfd. +If the read flag is set, the event will be signaled when the specified address +is being read from. The value actually read by the guest will be the value +passed in datamatch. + 5. The kvm_run structure Application code obtains a pointer to the kvm_run structure by diff --git a/include/linux/kvm.h b/include/linux/kvm.h index 81cd295..ce4cc89 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -387,12 +387,14 @@ enum { kvm_ioeventfd_flag_nr_datamatch, kvm_ioeventfd_flag_nr_pio, kvm_ioeventfd_flag_nr_deassign, + kvm_ioeventfd_flag_nr_read, kvm_ioeventfd_flag_nr_max, }; #define KVM_IOEVENTFD_FLAG_DATAMATCH (1 << kvm_ioeventfd_flag_nr_datamatch) #define KVM_IOEVENTFD_FLAG_PIO (1 << kvm_ioeventfd_flag_nr_pio) #define KVM_IOEVENTFD_FLAG_DEASSIGN (1 << kvm_ioeventfd_flag_nr_deassign) +#define KVM_IOEVENTFD_FLAG_READ (1 << kvm_ioeventfd_flag_nr_read) #define KVM_IOEVENTFD_VALID_FLAG_MASK ((1 << kvm_ioeventfd_flag_nr_max) - 1) diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c index a1a3f66..e0f24bf 100644 --- a/virt/kvm/eventfd.c +++ b/virt/kvm/eventfd.c @@ -428,6 +428,7 @@ struct _ioeventfd { u64 datamatch; struct kvm_io_device dev; bool wildcard; + bool track_reads; }; static inline struct _ioeventfd * @@ -522,6 +523,24 @@ ioeventfd_write(struct kvm_io_device *this, gpa_t addr, int len, return 0; } +/* MMIO/PIO reads trigger an event if the addr/val match */ +static int +ioeventfd_read(struct kvm_io_device *this, gpa_t addr, int len, + void *val) +{ + struct _ioeventfd *p = to_ioeventfd(this); + + /* Exit if signaling on reads isn't requested */ + if (!p->track_reads) + return -EOPNOTSUPP; + + if (!ioeventfd_in_range(p, addr, len, val)) + return -EOPNOTSUPP; + + eventfd_signal(p->eventfd, 1); + return 0; +} + /* * This function is called as KVM is completely shutting down. We do not * need to worry about locking just nuke anything we have as quickly as possible @@ -535,6 +554,7 @@ ioeventfd_destructor(struct kvm_io_device *this) } static const struct kvm_io_device_ops ioeventfd_ops = { + .read = ioeventfd_read, .write = ioeventfd_write, .destructor = ioeventfd_destructor, }; @@ -600,6 +620,10 @@ kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args) goto unlock_fail; } + /* Raise signal on reads from address if requested */ + if (args->flags & KVM_IOEVENTFD_FLAG_READ) + p->track_reads = true; + kvm_iodevice_init(&p->dev, &ioeventfd_ops); ret = kvm_io_bus_register_dev(kvm, bus_idx, &p->dev);