]> xenbits.xensource.com Git - xen.git/commitdiff
xen: Use guest atomics helpers when modifying atomically guest memory
authorJulien Grall <julien.grall@arm.com>
Mon, 29 Apr 2019 14:05:28 +0000 (15:05 +0100)
committerJulien Grall <julien.grall@arm.com>
Fri, 14 Jun 2019 14:46:00 +0000 (15:46 +0100)
On Arm, exclusive load-store atomics should only be used between trusted
thread. As not all the guests are trusted, it may be possible to DoS Xen
when updating shared memory with guest atomically.

This patch replaces all the atomics operations on shared memory with
a guest by the new guest atomics helpers. The x86 code was not audited
to know where guest atomics helpers could be used. I will leave that
to the x86 folks.

Note that some rework was required in order to plumb use the new guest
atomics in event channel and grant-table.

Because guest_test_bit is ignoring the parameter "d" for now, it
means there a lot of places do not need to drop the const. We may want
to revisit this in the future if the parameter "d" becomes necessary.

This is part of XSA-295.

Signed-off-by: Julien Grall <julien.grall@arm.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
xen/arch/arm/domain.c
xen/arch/arm/mm.c
xen/common/event_2l.c
xen/common/event_fifo.c
xen/common/grant_table.c
xen/include/asm-arm/grant_table.h
xen/include/asm-x86/grant_table.h

index c0a61da6f51a25c0c461ed8dc089577ecded6ccd..d9e796dcbe4b9b13e73d0547d837b7dfec010dec 100644 (file)
@@ -24,6 +24,7 @@
 #include <asm/current.h>
 #include <asm/event.h>
 #include <asm/guest_access.h>
+#include <asm/guest_atomics.h>
 #include <asm/regs.h>
 #include <asm/p2m.h>
 #include <asm/irq.h>
