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@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
This commit is contained in:
Andrew Cooper committed 2016-12-02 12:56:38 +00:00
1 parent 660eb42c02
commit da2209921e
2 files changed
+14 -70

No files matched your search

+10 -70
View File
@@ -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);
+4
View File
@@ -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,
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.