All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH for-4.9] x86/vmx: Shorten vmx_{get, set}_segment_register() for user segments
@ 2016-10-26 13:15 Andrew Cooper
  2016-10-26 13:40 ` Jan Beulich
  2016-11-16 13:42 ` Andrew Cooper
  0 siblings, 2 replies; 5+ messages in thread
From: Andrew Cooper @ 2016-10-26 13:15 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper, Kevin Tian, Jun Nakajima, Jan Beulich

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>
---
CC: Jan Beulich <JBeulich@suse.com>
CC: Jun Nakajima <jun.nakajima@intel.com>
CC: Kevin Tian <kevin.tian@intel.com>
---
 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,
-- 
2.1.4


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

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH for-4.9] x86/vmx: Shorten vmx_{get, set}_segment_register() for user segments
  2016-10-26 13:15 [PATCH for-4.9] x86/vmx: Shorten vmx_{get, set}_segment_register() for user segments Andrew Cooper
@ 2016-10-26 13:40 ` Jan Beulich
  2016-11-16 13:42 ` Andrew Cooper
  1 sibling, 0 replies; 5+ messages in thread
From: Jan Beulich @ 2016-10-26 13:40 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Kevin Tian, Jun Nakajima, Xen-devel

>>> On 26.10.16 at 15:15, <andrew.cooper3@citrix.com> 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@citrix.com>

Nice.

Reviewed-by: Jan Beulich <jbeulich@suse.com>

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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH for-4.9] x86/vmx: Shorten vmx_{get, set}_segment_register() for user segments
  2016-10-26 13:15 [PATCH for-4.9] x86/vmx: Shorten vmx_{get, set}_segment_register() for user segments Andrew Cooper
  2016-10-26 13:40 ` Jan Beulich
@ 2016-11-16 13:42 ` Andrew Cooper
  2016-11-17  5:10   ` Tian, Kevin
  1 sibling, 1 reply; 5+ messages in thread
From: Andrew Cooper @ 2016-11-16 13:42 UTC (permalink / raw)
  To: Xen-devel; +Cc: Kevin Tian, Jun Nakajima, Jan Beulich

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@citrix.com>
> ---
> CC: Jan Beulich <JBeulich@suse.com>
> CC: Jun Nakajima <jun.nakajima@intel.com>
> CC: Kevin Tian <kevin.tian@intel.com>

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@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH for-4.9] x86/vmx: Shorten vmx_{get, set}_segment_register() for user segments
  2016-11-16 13:42 ` Andrew Cooper
@ 2016-11-17  5:10   ` Tian, Kevin
  2016-11-17 11:59     ` Andrew Cooper
  0 siblings, 1 reply; 5+ messages in thread
From: Tian, Kevin @ 2016-11-17  5:10 UTC (permalink / raw)
  To: Andrew Cooper, Xen-devel; +Cc: Nakajima, Jun, Jan Beulich

> From: Andrew Cooper [mailto:andrew.cooper3@citrix.com]
> Sent: Wednesday, November 16, 2016 9:42 PM
> 
> 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@citrix.com>
> > ---
> > CC: Jan Beulich <JBeulich@suse.com>
> > CC: Jun Nakajima <jun.nakajima@intel.com>
> > CC: Kevin Tian <kevin.tian@intel.com>
> 
> Intel: Ping?

Acked-by: Kevin Tian <kevin.tian@intel.com>


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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH for-4.9] x86/vmx: Shorten vmx_{get, set}_segment_register() for user segments
  2016-11-17  5:10   ` Tian, Kevin
@ 2016-11-17 11:59     ` Andrew Cooper
  0 siblings, 0 replies; 5+ messages in thread
From: Andrew Cooper @ 2016-11-17 11:59 UTC (permalink / raw)
  To: Tian, Kevin, Xen-devel; +Cc: Nakajima, Jun, Jan Beulich

On 17/11/16 05:10, Tian, Kevin wrote:
>> From: Andrew Cooper [mailto:andrew.cooper3@citrix.com]
>> Sent: Wednesday, November 16, 2016 9:42 PM
>>
>> 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@citrix.com>
>>> ---
>>> CC: Jan Beulich <JBeulich@suse.com>
>>> CC: Jun Nakajima <jun.nakajima@intel.com>
>>> CC: Kevin Tian <kevin.tian@intel.com>
>> Intel: Ping?
> Acked-by: Kevin Tian <kevin.tian@intel.com>

Thanks.  Queued for 4.9.

~Andrew

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

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2016-11-17 11:59 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-10-26 13:15 [PATCH for-4.9] x86/vmx: Shorten vmx_{get, set}_segment_register() for user segments Andrew Cooper
2016-10-26 13:40 ` Jan Beulich
2016-11-16 13:42 ` Andrew Cooper
2016-11-17  5:10   ` Tian, Kevin
2016-11-17 11:59     ` Andrew Cooper

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.