[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH for-4.9] x86/vmx: Shorten vmx_{get, set}_segment_register() for user segments



On 26/10/16 14:15, Andrew Cooper wrote:
> The x86_segment enumeration matches hardware SReg encoding, which can be used
> to calculate the appropriate VMCS fields, rather than open coding every
> instance.
>
> This reduces the size of the switch statement, and the number of embedded BUG
> frames from the __vm{read,write}() calls.  In the unlikely case that a call
> does fault, the field can unambiguously be retrieved from the GPR state
> printed.
>
> Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
> ---
> CC: Jan Beulich <JBeulich@xxxxxxxx>
> CC: Jun Nakajima <jun.nakajima@xxxxxxxxx>
> CC: Kevin Tian <kevin.tian@xxxxxxxxx>

Intel: Ping?

> ---
>  xen/arch/x86/hvm/vmx/vmx.c         | 80 
> +++++---------------------------------
>  xen/include/asm-x86/hvm/vmx/vmcs.h |  4 ++
>  2 files changed, 14 insertions(+), 70 deletions(-)
>
> diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
> index 4d30eae..459f9cd 100644
> --- a/xen/arch/x86/hvm/vmx/vmx.c
> +++ b/xen/arch/x86/hvm/vmx/vmx.c
> @@ -969,41 +969,11 @@ void vmx_get_segment_register(struct vcpu *v, enum 
> x86_segment seg,
>  
>      switch ( seg )
>      {
> -    case x86_seg_cs:
> -        __vmread(GUEST_CS_SELECTOR, &sel);
> -        __vmread(GUEST_CS_LIMIT,    &limit);
> -        __vmread(GUEST_CS_BASE,     &reg->base);
> -        __vmread(GUEST_CS_AR_BYTES, &attr);
> -        break;
> -    case x86_seg_ds:
> -        __vmread(GUEST_DS_SELECTOR, &sel);
> -        __vmread(GUEST_DS_LIMIT,    &limit);
> -        __vmread(GUEST_DS_BASE,     &reg->base);
> -        __vmread(GUEST_DS_AR_BYTES, &attr);
> -        break;
> -    case x86_seg_es:
> -        __vmread(GUEST_ES_SELECTOR, &sel);
> -        __vmread(GUEST_ES_LIMIT,    &limit);
> -        __vmread(GUEST_ES_BASE,     &reg->base);
> -        __vmread(GUEST_ES_AR_BYTES, &attr);
> -        break;
> -    case x86_seg_fs:
> -        __vmread(GUEST_FS_SELECTOR, &sel);
> -        __vmread(GUEST_FS_LIMIT,    &limit);
> -        __vmread(GUEST_FS_BASE,     &reg->base);
> -        __vmread(GUEST_FS_AR_BYTES, &attr);
> -        break;
> -    case x86_seg_gs:
> -        __vmread(GUEST_GS_SELECTOR, &sel);
> -        __vmread(GUEST_GS_LIMIT,    &limit);
> -        __vmread(GUEST_GS_BASE,     &reg->base);
> -        __vmread(GUEST_GS_AR_BYTES, &attr);
> -        break;
> -    case x86_seg_ss:
> -        __vmread(GUEST_SS_SELECTOR, &sel);
> -        __vmread(GUEST_SS_LIMIT,    &limit);
> -        __vmread(GUEST_SS_BASE,     &reg->base);
> -        __vmread(GUEST_SS_AR_BYTES, &attr);
> +    case x86_seg_es ... x86_seg_gs:
> +        __vmread(GUEST_SEG_SELECTOR(seg), &sel);
> +        __vmread(GUEST_SEG_LIMIT(seg),    &limit);
> +        __vmread(GUEST_SEG_BASE(seg),     &reg->base);
> +        __vmread(GUEST_SEG_AR_BYTES(seg), &attr);
>          break;
>      case x86_seg_tr:
>          __vmread(GUEST_TR_SELECTOR, &sel);
> @@ -1131,41 +1101,11 @@ static void vmx_set_segment_register(struct vcpu *v, 
> enum x86_segment seg,
>  
>      switch ( seg )
>      {
> -    case x86_seg_cs:
> -        __vmwrite(GUEST_CS_SELECTOR, sel);
> -        __vmwrite(GUEST_CS_LIMIT, limit);
> -        __vmwrite(GUEST_CS_BASE, base);
> -        __vmwrite(GUEST_CS_AR_BYTES, attr);
> -        break;
> -    case x86_seg_ds:
> -        __vmwrite(GUEST_DS_SELECTOR, sel);
> -        __vmwrite(GUEST_DS_LIMIT, limit);
> -        __vmwrite(GUEST_DS_BASE, base);
> -        __vmwrite(GUEST_DS_AR_BYTES, attr);
> -        break;
> -    case x86_seg_es:
> -        __vmwrite(GUEST_ES_SELECTOR, sel);
> -        __vmwrite(GUEST_ES_LIMIT, limit);
> -        __vmwrite(GUEST_ES_BASE, base);
> -        __vmwrite(GUEST_ES_AR_BYTES, attr);
> -        break;
> -    case x86_seg_fs:
> -        __vmwrite(GUEST_FS_SELECTOR, sel);
> -        __vmwrite(GUEST_FS_LIMIT, limit);
> -        __vmwrite(GUEST_FS_BASE, base);
> -        __vmwrite(GUEST_FS_AR_BYTES, attr);
> -        break;
> -    case x86_seg_gs:
> -        __vmwrite(GUEST_GS_SELECTOR, sel);
> -        __vmwrite(GUEST_GS_LIMIT, limit);
> -        __vmwrite(GUEST_GS_BASE, base);
> -        __vmwrite(GUEST_GS_AR_BYTES, attr);
> -        break;
> -    case x86_seg_ss:
> -        __vmwrite(GUEST_SS_SELECTOR, sel);
> -        __vmwrite(GUEST_SS_LIMIT, limit);
> -        __vmwrite(GUEST_SS_BASE, base);
> -        __vmwrite(GUEST_SS_AR_BYTES, attr);
> +    case x86_seg_es ... x86_seg_gs:
> +        __vmwrite(GUEST_SEG_SELECTOR(seg), sel);
> +        __vmwrite(GUEST_SEG_LIMIT(seg),    limit);
> +        __vmwrite(GUEST_SEG_BASE(seg),     base);
> +        __vmwrite(GUEST_SEG_AR_BYTES(seg), attr);
>          break;
>      case x86_seg_tr:
>          __vmwrite(GUEST_TR_SELECTOR, sel);
> diff --git a/xen/include/asm-x86/hvm/vmx/vmcs.h 
> b/xen/include/asm-x86/hvm/vmx/vmcs.h
> index 997f4f5..894093d 100644
> --- a/xen/include/asm-x86/hvm/vmx/vmcs.h
> +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h
> @@ -420,6 +420,7 @@ enum vmcs_field {
>      VIRTUAL_PROCESSOR_ID            = 0x00000000,
>      POSTED_INTR_NOTIFICATION_VECTOR = 0x00000002,
>      EPTP_INDEX                      = 0x00000004,
> +#define GUEST_SEG_SELECTOR(sel) (GUEST_ES_SELECTOR + (sel) * 2) /* ES ... GS 
> */
>      GUEST_ES_SELECTOR               = 0x00000800,
>      GUEST_CS_SELECTOR               = 0x00000802,
>      GUEST_SS_SELECTOR               = 0x00000804,
> @@ -496,6 +497,7 @@ enum vmcs_field {
>      IDT_VECTORING_ERROR_CODE        = 0x0000440a,
>      VM_EXIT_INSTRUCTION_LEN         = 0x0000440c,
>      VMX_INSTRUCTION_INFO            = 0x0000440e,
> +#define GUEST_SEG_LIMIT(sel) (GUEST_ES_LIMIT + (sel) * 2) /* ES ... GS */
>      GUEST_ES_LIMIT                  = 0x00004800,
>      GUEST_CS_LIMIT                  = 0x00004802,
>      GUEST_SS_LIMIT                  = 0x00004804,
> @@ -506,6 +508,7 @@ enum vmcs_field {
>      GUEST_TR_LIMIT                  = 0x0000480e,
>      GUEST_GDTR_LIMIT                = 0x00004810,
>      GUEST_IDTR_LIMIT                = 0x00004812,
> +#define GUEST_SEG_AR_BYTES(sel) (GUEST_ES_AR_BYTES + (sel) * 2) /* ES ... GS 
> */
>      GUEST_ES_AR_BYTES               = 0x00004814,
>      GUEST_CS_AR_BYTES               = 0x00004816,
>      GUEST_SS_AR_BYTES               = 0x00004818,
> @@ -531,6 +534,7 @@ enum vmcs_field {
>      GUEST_CR0                       = 0x00006800,
>      GUEST_CR3                       = 0x00006802,
>      GUEST_CR4                       = 0x00006804,
> +#define GUEST_SEG_BASE(sel) (GUEST_ES_BASE + (sel) * 2) /* ES ... GS */
>      GUEST_ES_BASE                   = 0x00006806,
>      GUEST_CS_BASE                   = 0x00006808,
>      GUEST_SS_BASE                   = 0x0000680a,


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.