|
[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, ®->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, ®->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, ®->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, ®->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, ®->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, ®->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), ®->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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |