Isaku Yamahata wrote:
 
>>      2: Same IVT source code, but dual/mulitple compile to generate
>> dual/multiple IVT table. I.e. we replace those primitive ops
>> (sensitive instructions) with a MACRO which uses compile option for
>>              different hypervisor type. The pseudo code of the MACRO
could be:
>> (take read CR.IVR 
>> as example)
>> 
>> AltA:
>> #define ASM_READ_IVR /* read IVR to GR24 */
>> #ifdef XEN
>>      breg1 = return address
>>      br    xen_readivr
>> #else        /* native
>>      mov  GR24=CR.IVR;
>> #endif
>>              Or
>> AltB:
>> #define ASM_READ_IVR /* read IVR to GR24 */
>> #ifdef XEN
>>      in place code of function xen_readivr
>> #else        /* native
>>      mov  GR24=CR.IVR;
>> #endif
>> 
>>              From maintenance effort point of view, it is minimized,
>> but not exactly what X86 pv_ops look like.
>> 
>>              Both approach will cause code size issue, but altB is
>> much worse in this area, while AltA need one additional BR clobber
>> register
> 
> 
> Pros:
> - single code
> - hopefull less maintenance cost compared to #1
> 
> Cons:
> - requires restriction on register usage. And we need to define its
>   convension.
>   When modifying ivt.S in the future after converting ivt.S,
>   those convesion must be kept in mind.
> - suboptimal for paravirtualized case compared to #1 case
> 
> 
>>      3: Single IVT table, using indirect function call for pv_ops.
>>              This is more like X86 pv_ops, but we need to pay 2
>> additional BR clobber registers due to indirect function call, like
>> following pseudo code: 
>> 
>> AltC:
>>      breg0 = pv_ops base
>>      breg0 += offset for this pv_ops
>>      breg1 = return address;
>>      br  breg0.              /* pv_ops clobbered breg0/breg1 */
>> 
>> 
>>      For both #2 & #3, we need to modify Linux IVT code to get
>> clobber register for those MACROs, #3 need 2 br registers and 1-2 GR
>> registers for the function body. #2A needs least clobber register,
>> just 1-2 GR registers.
> 
> #2B may also need clobber 1(or 2?) GR registers depending on the
> original instruction.

Yes, clobber GR # is almost same for all Alts.

> 
> Pros:
> - single code/binary
> - less maintenance cost
> 
> Cons:
> - requires restriction on register usage. And we need to define its
>   convension.
>   When modifying ivt.S in the future after converting ivt.S,
>   those convesion must be kept in mind.
> - more clobbered register (for AltC)
> - suboptimal even for native case.

After binary patching, native side won't have impact. 
We can have in place patching, i..e. replace whole AltC
code dynamically with "mov GRx=CR.IVR;nop;nop..."

> 
> Presumably we can use binary patching technique to mitigate those
> overhead. Probably for native case, we can convert those branch with
> single instruction.
> For example we can make 'br breg0' into direct branch.

If it is single IVT table, we don't know the target address of
the function call.

> AltD(AltC'):
>         breg1 = return address;
>         br  native_pv_ops_ops   <=== binary patch at boot time
> 

?? Are u talking about AltA?

thanks, Eddie

_______________________________________________
Xen-ia64-devel mailing list
Xen-ia64-devel@lists.xensource.com
http://lists.xensource.com/xen-ia64-devel

Reply via email to