domid_t ldomid)
{
- if ( rgt_version == 1 )
+ if ( evaluate_nospec(rgt_version == 1) )
return _set_status_v1(shah, rd, act, readonly, mapflag, ldomid);
else
return _set_status_v2(shah, status, rd, act, readonly, mapflag, ldomid);
/* This call also ensures the above check cannot be passed speculatively */
shah = shared_entry_header(rgt, ref);
- status = rgt->gt_version == 1 ? &shah->flags : &status_entry(rgt, ref);
act = active_entry_acquire(rgt, ref);
+ /* Make sure we do not access memory speculatively */
+ status = evaluate_nospec(rgt->gt_version == 1) ? &shah->flags
+ : &status_entry(rgt, ref);
+
/* If already pinned, check the active domid and avoid refcnt overflow. */
if ( act->pin &&
((act->domid != ld->domain_id) ||
if ( !act->pin )
{
- unsigned long gfn = rgt->gt_version == 1 ?
+ unsigned long gfn = evaluate_nospec(rgt->gt_version == 1) ?
shared_entry_v1(rgt, ref).frame :
shared_entry_v2(rgt, ref).full_page.frame;
act = active_entry_acquire(rgt, op->ref);
sha = shared_entry_header(rgt, op->ref);
- if ( rgt->gt_version == 1 )
+ if ( evaluate_nospec(rgt->gt_version == 1) )
status = &sha->flags;
else
status = &status_entry(rgt, op->ref);
unsigned req_status_frames;
req_status_frames = grant_to_status_frames(req_nr_frames);
+
+ /* Make sure, prior version checks are architectural visible */
+ block_speculation();
+
for ( i = nr_status_frames(gt); i < req_status_frames; i++ )
{
if ( (gt->status[i] = alloc_xenheap_page()) == NULL )
{
unsigned int i;
+ /* Make sure, prior version checks are architectural visible */
+ block_speculation();
+
for ( i = 0; i < nr_status_frames(gt); i++ )
{
struct page_info *pg = virt_to_page(gt->status[i]);
}
/* Status pages - version 2 */
- if ( gt->gt_version > 1 )
+ if ( evaluate_nospec(gt->gt_version > 1) )
{
if ( gnttab_populate_status_frames(d, gt, req_nr_frames) )
goto shared_alloc_failed;
grant_read_lock(e->grant_table);
act = active_entry_acquire(e->grant_table, gop.ref);
- if ( e->grant_table->gt_version == 1 )
+ if ( evaluate_nospec(e->grant_table->gt_version == 1) )
{
grant_entry_v1_t *sha = &shared_entry_v1(e->grant_table, gop.ref);
sha = shared_entry_header(rgt, gref);
mfn = act->mfn;
- if ( rgt->gt_version == 1 )
+ if ( evaluate_nospec(rgt->gt_version == 1) )
{
status = &sha->flags;
td = rd;
shah = shared_entry_header(rgt, gref);
act = active_entry_acquire(rgt, gref);
- if ( rgt->gt_version == 1 )
+ if ( evaluate_nospec(rgt->gt_version == 1) )
{
sha2 = NULL;
status = &shah->flags;
if ( act_b->pin )
PIN_FAIL(out, GNTST_eagain, "ref b %#x busy\n", ref_b);
- if ( gt->gt_version == 1 )
+ if ( evaluate_nospec(gt->gt_version == 1) )
{
grant_entry_v1_t shared;
rc = -EINVAL;
else if ( ref >= nr_grant_entries(gt) )
rc = -ENOENT;
- else if ( gt->gt_version == 1 )
+ else if ( evaluate_nospec(gt->gt_version == 1) )
{
const grant_entry_v1_t *sha1 = &shared_entry_v1(gt, ref);
rc = -ENXIO;
else if ( !rc && status )
{
- if ( gt->gt_version == 1 )
+ if ( evaluate_nospec(gt->gt_version == 1) )
*status = flags;
else
*status = status_entry(gt, ref);
ASSERT(gt->gt_version == 2);
+ /* Make sure we have version equal to 2 even under speculation */
+ block_speculation();
+
if ( idx >= nr_status_frames(gt) )
{
unsigned long nr_status;
grant_write_lock(gt);
- if ( gt->gt_version == 2 && (idx & XENMAPIDX_grant_table_status) )
+ if ( evaluate_nospec(gt->gt_version == 2) && (idx & XENMAPIDX_grant_table_status) )
{
idx &= ~XENMAPIDX_grant_table_status;
status = true;