#define HV_X64_MSR_CRASH_P4 0x40000104
#define HV_X64_MSR_CRASH_CTL 0x40000105
-#define VIRIDIAN_MSR_MIN HV_X64_MSR_GUEST_OS_ID
-#define VIRIDIAN_MSR_MAX HV_X64_MSR_CRASH_CTL
-
/* Viridian Hypercall Status Codes. */
#define HV_STATUS_SUCCESS 0x0000
#define HV_STATUS_INVALID_HYPERCALL_CODE 0x0002
put_page_and_type(page);
}
-int wrmsr_viridian_regs(uint32_t idx, uint64_t val)
+int guest_wrmsr_viridian(struct vcpu *v, uint32_t idx, uint64_t val)
{
- struct vcpu *v = current;
struct domain *d = v->domain;
- if ( !is_viridian_domain(d) )
- return 0;
+ ASSERT(is_viridian_domain(d));
switch ( idx )
{
case HV_X64_MSR_REFERENCE_TSC:
if ( !(viridian_feature_mask(d) & HVMPV_reference_tsc) )
- return 0;
+ return X86EMUL_EXCEPTION;
perfc_incr(mshv_wrmsr_tsc_msr);
d->arch.hvm.viridian.reference_tsc.raw = val;
}
default:
- if ( idx >= VIRIDIAN_MSR_MIN && idx <= VIRIDIAN_MSR_MAX )
- gprintk(XENLOG_WARNING, "write to unimplemented MSR %#x\n",
- idx);
-
- return 0;
+ gdprintk(XENLOG_INFO,
+ "Write %016"PRIx64" to unimplemented MSR %#x\n", val, idx);
+ return X86EMUL_EXCEPTION;
}
- return 1;
+ return X86EMUL_OKAY;
}
static int64_t raw_trc_val(struct domain *d)
trc->off = (int64_t)trc->val - raw_trc_val(d);
}
-int rdmsr_viridian_regs(uint32_t idx, uint64_t *val)
+int guest_rdmsr_viridian(const struct vcpu *v, uint32_t idx, uint64_t *val)
{
- struct vcpu *v = current;
struct domain *d = v->domain;
-
- if ( !is_viridian_domain(d) )
- return 0;
+
+ ASSERT(is_viridian_domain(d));
switch ( idx )
{
case HV_X64_MSR_TSC_FREQUENCY:
if ( viridian_feature_mask(d) & HVMPV_no_freq )
- return 0;
+ return X86EMUL_EXCEPTION;
perfc_incr(mshv_rdmsr_tsc_frequency);
*val = (uint64_t)d->arch.tsc_khz * 1000ull;
case HV_X64_MSR_APIC_FREQUENCY:
if ( viridian_feature_mask(d) & HVMPV_no_freq )
- return 0;
+ return X86EMUL_EXCEPTION;
perfc_incr(mshv_rdmsr_apic_frequency);
*val = 1000000000ull / APIC_BUS_CYCLE_NS;
case HV_X64_MSR_REFERENCE_TSC:
if ( !(viridian_feature_mask(d) & HVMPV_reference_tsc) )
- return 0;
+ return X86EMUL_EXCEPTION;
perfc_incr(mshv_rdmsr_tsc_msr);
*val = d->arch.hvm.viridian.reference_tsc.raw;
trc = &d->arch.hvm.viridian.time_ref_count;
if ( !(viridian_feature_mask(d) & HVMPV_time_ref_count) )
- return 0;
+ return X86EMUL_EXCEPTION;
if ( !test_and_set_bit(_TRC_accessed, &trc->flags) )
printk(XENLOG_G_INFO "d%d: VIRIDIAN MSR_TIME_REF_COUNT: accessed\n",
}
default:
- if ( idx >= VIRIDIAN_MSR_MIN && idx <= VIRIDIAN_MSR_MAX )
- gprintk(XENLOG_WARNING, "read from unimplemented MSR %#x\n",
- idx);
-
- return 0;
+ gdprintk(XENLOG_INFO, "Read from unimplemented MSR %#x\n", idx);
+ return X86EMUL_EXCEPTION;
}
- return 1;
+ return X86EMUL_OKAY;
}
void viridian_vcpu_deinit(struct vcpu *v)
case 0x40000000 ... 0x400001ff:
if ( is_viridian_domain(d) )
{
- ret = (rdmsr_viridian_regs(msr, val)
- ? X86EMUL_OKAY : X86EMUL_EXCEPTION);
+ ret = guest_rdmsr_viridian(v, msr, val);
break;
}
case 0x40000000 ... 0x400001ff:
if ( is_viridian_domain(d) )
{
- ret = (wrmsr_viridian_regs(msr, val)
- ? X86EMUL_OKAY : X86EMUL_EXCEPTION);
+ ret = guest_wrmsr_viridian(v, msr, val);
break;
}