int viridian_synic_wrmsr(struct vcpu *v, uint32_t idx, uint64_t val)
{
struct viridian_vcpu *vv = v->arch.hvm.viridian;
+ struct domain *d = v->domain;
switch ( idx )
{
vv->vp_assist.msr.raw = val;
viridian_dump_guest_page(v, "VP_ASSIST", &vv->vp_assist);
if ( vv->vp_assist.msr.enabled )
- viridian_map_guest_page(v, &vv->vp_assist);
+ viridian_map_guest_page(d, &vv->vp_assist);
break;
default:
struct vcpu *v, const struct hvm_viridian_vcpu_context *ctxt)
{
struct viridian_vcpu *vv = v->arch.hvm.viridian;
+ struct domain *d = v->domain;
vv->vp_assist.msr.raw = ctxt->vp_assist_msr;
if ( vv->vp_assist.msr.enabled )
- viridian_map_guest_page(v, &vv->vp_assist);
+ viridian_map_guest_page(d, &vv->vp_assist);
vv->apic_assist_pending = ctxt->apic_assist_pending;
}
uint64_t Reserved2[509];
} HV_REFERENCE_TSC_PAGE, *PHV_REFERENCE_TSC_PAGE;
-static void dump_reference_tsc(const struct domain *d)
-{
- const union viridian_page_msr *rt = &d->arch.hvm.viridian->reference_tsc;
-
- if ( !rt->enabled )
- return;
-
- printk(XENLOG_G_INFO "d%d: VIRIDIAN REFERENCE_TSC: pfn: %lx\n",
- d->domain_id, (unsigned long)rt->pfn);
-}
-
static void update_reference_tsc(struct domain *d, bool initialize)
{
- unsigned long gmfn = d->arch.hvm.viridian->reference_tsc.pfn;
- struct page_info *page = get_page_from_gfn(d, gmfn, NULL, P2M_ALLOC);
- HV_REFERENCE_TSC_PAGE *p;
-
- if ( !page || !get_page_type(page, PGT_writable_page) )
- {
- if ( page )
- put_page(page);
- gdprintk(XENLOG_WARNING, "Bad GMFN %#"PRI_gfn" (MFN %#"PRI_mfn")\n",
- gmfn, mfn_x(page ? page_to_mfn(page) : INVALID_MFN));
- return;
- }
-
- p = __map_domain_page(page);
+ const struct viridian_page *rt = &d->arch.hvm.viridian->reference_tsc;
+ HV_REFERENCE_TSC_PAGE *p = rt->ptr;
if ( initialize )
clear_page(p);
printk(XENLOG_G_INFO "d%d: VIRIDIAN REFERENCE_TSC: invalidated\n",
d->domain_id);
- goto out;
+ return;
}
/*
if ( p->TscSequence == 0xFFFFFFFF ||
p->TscSequence == 0 ) /* Avoid both 'invalid' values */
p->TscSequence = 1;
-
- out:
- unmap_domain_page(p);
-
- put_page_and_type(page);
}
static int64_t raw_trc_val(const struct domain *d)
if ( !(viridian_feature_mask(d) & HVMPV_reference_tsc) )
return X86EMUL_EXCEPTION;
- vd->reference_tsc.raw = val;
- dump_reference_tsc(d);
- if ( vd->reference_tsc.enabled )
+ viridian_unmap_guest_page(&vd->reference_tsc);
+ vd->reference_tsc.msr.raw = val;
+ viridian_dump_guest_page(v, "REFERENCE_TSC", &vd->reference_tsc);
+ if ( vd->reference_tsc.msr.enabled )
+ {
+ viridian_map_guest_page(d, &vd->reference_tsc);
update_reference_tsc(d, true);
+ }
break;
default:
if ( !(viridian_feature_mask(d) & HVMPV_reference_tsc) )
return X86EMUL_EXCEPTION;
- *val = vd->reference_tsc.raw;
+ *val = vd->reference_tsc.msr.raw;
break;
case HV_X64_MSR_TIME_REF_COUNT:
void viridian_time_domain_deinit(const struct domain *d)
{
+ viridian_unmap_guest_page(&d->arch.hvm.viridian->reference_tsc);
}
void viridian_time_save_vcpu_ctxt(
const struct viridian_domain *vd = d->arch.hvm.viridian;
ctxt->time_ref_count = vd->time_ref_count.val;
- ctxt->reference_tsc = vd->reference_tsc.raw;
+ ctxt->reference_tsc = vd->reference_tsc.msr.raw;
}
void viridian_time_load_domain_ctxt(
struct viridian_domain *vd = d->arch.hvm.viridian;
vd->time_ref_count.val = ctxt->time_ref_count;
- vd->reference_tsc.raw = ctxt->reference_tsc;
+ vd->reference_tsc.msr.raw = ctxt->reference_tsc;
- if ( vd->reference_tsc.enabled )
+ if ( vd->reference_tsc.msr.enabled )
+ {
+ viridian_map_guest_page(d, &vd->reference_tsc);
update_reference_tsc(d, false);
+ }
}
/*