int set_shared_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn) { struct p2m_domain *p2m = p2m_get_hostp2m(d); int rc = 0; p2m_access_t a; p2m_type_t ot; mfn_t omfn; unsigned long pg_type; if ( !paging_mode_translate(p2m->domain) ) return 0; gfn_lock(p2m, gfn, 0); omfn = p2m->get_entry(p2m, gfn, &ot, &a, 0, NULL); /* At the moment we only allow p2m change if gfn has already been made * sharable first */ ASSERT(p2m_is_shared(ot)); ASSERT(mfn_valid(omfn)); /* Set the m2p entry to invalid only if there are no further type * refs to this page as shared */ pg_type = read_atomic(&(mfn_to_page(omfn)->u.inuse.type_info)); if ( (pg_type & PGT_count_mask) == 0 || (pg_type & PGT_type_mask) != PGT_shared_page ) set_gpfn_from_mfn(mfn_x(omfn), INVALID_M2P_ENTRY); P2M_DEBUG("set shared %lx %lx\n", gfn, mfn_x(mfn)); rc = set_p2m_entry(p2m, gfn, mfn, PAGE_ORDER_4K, p2m_ram_shared, p2m->default_access); gfn_unlock(p2m, gfn, 0); if ( 0 == rc ) gdprintk(XENLOG_ERR, "set_shared_p2m_entry: set_p2m_entry failed! mfn=%08lx\n", mfn_x(get_gfn_query_unlocked(p2m->domain, gfn, &ot))); return rc; }
static always_inline spinlock_tickets_t observe_lock(spinlock_tickets_t *t) { spinlock_tickets_t v; smp_rmb(); v.head_tail = read_atomic(&t->head_tail); return v; }
long read_console_ring(struct xen_sysctl_readconsole *op) { XEN_GUEST_HANDLE_PARAM(char) str; uint32_t idx, len, max, sofar, c, p; str = guest_handle_cast(op->buffer, char), max = op->count; sofar = 0; c = read_atomic(&conringc); p = read_atomic(&conringp); if ( op->incremental && (c <= p ? c < op->index && op->index <= p : c < op->index || op->index <= p) ) c = op->index; while ( (c != p) && (sofar < max) ) { idx = CONRING_IDX_MASK(c); len = p - c; if ( (idx + len) > conring_size ) len = conring_size - idx; if ( (sofar + len) > max ) len = max - sofar; if ( copy_to_guest_offset(str, sofar, &conring[idx], len) ) return -EFAULT; sofar += len; c += len; } if ( op->clear ) { spin_lock_irq(&console_lock); conringc = p - c > conring_size ? p - conring_size : c; spin_unlock_irq(&console_lock); } op->count = sofar; op->index = c; return 0; }
static always_inline u16 observe_head(spinlock_tickets_t *t) { smp_rmb(); return read_atomic(&t->head); }