|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v2] x86: generic MSRs save/restore
>>> On 16.12.13 at 04:01, "Liu, Jinsong" <jinsong.liu@xxxxxxxxx> wrote:
> Jan Beulich wrote:
>> This patch introduces a generic MSRs save/restore mechanism, so that
>> in the future new MSRs save/restore could be added w/ smaller change
>> than the full blown addition of a new save/restore type.
>>
>> Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
>>
>> --- a/xen/arch/x86/hvm/hvm.c
>> +++ b/xen/arch/x86/hvm/hvm.c
>> @@ -1127,10 +1127,117 @@ static int hvm_load_cpu_xsave_states(str
>> return 0;
>> }
>>
>> -/* We need variable length data chunk for xsave area, hence
>> customized
>> - * declaration other than HVM_REGISTER_SAVE_RESTORE.
>> +#define HVM_CPU_MSR_SIZE(cnt) offsetof(struct hvm_msr, msr[cnt])
>> +static unsigned int __read_mostly msr_count_max;
>> +
>> +static int hvm_save_cpu_msrs(struct domain *d, hvm_domain_context_t
>> *h) +{
>> + struct vcpu *v;
>> +
>> + for_each_vcpu ( d, v )
>> + {
>> + struct hvm_msr *ctxt;
>> + unsigned int i;
>> +
>> + if ( _hvm_init_entry(h, CPU_MSR_CODE, v->vcpu_id,
>> + HVM_CPU_MSR_SIZE(msr_count_max)) )
>> + return 1;
>> + ctxt = (struct hvm_msr *)&h->data[h->cur];
>> + ctxt->count = 0;
>> +
>> + if ( hvm_funcs.save_msr )
>> + hvm_funcs.save_msr(v, ctxt);
>> +
>> + for ( i = 0; i < ctxt->count; ++i )
>> + ctxt->msr[i]._rsvd = 0;
>> +
>> + if ( ctxt->count )
>> + h->cur += HVM_CPU_MSR_SIZE(ctxt->count);
>> + else
>> + h->cur -= sizeof(struct hvm_save_descriptor);
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +static int hvm_load_cpu_msrs(struct domain *d, hvm_domain_context_t
>> *h) +{
>> + unsigned int i, vcpuid = hvm_load_instance(h);
>> + struct vcpu *v;
>> + const struct hvm_save_descriptor *desc;
>> + struct hvm_msr *ctxt;
>> + int err = 0;
>> +
>> + if ( vcpuid >= d->max_vcpus || (v = d->vcpu[vcpuid]) == NULL )
>> + {
>> + dprintk(XENLOG_G_ERR, "HVM restore: dom%d has no vcpu%u\n",
>> + d->domain_id, vcpuid);
>> + return -EINVAL;
>> + }
>> +
>> + /* Customized checking for entry since our entry is of variable
>> length */ + desc = (struct hvm_save_descriptor *)&h->data[h->cur];
>> + if ( sizeof (*desc) > h->size - h->cur)
>> + {
>> + printk(XENLOG_G_WARNING
>> + "HVM%d.%d restore: not enough data left to read MSR
>> descriptor\n", + d->domain_id, vcpuid);
>> + return -ENODATA;
>> + }
>> + if ( desc->length + sizeof (*desc) > h->size - h->cur)
>> + {
>> + printk(XENLOG_G_WARNING
>> + "HVM%d.%d restore: not enough data left to read %u
>> MSR bytes\n", + d->domain_id, vcpuid, desc->length);
>> + return -ENODATA;
>> + }
>> + if ( desc->length < HVM_CPU_MSR_SIZE(1) )
>> + {
>> + printk(XENLOG_G_WARNING
>> + "HVM%d.%d restore mismatch: MSR length %u < %zu\n",
>> + d->domain_id, vcpuid, desc->length,
>> HVM_CPU_MSR_SIZE(1)); + return -EINVAL;
>> + }
>> +
>> + h->cur += sizeof(*desc);
>> + ctxt = (struct hvm_msr *)&h->data[h->cur];
>> + h->cur += desc->length;
>> +
>> + if ( desc->length != HVM_CPU_MSR_SIZE(ctxt->count) )
>> + {
>> + printk(XENLOG_G_WARNING
>> + "HVM%d.%d restore mismatch: MSR length %u != %zu\n",
>> + d->domain_id, vcpuid, desc->length,
>> + HVM_CPU_MSR_SIZE(ctxt->count));
>> + return -EOPNOTSUPP;
>> + }
>> +
>> + for ( i = 0; i < ctxt->count; ++i )
>> + if ( ctxt->msr[i]._rsvd )
>> + return -EOPNOTSUPP;
>> + /* Checking finished */
>> +
>> + if ( hvm_funcs.load_msr )
>> + err = hvm_funcs.load_msr(v, ctxt);
>> +
>> + for ( i = 0; !err && i < ctxt->count; ++i )
>> + {
>> + switch ( ctxt->msr[i].index )
>> + {
>> + default:
>> + if ( !ctxt->msr[i]._rsvd )
>> + err = -ENXIO;
>> + break;
>> + }
>> + }
>> +
>> + return err;
>> +}
>> +
>> +/* We need variable length data chunks for XSAVE area and MSRs, hence
>> + * a custom declaration rather than HVM_REGISTER_SAVE_RESTORE.
>> */
>> -static int __init __hvm_register_CPU_XSAVE_save_and_restore(void)
>> +static int __init hvm_register_CPU_save_and_restore(void)
>> {
>> hvm_register_savevm(CPU_XSAVE_CODE,
>> "CPU_XSAVE",
>> @@ -1139,9 +1246,22 @@ static int __init __hvm_register_CPU_XSA
>> HVM_CPU_XSAVE_SIZE(xfeature_mask) +
>> sizeof(struct hvm_save_descriptor),
>> HVMSR_PER_VCPU);
>> +
>> + if ( hvm_funcs.init_msr )
>> + msr_count_max += hvm_funcs.init_msr();
>> +
>> + if ( msr_count_max )
>> + hvm_register_savevm(CPU_MSR_CODE,
>> + "CPU_MSR",
>> + hvm_save_cpu_msrs,
>> + hvm_load_cpu_msrs,
>> + HVM_CPU_MSR_SIZE(msr_count_max) +
>> + sizeof(struct hvm_save_descriptor),
>> + HVMSR_PER_VCPU);
>> +
>> return 0;
>> }
>> -__initcall(__hvm_register_CPU_XSAVE_save_and_restore);
>> +__initcall(hvm_register_CPU_save_and_restore);
>>
>> int hvm_vcpu_initialise(struct vcpu *v)
>> {
>> --- a/xen/include/asm-x86/hvm/hvm.h
>> +++ b/xen/include/asm-x86/hvm/hvm.h
>> @@ -109,6 +109,10 @@ struct hvm_function_table {
>> void (*save_cpu_ctxt)(struct vcpu *v, struct hvm_hw_cpu *ctxt);
>> int (*load_cpu_ctxt)(struct vcpu *v, struct hvm_hw_cpu *ctxt);
>>
>> + unsigned int (*init_msr)(void);
>> + void (*save_msr)(struct vcpu *, struct hvm_msr *);
>> + int (*load_msr)(struct vcpu *, struct hvm_msr *);
>> +
>> /* Examine specifics of the guest state. */
>> unsigned int (*get_interrupt_shadow)(struct vcpu *v);
>> void (*set_interrupt_shadow)(struct vcpu *v, unsigned int
>> intr_shadow); --- a/xen/include/public/arch-x86/hvm/save.h
>> +++ b/xen/include/public/arch-x86/hvm/save.h
>> @@ -592,9 +592,21 @@ struct hvm_tsc_adjust {
>>
>> DECLARE_HVM_SAVE_TYPE(TSC_ADJUST, 19, struct hvm_tsc_adjust);
>>
>> +
>> +struct hvm_msr {
>> + uint32_t count;
>> + struct hvm_one_msr {
>> + uint32_t index;
>> + uint32_t _rsvd;
>> + uint64_t val;
>> + } msr[1 /* variable size */];
>> +};
>> +
>> +#define CPU_MSR_CODE 20
>> +
>
> +DECLARE_HVM_SAVE_TYPE(CPU_MSR, CPU_MSR_CODE, struct hvm_msr);
> +msr dump patch at tools/misc/xen-hvmctx.c
Sorry, I don't follow what this is to mean. If that other patch of
yours needs adjustment, then this surely doesn't belong here.
Jan
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |