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

[Xen-changelog] [xen master] x86/vmx: Shorten vmx_{get, set}_segment_register() for user segments



commit da2209921e509d809f049b98467b019b4600aebb
Author:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
AuthorDate: Fri Sep 23 15:03:08 2016 +0100
Commit:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CommitDate: Fri Dec 2 12:56:38 2016 +0000

    x86/vmx: Shorten vmx_{get,set}_segment_register() for user segments
    
    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>
    Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
    Acked-by: Kevin Tian <kevin.tian@xxxxxxxxx>
---
 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 7b2c50c..47de375 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);
@@ -1133,41 +1103,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,
--
generated by git-patchbot for /home/xen/git/xen.git#master

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

 


Rackspace

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