From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Jan Beulich" Subject: Re: [PATCH v5 4/7] X86: generic MSRs save/restore Date: Wed, 04 Dec 2013 14:18:42 +0000 Message-ID: <529F47D2020000780010A0E4@nat28.tlf.novell.com> References: Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=__Part4E7D8ED2.3__=" Return-path: In-Reply-To: List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: Jinsong Liu Cc: Andrew Cooper , "xen-devel@lists.xen.org" , "keir@xen.org" , "Ian.Campbell@citrix.com" , "haoxudong.hao@gmail.com" List-Id: xen-devel@lists.xenproject.org This is a MIME message. If you are reading this text, you may want to consider changing to a mail reader or gateway that understands how to properly handle MIME multipart messages. --=__Part4E7D8ED2.3__= Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: quoted-printable Content-Disposition: inline >>> On 03.12.13 at 15:50, "Liu, Jinsong" wrote: > Subject: [PATCH v5 4/7] X86: generic MSRs save/restore >=20 > This patch introduced 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. >=20 > Suggested-by: Jan Beulich Attached is (obviously compile tested only) what I really suggested. Jan --=__Part4E7D8ED2.3__= Content-Type: text/plain; name="x86-MSR-sr.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="x86-MSR-sr.patch" x86: generic MSRs save/restore=0A=0AThis patch introduces a generic MSRs = save/restore mechanism, so that=0Ain the future new MSRs save/restore = could be added w/ smaller change=0Athan the full blown addition of a new = save/restore type.=0A=0ASigned-off-by: Jan Beulich =0A= =0A--- a/xen/arch/x86/hvm/hvm.c=0A+++ b/xen/arch/x86/hvm/hvm.c=0A@@ = -1127,10 +1127,110 @@ static int hvm_load_cpu_xsave_states(str=0A = return 0;=0A }=0A =0A-/* We need variable length data chunk for xsave = area, hence customized=0A- * declaration other than HVM_REGISTER_SAVE_RESTO= RE.=0A+#define HVM_CPU_MSR_SIZE(cnt) offsetof(struct hvm_msr, msr[cnt])=0A+= static unsigned int __read_mostly msr_count_max;=0A+=0A+static int = hvm_save_cpu_msrs(struct domain *d, hvm_domain_context_t *h)=0A+{=0A+ = struct vcpu *v;=0A+=0A+ if ( !msr_count_max )=0A+ return = 0;=0A+=0A+ for_each_vcpu ( d, v )=0A+ {=0A+ struct hvm_msr = *ctxt;=0A+ unsigned int i;=0A+=0A+ if ( _hvm_init_entry(h, = CPU_MSR_CODE, v->vcpu_id,=0A+ HVM_CPU_MSR_SIZE(= msr_count_max)) )=0A+ return 1;=0A+ ctxt =3D (struct = hvm_msr *)&h->data[h->cur];=0A+ ctxt->count =3D 0;=0A+=0A+ = if ( hvm_funcs.save_msr )=0A+ hvm_funcs.save_msr(v, ctxt);=0A+= =0A+ for ( i =3D 0; i < ctxt->count; ++i )=0A+ ctxt->msr[= i]._rsvd =3D 0;=0A+=0A+ if ( ctxt->count )=0A+ h->cur = +=3D HVM_CPU_MSR_SIZE(ctxt->count);=0A+ else=0A+ h->cur = -=3D sizeof(struct hvm_save_descriptor);=0A+ }=0A+=0A+ return = 0;=0A+}=0A+=0A+static int hvm_load_cpu_msrs(struct domain *d, hvm_domain_co= ntext_t *h)=0A+{=0A+ unsigned int i, vcpuid =3D hvm_load_instance(h);=0A= + struct vcpu *v;=0A+ const struct hvm_save_descriptor *desc;=0A+ = const struct hvm_msr *ctxt;=0A+ int err =3D 0;=0A+=0A+ if ( vcpuid = >=3D d->max_vcpus || (v =3D d->vcpu[vcpuid]) =3D=3D NULL )=0A+ {=0A+ = dprintk(XENLOG_G_ERR, "HVM restore: dom%d has no vcpu%u\n",=0A+ = d->domain_id, vcpuid);=0A+ return -EINVAL;=0A+ }=0A+=0A+ = /* Customized checking for entry since our entry is of variable length = */=0A+ desc =3D (struct hvm_save_descriptor *)&h->data[h->cur];=0A+ = if ( sizeof (*desc) > h->size - h->cur)=0A+ {=0A+ printk(XENLOG_G= _WARNING=0A+ "HVM%d.%d restore: not enough data left to read = MSR descriptor\n",=0A+ d->domain_id, vcpuid);=0A+ = return -ENODATA;=0A+ }=0A+ if ( desc->length + sizeof (*desc) > = h->size - h->cur)=0A+ {=0A+ printk(XENLOG_G_WARNING=0A+ = "HVM%d.%d restore: not enough data left to read %u MSR bytes\n",=0A+ = d->domain_id, vcpuid, desc->length);=0A+ return = -ENODATA;=0A+ }=0A+ if ( desc->length < HVM_CPU_MSR_SIZE(1) )=0A+ = {=0A+ printk(XENLOG_G_WARNING=0A+ "HVM%d.%d restore = mismatch: MSR length %u < %zu\n",=0A+ d->domain_id, vcpuid, = desc->length, HVM_CPU_MSR_SIZE(1));=0A+ return -EINVAL;=0A+ = }=0A+=0A+ h->cur +=3D sizeof(*desc);=0A+ ctxt =3D (struct hvm_msr = *)&h->data[h->cur];=0A+ h->cur +=3D desc->length;=0A+=0A+ if ( = desc->length !=3D HVM_CPU_MSR_SIZE(ctxt->count) )=0A+ {=0A+ = printk(XENLOG_G_WARNING=0A+ "HVM%d.%d restore mismatch: MSR = length %u !=3D %zu\n",=0A+ d->domain_id, vcpuid, desc->length= ,=0A+ HVM_CPU_MSR_SIZE(ctxt->count));=0A+ return = -EOPNOTSUPP;=0A+ }=0A+ /* Checking finished */=0A+=0A+ for ( i = =3D 0; i < ctxt->count; ++i )=0A+ {=0A+ if ( hvm_funcs.load_msr = )=0A+ err =3D hvm_funcs.load_msr(v, &ctxt->msr[i]);=0A+ = if ( err )=0A+ break;=0A+ }=0A+=0A+ return err;=0A+}=0A+= =0A+/* We need variable length data chunks for XSAVE area and MSRs, = hence=0A+ * a custom declaration rather than HVM_REGISTER_SAVE_RESTORE.=0A = */=0A-static int __init __hvm_register_CPU_XSAVE_save_and_restore(void)=0A= +static int __init hvm_register_CPU_save_and_restore(void)=0A {=0A = hvm_register_savevm(CPU_XSAVE_CODE,=0A "CPU_XSAVE",= =0A@@ -1139,9 +1239,22 @@ static int __init __hvm_register_CPU_XSA=0A = HVM_CPU_XSAVE_SIZE(xfeature_mask) +=0A = sizeof(struct hvm_save_descriptor),=0A = HVMSR_PER_VCPU);=0A+=0A+ if ( hvm_funcs.init_msr )=0A+ msr_count_= max +=3D hvm_funcs.init_msr();=0A+=0A+ if ( msr_count_max )=0A+ = hvm_register_savevm(CPU_MSR_CODE,=0A+ "CPU_MSR",= =0A+ hvm_save_cpu_msrs,=0A+ = hvm_load_cpu_msrs,=0A+ HVM_CPU_MSR_SIZE(m= sr_count_max) +=0A+ sizeof(struct hvm_save_d= escriptor),=0A+ HVMSR_PER_VCPU);=0A+=0A = return 0;=0A }=0A-__initcall(__hvm_register_CPU_XSAVE_save_and_restore);=0A= +__initcall(hvm_register_CPU_save_and_restore);=0A =0A int hvm_vcpu_initial= ise(struct vcpu *v)=0A {=0A--- a/xen/include/asm-x86/hvm/hvm.h=0A+++ = b/xen/include/asm-x86/hvm/hvm.h=0A@@ -109,6 +109,10 @@ struct hvm_function_= table {=0A void (*save_cpu_ctxt)(struct vcpu *v, struct hvm_hw_cpu = *ctxt);=0A int (*load_cpu_ctxt)(struct vcpu *v, struct hvm_hw_cpu = *ctxt);=0A =0A+ unsigned int (*init_msr)(void);=0A+ void (*save_msr)(= struct vcpu *, struct hvm_msr *);=0A+ int (*load_msr)(struct vcpu *, = const struct hvm_one_msr *);=0A+=0A /* Examine specifics of the guest = state. */=0A unsigned int (*get_interrupt_shadow)(struct vcpu *v);=0A = void (*set_interrupt_shadow)(struct vcpu *v, unsigned int intr_shadow);= =0A--- a/xen/include/public/arch-x86/hvm/save.h=0A+++ b/xen/include/public/= arch-x86/hvm/save.h=0A@@ -592,9 +592,21 @@ struct hvm_tsc_adjust {=0A =0A = DECLARE_HVM_SAVE_TYPE(TSC_ADJUST, 19, struct hvm_tsc_adjust);=0A =0A+=0A+st= ruct hvm_msr {=0A+ uint32_t count;=0A+ struct hvm_one_msr {=0A+ = uint32_t index;=0A+ uint32_t _rsvd;=0A+ uint64_t val;=0A+ = } msr[1 /* variable size */];=0A+};=0A+=0A+#define CPU_MSR_CODE = 16=0A+=0A /* =0A * Largest type-code in use=0A */=0A-#define HVM_SAVE_COD= E_MAX 19=0A+#define HVM_SAVE_CODE_MAX 20=0A =0A #endif /* __XEN_PUBLIC_HVM_= SAVE_X86_H__ */=0A --=__Part4E7D8ED2.3__= Content-Type: text/plain; name="x86-MPX-sr.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="x86-MPX-sr.patch" x86: MSR_IA32_BNDCFGS save/restore=0A=0ASigned-off-by: Jan Beulich = =0A=0A--- a/xen/arch/x86/hvm/vmx/vmx.c=0A+++ b/xen/arch/= x86/hvm/vmx/vmx.c=0A@@ -580,6 +580,50 @@ static int vmx_load_vmcs_ctxt(stru= ct vcp=0A return 0;=0A }=0A =0A+static unsigned int __init vmx_init_msr= (void)=0A+{=0A+ return !!cpu_has_mpx;=0A+}=0A+=0A+static void vmx_save_m= sr(struct vcpu *v, struct hvm_msr *ctxt)=0A+{=0A+ vmx_vmcs_enter(v);=0A+= =0A+ if ( cpu_has_mpx )=0A+ {=0A+ __vmread(GUEST_BNDCFGS, = &ctxt->msr[ctxt->count].val);=0A+ if ( ctxt->msr[ctxt->count].val = )=0A+ ctxt->msr[ctxt->count++].index =3D MSR_IA32_BNDCFGS;=0A+ = }=0A+=0A+ vmx_vmcs_exit(v);=0A+}=0A+=0A+static int vmx_load_msr(struct= vcpu *v, const struct hvm_one_msr *msr)=0A+{=0A+ int err =3D 0;=0A+=0A+= vmx_vmcs_enter(v);=0A+=0A+ switch ( msr->index )=0A+ {=0A+ = case MSR_IA32_BNDCFGS:=0A+ if ( cpu_has_mpx )=0A+ = __vmwrite(GUEST_BNDCFGS, msr->val);=0A+ else=0A+ err =3D = -ENXIO;=0A+ break;=0A+=0A+ default:=0A+ err =3D = -ENOENT;=0A+ break;=0A+ }=0A+=0A+ vmx_vmcs_exit(v);=0A+=0A+ = return err;=0A+}=0A+=0A static void vmx_fpu_enter(struct vcpu *v)=0A {=0A = vcpu_restore_fpu_lazy(v);=0A@@ -1606,6 +1650,9 @@ static struct = hvm_function_table __initd=0A .vcpu_destroy =3D vmx_vcpu_destro= y,=0A .save_cpu_ctxt =3D vmx_save_vmcs_ctxt,=0A .load_cpu_ct= xt =3D vmx_load_vmcs_ctxt,=0A+ .init_msr =3D = vmx_init_msr,=0A+ .save_msr =3D vmx_save_msr,=0A+ = .load_msr =3D vmx_load_msr,=0A .get_interrupt_shadow =3D = vmx_get_interrupt_shadow,=0A .set_interrupt_shadow =3D vmx_set_interrup= t_shadow,=0A .guest_x86_mode =3D vmx_guest_x86_mode,=0A--- = a/xen/include/asm-x86/hvm/vmx/vmcs.h=0A+++ b/xen/include/asm-x86/hvm/vmx/vm= cs.h=0A@@ -367,6 +367,8 @@ enum vmcs_field {=0A GUEST_PDPTR2_HIGH = =3D 0x0000280f,=0A GUEST_PDPTR3 =3D = 0x00002810,=0A GUEST_PDPTR3_HIGH =3D 0x00002811,=0A+ = GUEST_BNDCFGS =3D 0x00002812,=0A+ GUEST_BNDCFGS_HIGH = =3D 0x00002813,=0A HOST_PAT =3D = 0x00002c00,=0A HOST_PAT_HIGH =3D 0x00002c01,=0A = HOST_EFER =3D 0x00002c02,=0A --=__Part4E7D8ED2.3__= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel --=__Part4E7D8ED2.3__=--