@@ -935,7 +936,7 @@ void arch_dump_vcpu_info(struct vcpu *v)
 
 void vcpu_mark_events_pending(struct vcpu *v)
 {
-    int already_pending = test_and_set_bit(
+    bool already_pending = guest_test_and_set_bit(v->domain,
         0, (unsigned long *)&vcpu_info(v, evtchn_upcall_pending));
 
     if ( already_pending )
index 4c1a407c958753a4b19feb85f2b4174d2bf9db09..c991dbd1783f96a978d52c8d9ea8d6aab9e4a883 100644 (file)
@@ -41,6 +41,8 @@
 #include <xen/pfn.h>
 #include <xen/sizes.h>
 #include <xen/libfdt/libfdt.h>
+
+#include <asm/guest_atomics.h>
 #include <asm/setup.h>
 
 struct domain *dom_xen, *dom_io, *dom_cow;
@@ -1367,7 +1369,7 @@ void put_page_type(struct page_info *page)
     return;
 }
 
-void gnttab_clear_flag(unsigned long nr, uint16_t *addr)
+void gnttab_clear_flag(struct domain *d, unsigned long nr, uint16_t *addr)
 {
     /*
      * Note that this cannot be clear_bit(), as the access must be
@@ -1377,7 +1379,7 @@ void gnttab_clear_flag(unsigned long nr, uint16_t *addr)
 
     do {
         old = *addr;
-    } while (cmpxchg(addr, old, old & mask) != old);
+    } while (guest_cmpxchg(d, addr, old, old & mask) != old);
 }
 
 void gnttab_mark_dirty(struct domain *d, unsigned long l)
index 42a5476498857ae693d2f4d7392d9d5369a9430f..6aabf0b9b01939c83cc045674e776da633d86af3 100644 (file)
@@ -14,6 +14,8 @@
 #include <xen/sched.h>
 #include <xen/event.h>
 
+#include <asm/guest_atomics.h>
+
 static void evtchn_2l_set_pending(struct vcpu *v, struct evtchn *evtchn)
 {
     struct domain *d = v->domain;
@@ -26,12 +28,12 @@ static void evtchn_2l_set_pending(struct vcpu *v, struct evtchn *evtchn)
      * others may require explicit memory barriers.
      */
 
-    if ( test_and_set_bit(port, &shared_info(d, evtchn_pending)) )
+    if ( guest_test_and_set_bit(d, port, &shared_info(d, evtchn_pending)) )
         return;
 
-    if ( !test_bit        (port, &shared_info(d, evtchn_mask)) &&
-         !test_and_set_bit(port / BITS_PER_EVTCHN_WORD(d),
-                           &vcpu_info(v, evtchn_pending_sel)) )
+    if ( !guest_test_bit(d, port, &shared_info(d, evtchn_mask)) &&
+         !guest_test_and_set_bit(d, port / BITS_PER_EVTCHN_WORD(d),
+                                 &vcpu_info(v, evtchn_pending_sel)) )
     {
         vcpu_mark_events_pending(v);
     }
@@ -41,7 +43,7 @@ static void evtchn_2l_set_pending(struct vcpu *v, struct evtchn *evtchn)
 
 static void evtchn_2l_clear_pending(struct domain *d, struct evtchn *evtchn)
 {
-    clear_bit(evtchn->port, &shared_info(d, evtchn_pending));
+    guest_clear_bit(d, evtchn->port, &shared_info(d, evtchn_pending));
 }
 
 static void evtchn_2l_unmask(struct domain *d, struct evtchn *evtchn)
@@ -53,10 +55,10 @@ static void evtchn_2l_unmask(struct domain *d, struct evtchn *evtchn)
      * These operations must happen in strict order. Based on
      * evtchn_2l_set_pending() above.
      */
-    if ( test_and_clear_bit(port, &shared_info(d, evtchn_mask)) &&
-         test_bit          (port, &shared_info(d, evtchn_pending)) &&
-         !test_and_set_bit (port / BITS_PER_EVTCHN_WORD(d),
-                            &vcpu_info(v, evtchn_pending_sel)) )
+    if ( guest_test_and_clear_bit(d, port, &shared_info(d, evtchn_mask)) &&
+         guest_test_bit(d, port, &shared_info(d, evtchn_pending)) &&
+         !guest_test_and_set_bit(d, port / BITS_PER_EVTCHN_WORD(d),
+                                 &vcpu_info(v, evtchn_pending_sel)) )
     {
         vcpu_mark_events_pending(v);
     }
@@ -67,7 +69,8 @@ static bool_t evtchn_2l_is_pending(struct domain *d, evtchn_port_t port)
     unsigned int max_ports = BITS_PER_EVTCHN_WORD(d) * BITS_PER_EVTCHN_WORD(d);
 
     ASSERT(port < max_ports);
-    return port < max_ports && test_bit(port, &shared_info(d, evtchn_pending));
+    return (port < max_ports &&
+            guest_test_bit(d, port, &shared_info(d, evtchn_pending)));
 }
 
 static bool_t evtchn_2l_is_masked(struct domain *d, evtchn_port_t port)
@@ -75,7 +78,8 @@ static bool_t evtchn_2l_is_masked(struct domain *d, evtchn_port_t port)
     unsigned int max_ports = BITS_PER_EVTCHN_WORD(d) * BITS_PER_EVTCHN_WORD(d);
 
     ASSERT(port < max_ports);
-    return port >= max_ports || test_bit(port, &shared_info(d, evtchn_mask));
+    return (port >= max_ports ||
+            guest_test_bit(d, port, &shared_info(d, evtchn_mask)));
 }
 
 static void evtchn_2l_print_state(struct domain *d,
index fc58a4608a84ff66c08aec4a8454e8932ec54416..08a8321f1246a4bb799403a7a2701d07de82c642 100644 (file)
@@ -18,6 +18,8 @@
 #include <xen/mm.h>
 #include <xen/domain_page.h>
 
+#include <asm/guest_atomics.h>
+
 #include <public/event_channel.h>
 
 static inline event_word_t *evtchn_fifo_word_from_port(struct domain *d,
@@ -51,7 +53,7 @@ static void evtchn_fifo_init(struct domain *d, struct evtchn *evtchn)
      * on the wrong VCPU or with an unexpected priority.
      */
     word = evtchn_fifo_word_from_port(d, evtchn->port);
-    if ( word && test_bit(EVTCHN_FIFO_LINKED, word) )
+    if ( word && guest_test_bit(d, EVTCHN_FIFO_LINKED, word) )
         gdprintk(XENLOG_WARNING, "domain %d, port %d already on a queue\n",
                  d->domain_id, evtchn->port);
 }
@@ -116,7 +118,7 @@ static int try_set_link(event_word_t *word, event_word_t *w, uint32_t link)
  * We block unmasking by the guest by marking the tail word as BUSY,
  * therefore, the cmpxchg() may fail at most 4 times.
  */
-static bool_t evtchn_fifo_set_link(const struct domain *d, event_word_t *word,
+static bool_t evtchn_fifo_set_link(struct domain *d, event_word_t *word,
                                    uint32_t link)
 {
     event_word_t w;
@@ -130,7 +132,7 @@ static bool_t evtchn_fifo_set_link(const struct domain *d, event_word_t *word,
         return ret;
 
     /* Lock the word to prevent guest unmasking. */
-    set_bit(EVTCHN_FIFO_BUSY, word);
+    guest_set_bit(d, EVTCHN_FIFO_BUSY, word);
 
     w = read_atomic(word);
 
@@ -140,13 +142,13 @@ static bool_t evtchn_fifo_set_link(const struct domain *d, event_word_t *word,
         if ( ret >= 0 )
         {
             if ( ret == 0 )
-                clear_bit(EVTCHN_FIFO_BUSY, word);
+                guest_clear_bit(d, EVTCHN_FIFO_BUSY, word);
             return ret;
         }
     }
     gdprintk(XENLOG_WARNING, "domain %d, port %d not linked\n",
              d->domain_id, link);
-    clear_bit(EVTCHN_FIFO_BUSY, word);
+    guest_clear_bit(d, EVTCHN_FIFO_BUSY, word);
     return 1;
 }
 
@@ -171,13 +173,13 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         return;
     }
 
-    was_pending = test_and_set_bit(EVTCHN_FIFO_PENDING, word);
+    was_pending = guest_test_and_set_bit(d, EVTCHN_FIFO_PENDING, word);
 
     /*
      * Link the event if it unmasked and not already linked.
      */
-    if ( !test_bit(EVTCHN_FIFO_MASKED, word)
-         && !test_bit(EVTCHN_FIFO_LINKED, word) )
+    if ( !guest_test_bit(d, EVTCHN_FIFO_MASKED, word) &&
+         !guest_test_bit(d, EVTCHN_FIFO_LINKED, word) )
     {
         struct evtchn_fifo_queue *q, *old_q;
         event_word_t *tail_word;
@@ -206,7 +208,7 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         if ( !old_q )
             goto done;
 
-        if ( test_and_set_bit(EVTCHN_FIFO_LINKED, word) )
+        if ( guest_test_and_set_bit(d, EVTCHN_FIFO_LINKED, word) )
         {
             spin_unlock_irqrestore(&old_q->lock, flags);
             goto done;
@@ -252,8 +254,8 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
         spin_unlock_irqrestore(&q->lock, flags);
 
         if ( !linked
-             && !test_and_set_bit(q->priority,
-                                  &v->evtchn_fifo->control_block->ready) )
+             && !guest_test_and_set_bit(d, q->priority,
+                                        &v->evtchn_fifo->control_block->ready) )
             vcpu_mark_events_pending(v);
     }
  done:
@@ -275,7 +277,7 @@ static void evtchn_fifo_clear_pending(struct domain *d, struct evtchn *evtchn)
      * No need to unlink as the guest will unlink and ignore
      * non-pending events.
      */
-    clear_bit(EVTCHN_FIFO_PENDING, word);
+    guest_clear_bit(d, EVTCHN_FIFO_PENDING, word);
 }
 
 static void evtchn_fifo_unmask(struct domain *d, struct evtchn *evtchn)
@@ -287,10 +289,10 @@ static void evtchn_fifo_unmask(struct domain *d, struct evtchn *evtchn)
     if ( unlikely(!word) )
         return;
 
-    clear_bit(EVTCHN_FIFO_MASKED, word);
+    guest_clear_bit(d, EVTCHN_FIFO_MASKED, word);
 
     /* Relink if pending. */
-    if ( test_bit(EVTCHN_FIFO_PENDING, word) )
+    if ( guest_test_bit(d, EVTCHN_FIFO_PENDING, word) )
         evtchn_fifo_set_pending(v, evtchn);
 }
 
@@ -302,7 +304,7 @@ static bool_t evtchn_fifo_is_pending(struct domain *d, evtchn_port_t port)
     if ( unlikely(!word) )
         return 0;
 
-    return test_bit(EVTCHN_FIFO_PENDING, word);
+    return word && guest_test_bit(d, EVTCHN_FIFO_PENDING, word);
 }
 
 static bool_t evtchn_fifo_is_masked(struct domain *d, evtchn_port_t port)
@@ -313,7 +315,7 @@ static bool_t evtchn_fifo_is_masked(struct domain *d, evtchn_port_t port)
     if ( unlikely(!word) )
         return 1;
 
-    return test_bit(EVTCHN_FIFO_MASKED, word);
+    return !word || guest_test_bit(d, EVTCHN_FIFO_MASKED, word);
 }
 
 static bool_t evtchn_fifo_is_busy(struct domain *d, evtchn_port_t port)
@@ -324,7 +326,7 @@ static bool_t evtchn_fifo_is_busy(struct domain *d, evtchn_port_t port)
     if ( unlikely(!word) )
         return 0;
 
-    return test_bit(EVTCHN_FIFO_LINKED, word);
+    return word && guest_test_bit(d, EVTCHN_FIFO_LINKED, word);
 }
 
 static int evtchn_fifo_set_priority(struct domain *d, struct evtchn *evtchn,
@@ -351,11 +353,11 @@ static void evtchn_fifo_print_state(struct domain *d,
     word = evtchn_fifo_word_from_port(d, evtchn->port);
     if ( !word )
         printk("?     ");
-    else if ( test_bit(EVTCHN_FIFO_LINKED, word) )
-        printk("%c %-4u", test_bit(EVTCHN_FIFO_BUSY, word) ? 'B' : ' ',
+    else if ( guest_test_bit(d, EVTCHN_FIFO_LINKED, word) )
+        printk("%c %-4u", guest_test_bit(d, EVTCHN_FIFO_BUSY, word) ? 'B' : ' ',
                *word & EVTCHN_FIFO_LINK_MASK);
     else
-        printk("%c -   ", test_bit(EVTCHN_FIFO_BUSY, word) ? 'B' : ' ');
+        printk("%c -   ", guest_test_bit(d, EVTCHN_FIFO_BUSY, word) ? 'B' : ' ');
 }
 
 static const struct evtchn_port_ops evtchn_port_ops_fifo =
@@ -507,7 +509,7 @@ static void setup_ports(struct domain *d)
 
         evtchn = evtchn_from_port(d, port);
 
-        if ( test_bit(port, &shared_info(d, evtchn_pending)) )
+        if ( guest_test_bit(d, port, &shared_info(d, evtchn_pending)) )
             evtchn->pending = 1;
 
         evtchn_fifo_set_priority(d, evtchn, EVTCHN_FIFO_PRIORITY_DEFAULT);
index a555dabbf75ca08ef6748a0e1116ad26ffcd4f74..c3c9e50d311e7e4d5e900cdf81ca257ce2d515e8 100644 (file)
@@ -39,6 +39,7 @@
 #include <xen/vmap.h>
 #include <xsm/xsm.h>
 #include <asm/flushtlb.h>
+#include <asm/guest_atomics.h>
 
 /* 
  * This option is deprecated, use gnttab_max_frames and
@@ -546,6 +547,7 @@ static unsigned int nr_grant_entries(struct grant_table *gt)
 }
 
 static int _set_status_v1(const grant_entry_header_t *shah,
+                          struct domain *rd,
                           struct active_grant_entry *act,
                           int readonly,
                           int mapflag,
@@ -601,8 +603,8 @@ static int _set_status_v1(const grant_entry_header_t *shah,
                          "Attempt to write-pin a r/o grant entry.\n");
         }
 
-        prev_scombo.word = cmpxchg((u32 *)shah,
-                                   scombo.word, new_scombo.word);
+        prev_scombo.word = guest_cmpxchg(rd, (u32 *)shah,
+                                         scombo.word, new_scombo.word);
         if ( likely(prev_scombo.word == scombo.word) )
             break;
 
@@ -619,6 +621,7 @@ done:
 
 static int _set_status_v2(const grant_entry_header_t *shah,
                           grant_status_t *status,
+                          struct domain *rd,
                           struct active_grant_entry *act,
                           int readonly,
                           int mapflag,
@@ -681,8 +684,8 @@ static int _set_status_v2(const grant_entry_header_t *shah,
              (id != ldomid) ||
              (!readonly && (flags & GTF_readonly)) )
         {
-            gnttab_clear_flag(_GTF_writing, status);
-            gnttab_clear_flag(_GTF_reading, status);
+            gnttab_clear_flag(rd, _GTF_writing, status);
+            gnttab_clear_flag(rd, _GTF_reading, status);
             PIN_FAIL(done, GNTST_general_error,
                      "Unstable flags (%x) or dom (%d). (expected dom %d) "
                      "(r/w: %d)\n",
@@ -693,7 +696,7 @@ static int _set_status_v2(const grant_entry_header_t *shah,
     {
         if ( unlikely(flags & GTF_readonly) )
         {
-            gnttab_clear_flag(_GTF_writing, status);
+            gnttab_clear_flag(rd, _GTF_writing, status);
             PIN_FAIL(done, GNTST_general_error,
                      "Unstable grant readonly flag\n");
         }
@@ -706,6 +709,7 @@ done:
 
 static int _set_status(const grant_entry_header_t *shah,
                        grant_status_t *status,
+                       struct domain *rd,
                        unsigned rgt_version,
                        struct active_grant_entry *act,
                        int readonly,
@@ -714,9 +718,9 @@ static int _set_status(const grant_entry_header_t *shah,
 {
 
     if ( rgt_version == 1 )
-        return _set_status_v1(shah, act, readonly, mapflag, ldomid);
+        return _set_status_v1(shah, rd, act, readonly, mapflag, ldomid);
     else
-        return _set_status_v2(shah, status, act, readonly, mapflag, ldomid);
+        return _set_status_v2(shah, status, rd, act, readonly, mapflag, ldomid);
 }
 
 static struct active_grant_entry *grant_map_exists(const struct domain *ld,
@@ -884,7 +888,7 @@ __gnttab_map_grant_ref(
          (!(op->flags & GNTMAP_readonly) &&
           !(act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask))) )
     {
-        if ( (rc = _set_status(shah, status, rgt->gt_version, act,
+        if ( (rc = _set_status(shah, status, rd, rgt->gt_version, act,
                                op->flags & GNTMAP_readonly, 1,
                                ld->domain_id) != GNTST_okay) )
             goto act_release_out;
@@ -1097,10 +1101,10 @@ __gnttab_map_grant_ref(
  unlock_out_clear:
     if ( !(op->flags & GNTMAP_readonly) &&
          !(act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) )
-        gnttab_clear_flag(_GTF_writing, status);
+        gnttab_clear_flag(rd, _GTF_writing, status);
 
     if ( !act->pin )
-        gnttab_clear_flag(_GTF_reading, status);
+        gnttab_clear_flag(rd, _GTF_reading, status);
 
  act_release_out:
     active_entry_release(act);
@@ -1382,10 +1386,10 @@ __gnttab_unmap_common_complete(struct gnttab_unmap_common *op)
 
     if ( ((act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0) &&
          !(op->done & GNTMAP_readonly) )
-        gnttab_clear_flag(_GTF_writing, status);
+        gnttab_clear_flag(rd, _GTF_writing, status);
 
     if ( act->pin == 0 )
-        gnttab_clear_flag(_GTF_reading, status);
+        gnttab_clear_flag(rd, _GTF_reading, status);
 
     active_entry_release(act);
     grant_read_unlock(rgt);
@@ -1869,8 +1873,8 @@ gnttab_prepare_for_transfer(
         new_scombo = scombo;
         new_scombo.shorts.flags |= GTF_transfer_committed;
 
-        prev_scombo.word = cmpxchg((u32 *)&sha->flags,
-                                   scombo.word, new_scombo.word);
+        prev_scombo.word = guest_cmpxchg(rd, (u32 *)&sha->flags,
+                                         scombo.word, new_scombo.word);
         if ( likely(prev_scombo.word == scombo.word) )
             break;
 
@@ -2165,11 +2169,11 @@ __release_grant_for_copy(
 
         act->pin -= GNTPIN_hstw_inc;
         if ( !(act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) )
-            gnttab_clear_flag(_GTF_writing, status);
+            gnttab_clear_flag(rd, _GTF_writing, status);
     }
 
     if ( !act->pin )
-        gnttab_clear_flag(_GTF_reading, status);
+        gnttab_clear_flag(rd, _GTF_reading, status);
 
     active_entry_release(act);
     grant_read_unlock(rgt);
@@ -2191,14 +2195,15 @@ __release_grant_for_copy(
    under the domain's grant table lock. */
 /* Only safe on transitive grants.  Even then, note that we don't
    attempt to drop any pin on the referent grant. */
-static void __fixup_status_for_copy_pin(const struct active_grant_entry *act,
-                                   uint16_t *status)
+static void __fixup_status_for_copy_pin(struct domain *rd,
+                                        const struct active_grant_entry *act,
+                                        uint16_t *status)
 {
     if ( !(act->pin & (GNTPIN_hstw_mask | GNTPIN_devw_mask)) )
-        gnttab_clear_flag(_GTF_writing, status);
+        gnttab_clear_flag(rd, _GTF_writing, status);
 
     if ( !act->pin )
-        gnttab_clear_flag(_GTF_reading, status);
+        gnttab_clear_flag(rd, _GTF_reading, status);
 }
 
 /* Grab a frame number from a grant entry and update the flags and pin
@@ -2258,7 +2263,7 @@ __acquire_grant_for_copy(
     {
         if ( (!old_pin || (!readonly &&
                            !(old_pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)))) &&
-             (rc = _set_status_v2(shah, status, act, readonly, 0,
+             (rc = _set_status_v2(shah, status, rd, act, readonly, 0,
                                   ldom)) != GNTST_okay )
             goto unlock_out;
 
@@ -2306,7 +2311,7 @@ __acquire_grant_for_copy(
 
         if ( rc != GNTST_okay )
         {
-            __fixup_status_for_copy_pin(act, status);
+            __fixup_status_for_copy_pin(rd, act, status);
             rcu_unlock_domain(td);
             active_entry_release(act);
             grant_read_unlock(rgt);
@@ -2328,7 +2333,7 @@ __acquire_grant_for_copy(
                           !act->is_sub_page)) )
         {
             __release_grant_for_copy(td, trans_gref, readonly);
-            __fixup_status_for_copy_pin(act, status);
+            __fixup_status_for_copy_pin(rd, act, status);
             rcu_unlock_domain(td);
             active_entry_release(act);
             grant_read_unlock(rgt);
@@ -2357,7 +2362,7 @@ __acquire_grant_for_copy(
     else if ( !old_pin ||
               (!readonly && !(old_pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask))) )
     {
-        if ( (rc = _set_status(shah, status, rgt->gt_version, act,
+        if ( (rc = _set_status(shah, status, rd, rgt->gt_version, act,
                                readonly, 0, ldom)) != GNTST_okay )
              goto unlock_out;
 
@@ -2443,10 +2448,10 @@ __acquire_grant_for_copy(
  unlock_out_clear:
     if ( !(readonly) &&
          !(act->pin & (GNTPIN_hstw_mask | GNTPIN_devw_mask)) )
-        gnttab_clear_flag(_GTF_writing, status);
+        gnttab_clear_flag(rd, _GTF_writing, status);
 
     if ( !act->pin )
-        gnttab_clear_flag(_GTF_reading, status);
+        gnttab_clear_flag(rd, _GTF_reading, status);
 
  unlock_out:
     active_entry_release(act);
@@ -3549,11 +3554,11 @@ gnttab_release_mappings(
             }
 
             if ( (act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0 )
-                gnttab_clear_flag(_GTF_writing, status);
+                gnttab_clear_flag(rd, _GTF_writing, status);
         }
 
         if ( act->pin == 0 )
-            gnttab_clear_flag(_GTF_reading, status);
+            gnttab_clear_flag(rd, _GTF_reading, status);
 
         active_entry_release(act);
         grant_read_unlock(rgt);
index b47220c1c620496b90e9aeecfa4cf1f76336d21a..886f8398c3f2b566233f9a6e0678fb84e11dd199 100644 (file)
@@ -6,7 +6,7 @@
 #define INITIAL_NR_GRANT_FRAMES 4
 #define GNTTAB_MAX_VERSION 1
 
-void gnttab_clear_flag(unsigned long nr, uint16_t *addr);
+void gnttab_clear_flag(struct domain *d, unsigned long nr, uint16_t *addr);
 int create_grant_host_mapping(unsigned long gpaddr,
         unsigned long mfn, unsigned int flags, unsigned int
         cache_flags);
index 9c64361ee2602df06bd28670217e3f1b582335b0..889b04cc88c9e2b3d1005d249e46ec87360d49d6 100644 (file)
@@ -56,7 +56,8 @@ int replace_grant_host_mapping(
 
 #define gnttab_mark_dirty(d, f) paging_mark_dirty((d), (f))
 
-static inline void gnttab_clear_flag(unsigned int nr, uint16_t *st)
+static inline void gnttab_clear_flag(struct domain *d, unsigned int nr,
+                                     uint16_t *st)
 {
     /*
      * Note that this cannot be clear_bit(), as the access must be