Re: [PATCH 2/4] kvm-unit-tests: VMX: Add test cases for CR0/4 shadowing
在 2013-8-18,22:07,Paolo Bonzini 写道: > Il 15/08/2013 09:59, Arthur Chunqi Li ha scritto: volatile u32 stage? And we have barrier() to avoid reordering. >> Reordering here is not a big deal here, though it is actually needed >> here. I occurred the following problem: >> >> stage = 1; >> do something that causes vmexit; >> stage = 2; >> >> Then the compiler will optimize "stage = 1" and "stage = 2" to one >> instruction "stage =2", since instructions between them don't use >> "stage". Can volatile solve this problem? > > I'm not sure if volatile stores are reordered against non-volatile stores. > > Better keep set_stage() but write it as > >barrier(); >stage = s; >barrier(); Yep. I have done it like this in the 2nd version. Arthur > > Paolo -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] KVM: nVMX: Advertise IA32_PAT in VM exit control
> On Mon, Aug 05, 2013 at 05:10:35PM +0800, Arthur Chunqi Li wrote: >> Advertise VM_EXIT_SAVE_IA32_PAT and VM_EXIT_LOAD_IA32_PAT. >> >> Signed-off-by: Arthur Chunqi Li >> --- >> arch/x86/kvm/vmx.c |3 ++- >> 1 file changed, 2 insertions(+), 1 deletion(-) >> >> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c >> index 45fd70c..240f0db 100644 >> --- a/arch/x86/kvm/vmx.c >> +++ b/arch/x86/kvm/vmx.c >> @@ -2198,7 +2198,8 @@ static __init void nested_vmx_setup_ctls_msrs(void) >> #else >>nested_vmx_exit_ctls_high = 0; >> #endif >> -nested_vmx_exit_ctls_high |= VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR; >> +nested_vmx_exit_ctls_high |= VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR | >> +VM_EXIT_LOAD_IA32_PAT | VM_EXIT_SAVE_IA32_PAT; >> > You should not set those if host does not support them, otherwise > GUEST_IA32_PAT may not be available To Jan, Is this different from IA32_EFER? Arthur > > -- >Gleb. -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] kvm-unit-tests: VMX: Fix confused definition of rflags
在 2013-8-5,17:10,Gleb Natapov 写道: > On Mon, Aug 05, 2013 at 04:48:47PM +0800, Arthur Chunqi Li wrote: >> On Mon, Aug 5, 2013 at 4:29 PM, Gleb Natapov wrote: >>> On Tue, Jul 30, 2013 at 11:41:00PM +0800, Arthur Chunqi Li wrote: Change "rflags" in "struct regs" to "host_rflags". Remove settings to GUEST_RFLAGS since GUEST_RFLAGS can be set by vmwrite. Treat host_rflags as host rflags before and after vmenter. >>> I am not sure the change is for the better. Before the change one could >>> set up rflags for guest environment by setting regs.rflags, no special >>> init function had to be written. I do not see any problem with correct >>> code, except that rflags is not correct on a guest entry, but this >>> should be easy to fix. >> regs.rflags are designed to set guest rflags, but the current >> implementation just use it as host_rflags. > Current implementation uses it to set guest flags at the beginning of > a test. > >> For every VM entry, it will >> load value set by vmcs_write(GUEST_RFLAGS). > Not for every vmentry, only for the first one. Doing it for every > vmentry without saving it first with vmcs_read would been incorrect. > >> Set regs.flags as host >> rflags and then enter VM cannot affect VM's rflags, which is the >> current implementation. > It can, on the first launch. It is easy to add code to exit_handler() to > set current->guest_regs.rflags correctly before calling test's exit handler > and write GUEST_RFLAGS according to current->guest_regs.rflags after > exit handler returns, but as you say below test can do it by itself in > exit handler if it wishes so. > >> Besides, if host want to set/get guest's rflags, it just use >> vmcs_write/read(GUEST_RFLAGS). > True, but to do it at the beginning of the test it will require to write > special init function even if non are needed otherwise. So you are > removing this functionality without clear benefit. True, so it seems better to keep it. However, now it is confused with host_rflags and not correctly set/get when vmentry/vmexit. I will commit another patch to fix both bugs. Arthur > >> Arthur >>> Besides, add checks to flags after vmenter. Signed-off-by: Arthur Chunqi Li --- x86/vmx.c | 11 ++- x86/vmx.h |2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/x86/vmx.c b/x86/vmx.c index 7467927..082c3bb 100644 --- a/x86/vmx.c +++ b/x86/vmx.c @@ -481,6 +481,8 @@ static int vmx_run() "vmresume\n\t" "2: " "setbe %0\n\t" + "jbe vmx_return\n\t" + "ud2\n\t" "vmx_return:\n\t" SAVE_GPR_C SAVE_RFLAGS @@ -505,15 +507,15 @@ static int vmx_run() return 0; case VMX_TEST_LAUNCH_ERR: printf("%s : vmlaunch failed.\n", __func__); - if ((!(regs.rflags & X86_EFLAGS_CF) && !(regs.rflags & X86_EFLAGS_ZF)) - || ((regs.rflags & X86_EFLAGS_CF) && (regs.rflags & X86_EFLAGS_ZF))) + if ((!(regs.host_rflags & X86_EFLAGS_CF) && !(regs.host_rflags & X86_EFLAGS_ZF)) + || ((regs.host_rflags & X86_EFLAGS_CF) && (regs.host_rflags & X86_EFLAGS_ZF))) printf("\tvmlaunch set wrong flags\n"); report("test vmlaunch", 0); break; case VMX_TEST_RESUME_ERR: printf("%s : vmresume failed.\n", __func__); - if ((!(regs.rflags & X86_EFLAGS_CF) && !(regs.rflags & X86_EFLAGS_ZF)) - || ((regs.rflags & X86_EFLAGS_CF) && (regs.rflags & X86_EFLAGS_ZF))) + if ((!(regs.host_rflags & X86_EFLAGS_CF) && !(regs.host_rflags & X86_EFLAGS_ZF)) + || ((regs.host_rflags & X86_EFLAGS_CF) && (regs.host_rflags & X86_EFLAGS_ZF))) printf("\tvmresume set wrong flags\n"); report("test vmresume", 0); break; @@ -540,7 +542,6 @@ static int test_run(struct vmx_test *test) test->exits = 0; current = test; regs = test->guest_regs; - vmcs_write(GUEST_RFLAGS, regs.rflags | 0x2); launched = 0; printf("\nTest suite : %s\n", test->name); vmx_run(); diff --git a/x86/vmx.h b/x86/vmx.h index 1fb9738..d80e000 100644 --- a/x86/vmx.h +++ b/x86/vmx.h @@ -27,7 +27,7 @@ struct regs { u64 r13; u64 r14; u64 r15; - u64 rflags; + u64 host_rflags; }; struct vmx_test { -- 1.7.9.5 >>> >>> -- >>>Gleb. > > -- >Gleb. -- To un
Re: [PATCH v2] kvm-unit-tests: VMX: Split VMX test suites to separate file
在 2013-8-5,2:08,Jan Kiszka 写道: > On 2013-08-04 20:04, Arthur Chunqi Li wrote: >> @@ -432,6 +432,22 @@ enum Ctrl1 { >> #define HYPERCALL_MASK0xFFF >> #define HYPERCALL_VMEXIT0x1 >> >> + >> +extern u64 hypercall_field; >> +extern u32 vpid_cnt; >> +extern ulong fix_cr0_set, fix_cr0_clr; >> +extern ulong fix_cr4_set, fix_cr4_clr; >> +extern struct regs regs; >> +extern struct vmx_test *current; >> +extern bool launched; > > You didn't address my question if we need them all to write test cases > or if some are actually core internal. You are right. Not all global variants in last version is necessary for test cases, so I move some of them to vmx.c internal. The rest ones in this version are needed by tests to identify some states. Arthur. > > The rest looks good. > > Jan > > -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2] kvm-unit-tests : Basic architecture of VMX nested test case
> On 2013-07-25 18:51, Bandan Das wrote: >> Arthur Chunqi Li writes: >> >>> This is the first version of VMX nested environment. It contains the >>> basic VMX instructions test cases, including VMXON/VMXOFF/VMXPTRLD/ >>> VMXPTRST/VMCLEAR/VMLAUNCH/VMRESUME/VMCALL. This patchalso tests the >>> basic execution routine in VMX nested environment andlet the VM print >>> "Hello World" to inform its successfully run. >>> >>> The first release also includes a test suite for vmenter (vmlaunch and >>> vmresume). Besides, hypercall mechanism is included and currently it is >>> used to invoke VM normal exit. >> >> What's the difference between this and the one you posted earlier : >> [PATCH] kvm-unit-tests : Basic architecture of VMX nested test case >> <1374730297-27169-1-git-send-email-yzt...@gmail.com> >> >> Can you please mention what's changed in v2 ? > > True. A changelog can go... Compared to v1, v2 removes two unused inline functions vmlaunch/vmresume in x86/vmx.h, and add host rflags in "struct regs" so that user can get host's rflags in exit_handler. > >> >> Bandan >> >>> New files added: >>> x86/vmx.h : contains all VMX related macro declerations >>> x86/vmx.c : main file for VMX nested test case >>> >>> Signed-off-by: Arthur Chunqi Li >>> --- > > ...here, ie. after the --- so that it wont be part of the commit. > > Jan > > -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] KVM : Fix read/write to IA32_FEATURE_CONTROL MSR in nested virt
在 2013-7-4,15:24,Gleb Natapov 写道: > On Thu, Jul 04, 2013 at 03:21:15PM +0800, Arthur Chunqi Li wrote: >> On Thu, Jul 4, 2013 at 3:10 PM, Gleb Natapov wrote: >>> On Thu, Jul 04, 2013 at 09:00:09AM +0200, Paolo Bonzini wrote: Il 03/07/2013 15:41, Arthur Chunqi Li ha scritto: > Fix read/write to IA32_FEATURE_CONTROL MSR in nested environment. > Simply return 0x5 when read and generate #GP(0) when write. > Delete handling codes in vmx_set_vmx_msr() and generate #GP(0) in > handle_wrmsr(). > > Signed-off-by: Arthur Chunqi Li > --- > arch/x86/kvm/vmx.c |5 + > 1 file changed, 1 insertion(+), 4 deletions(-) > > diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c > index 260a919..e125f94 100644 > --- a/arch/x86/kvm/vmx.c > +++ b/arch/x86/kvm/vmx.c > @@ -2277,7 +2277,7 @@ static int vmx_get_vmx_msr(struct kvm_vcpu *vcpu, > u32 msr_index, u64 *pdata) > >switch (msr_index) { >case MSR_IA32_FEATURE_CONTROL: > - *pdata = 0; > + *pdata = 0x5; >break; This is not in the MSR_IA32_VMX_BASIC..MSR_IA32_VMX_TRUE_ENTRY_CTLS range, so you must check nested_vmx_allowed and return 0 if it is false. >>> Or 1? >> I think 1 is better here because this may return LOCK message when >> query and tell OS not to write (if OS does such logical check) >>> Otherwise looks good. Paolo >case MSR_IA32_VMX_BASIC: >/* > @@ -2356,9 +2356,6 @@ static int vmx_set_vmx_msr(struct kvm_vcpu *vcpu, > u32 msr_index, u64 data) >>> Also this function is no longer needed. You can drop it. >>> >>> And what about Nadav's patch Bandan pointed too? It is not entirely >>> correct, but it is close to real HW. >> I think Nadav's patch is much closer to the HW scenario. However, I >> think we don't need make things complex since KVM doen't support SMX >> now and this MSR is always set to 0x5. >> > Set to 0x5 by BIOS on real HW. This way BIOS can control if VMX is > exposed to an OS. I know. So if we don't use solutions like Nadav's patch, some third-party BIOSes emulator (if they are) may get error since we simply generate #GP(0) when write to this MSR. We can correct SIPI reset in Nadav's patch and add initial codes to seabios, then the entire logical can fit real HW. Arthur > >> Arthur >>> >if (!nested_vmx_allowed(vcpu)) >return 0; > > - if (msr_index == MSR_IA32_FEATURE_CONTROL) > - /* TODO: the right thing. */ > - return 1; >/* > * No need to treat VMX capability MSRs specially: If we don't handle > * them, handle_wrmsr will #GP(0), which is correct (they are readonly) > >>> >>> -- >>>Gleb. > > -- >Gleb. -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: IA32_FEATURE_CONTROL MSR in nested virt
OK, I will write a patch as what Paolo says. Anything else need to be taken into consideration, Paolo? Arthur Chunqi Li Department of Computer Science School of EECS Peking University Beijing, China >From my iPhone 在 2013-7-3,17:14,Gleb Natapov 写道: > On Wed, Jul 03, 2013 at 04:24:33PM +0800, Arthur Chunqi Li wrote: >> Hi Gleb and Paolo, >> When I write test cases for nested virt and found that reading/writing >> IA32_FEATURE_CONTROL will be simply ignored or return 0 (in >> arch/x86/kvm/vmx.c) in VM. Checking this MSR will be done by some >> hypervisors (e.g. NOVA) and may cause error then, so it is necessary >> to behave right when read/write it in VM. > NOVA cannot write to it and expect anything but #GP since BIOSes usually > lock the MSR. So I agree with Paolo about returning 5 on read and #GP on > write. Later we can implement locking functionality and make BIOS > enable/disable nested vmx. > >> Are there any difficulties to handle this MSR? I have two solutions. >> The first one is return the value of physical CPU's and always return >> true when write. This is simple but may behave as if it is a VM >> because write to it after VMXON will not return GP exception. This >> solution can solve most basic problems since this MSR is not commonly >> used. Another solution is adding a field in VCPU to handle this MSR. >> This is a complex but better method. >> >> I think I can complete this if needed. >> >> Thanks, >> Arthur >> >> -- >> Arthur Chunqi Li >> Department of Computer Science >> School of EECS >> Peking University >> Beijing, China > > -- >Gleb. -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] kvm-unit-tests: Add a func to run instruction in emulator
ok, I will handle all above in the following commit. Arthur Chunqi Li Department of Computer Science School of EECS Peking University Beijing, China >From my iPhone 在 2013-6-20,16:48,Gleb Natapov 写道: > On Wed, Jun 19, 2013 at 11:00:56PM +0800, Arthur Chunqi Li wrote: >> Add a function trap_emulator to run an instruction in emulator. >> Set inregs first (%rax is invalid because it is used as return >> address), put instruction codec in alt_insn and call func with >> alt_insn_length. Get results in outregs. >> >> Signed-off-by: Arthur Chunqi Li >> --- >> x86/emulator.c | 110 >> >> 1 file changed, 110 insertions(+) >> mode change 100644 => 100755 x86/emulator.c >> >> diff --git a/x86/emulator.c b/x86/emulator.c >> old mode 100644 >> new mode 100755 >> index 96576e5..48d45c8 >> --- a/x86/emulator.c >> +++ b/x86/emulator.c >> @@ -11,6 +11,15 @@ int fails, tests; >> >> static int exceptions; >> >> +struct regs { >> +u64 rax, rbx, rcx, rdx; >> +u64 rsi, rdi, rsp, rbp; >> +u64 r8, r9, r10, r11; >> +u64 r12, r13, r14, r15; >> +u64 rip, rflags; >> +}; >> +struct regs inregs, outregs, save; >> + >> void report(const char *name, int result) >> { >>++tests; >> @@ -685,6 +694,107 @@ static void test_shld_shrd(u32 *mem) >> report("shrd (cl)", *mem == ((0x12345678 >> 3) | (5u << 29))); >> } >> >> +#define INSN_SAVE\ > No need for all the defines. Put all the code into insn_page, allocate > alt_insn_page dynamically and copy the code there by memcpy. > >> +"ret\n\t"\ >> +"pushf\n\t"\ >> +"push 136+save \n\t"\ >> +"popf \n\t"\ >> +"xchg %rax, 0+save \n\t"\ >> +"xchg %rbx, 8+save \n\t"\ >> +"xchg %rcx, 16+save \n\t"\ >> +"xchg %rdx, 24+save \n\t"\ >> +"xchg %rsi, 32+save \n\t"\ >> +"xchg %rdi, 40+save \n\t"\ >> +"xchg %rsp, 48+save \n\t"\ >> +"xchg %rbp, 56+save \n\t"\ >> +"xchg %r8, 64+save \n\t"\ >> +"xchg %r9, 72+save \n\t"\ >> +"xchg %r10, 80+save \n\t"\ >> +"xchg %r11, 88+save \n\t"\ >> +"xchg %r12, 96+save \n\t"\ >> +"xchg %r13, 104+save \n\t"\ >> +"xchg %r14, 112+save \n\t"\ >> +"xchg %r15, 120+save \n\t"\ >> + >> +#define INSN_RESTORE\ >> +"xchg %rax, 0+save \n\t"\ >> +"xchg %rbx, 8+save \n\t"\ >> +"xchg %rcx, 16+save \n\t"\ >> +"xchg %rdx, 24+save \n\t"\ >> +"xchg %rsi, 32+save \n\t"\ >> +"xchg %rdi, 40+save \n\t"\ >> +"xchg %rsp, 48+save \n\t"\ >> +"xchg %rbp, 56+save \n\t"\ >> +"xchg %r8, 64+save \n\t"\ >> +"xchg %r9, 72+save \n\t"\ >> +"xchg %r10, 80+save \n\t"\ >> +"xchg %r11, 88+save \n\t"\ >> +"xchg %r12, 96+save \n\t"\ >> +"xchg %r13, 104+save \n\t"\ >> +"xchg %r14, 112+save \n\t"\ >> +"xchg %r15, 120+save \n\t"\ >> +"pushf \n\t"\ >> +"pop 136+save \n\t"\ >> +"popf \n\t"\ >> +"ret \n\t"\ >> + >> +#define INSN_TRAP\ >> +"in (%dx),%al\n\t"\ >> +". = . + 31\n\t"\ > If you will do ".skip 31, 0x90\n\t" instead you can drop loop > that inserts nops bellow. > >> + >> +asm( >> +".align 4096\n\t" >> +"insn_page:\n\t" >> +INSN_SAVE >> +"test_insn:\n\t" >> +INSN_TRAP >> +"test_insn_end:\n\t" >> +INSN_RESTORE >> +"insn_page_end:\n\t" >> +".align 4096\n\t" >> + >> +"alt_insn_page:\n\t" >> +INSN_SAVE >> +"alt_test_insn:\n\t" >> +INSN_TRAP >> +"alt_test_insn_end:\n\t" >> +INSN_RESTORE >> +"alt_insn_page_end:\n\t" >> +".align 4096\n\t" >> +); >> + >> +static void trap_emulator(uint64_t *mem, uint8_t* alt_insn, int >> alt_insn_length) >> +{ >> +ulong *cr3 = (ulong *)read_cr3(); >> +void *insn_ram; >> +int i; >> +extern u8 insn_page[], test_insn[], test_insn_end[]; >> +extern u8 alt_insn_page[], alt_test_insn[]; >> + >> +insn_ram = vmap(virt_to_phys(insn_page), 4096); >> +for (i=1; i> +alt_test_insn[i] = test_insn[i] = 0x90; // nop >> +for (i=0; i> +alt_test_insn[i] = alt_insn[i]; >> +for(;i> +alt_test_insn[i] = 0x90; // nop >> +save = inregs; >> + >> +// Load the code TLB with insn_page, but point the page tables at >> +// alt_insn_page (and keep the data TLB clear, for AMD decode assist). >> +// This will make the CPU trap on the insn_page instruction but the >> +// hypervisor will see alt_insn_page. > I prefer all the comments to be changed to /**/ style while we are at it. > >> +install_page(cr3, virt_to_phys(insn_page), insn_ram); >> +invlpg(insn_ram); >> +// Load code TLB >> +asm volatile("
Re: [PATCH 1/2] kvm-unit-tests: Add a func to run instruction in emulator
在 2013-6-20,0:03,Gleb Natapov 写道: > On Wed, Jun 19, 2013 at 11:07:18PM +0800, 李春奇 wrote: >> Hi Gleb, >> This version can set %rsp before trapping into emulator, because >> insn_page and alt_insn_page is statically defined and their relative >> position to (save) is fixed during execution. > The position of the code is not fixed during execution since you execute > it from a virtual address obtained dynamically by vmap() and the address > is definitely different from the one the code was compiled for, but if > you look at the code that compile actually produce you will see that it > uses absolute address to access "save" and this is why it works. I > wounder why compiler decided to use absolute address this time, Paolo? > >> In this way, test case of test_mmx_movq_mf needs to pre-define its own >> stack, this change is in the next patch. >> >> In this version, insn_ram is initially mapped to insn_page and them >> each call to insn_page/alt_insn_page are all via insn_ram. This trick >> runs well but I don't know why my previous version causes error. > Because previous version tried to use install_page() on a large page > mapped region and the function does not know how to handle that. I don't quite understand what you mean here. What is the differences between large page and 4k page in this test case? Maybe I don't understand the differences of install_pte() with 4k page and 2m pages. > >> Arthur. >> On Wed, Jun 19, 2013 at 11:00 PM, Arthur Chunqi Li wrote: >>> Add a function trap_emulator to run an instruction in emulator. >>> Set inregs first (%rax is invalid because it is used as return >>> address), put instruction codec in alt_insn and call func with >>> alt_insn_length. Get results in outregs. >>> >>> Signed-off-by: Arthur Chunqi Li >>> --- >>> x86/emulator.c | 110 >>> >>> 1 file changed, 110 insertions(+) >>> mode change 100644 => 100755 x86/emulator.c >>> >>> diff --git a/x86/emulator.c b/x86/emulator.c >>> old mode 100644 >>> new mode 100755 >>> index 96576e5..48d45c8 >>> --- a/x86/emulator.c >>> +++ b/x86/emulator.c >>> @@ -11,6 +11,15 @@ int fails, tests; >>> >>> static int exceptions; >>> >>> +struct regs { >>> + u64 rax, rbx, rcx, rdx; >>> + u64 rsi, rdi, rsp, rbp; >>> + u64 r8, r9, r10, r11; >>> + u64 r12, r13, r14, r15; >>> + u64 rip, rflags; >>> +}; >>> +struct regs inregs, outregs, save; >>> + >>> void report(const char *name, int result) >>> { >>> ++tests; >>> @@ -685,6 +694,107 @@ static void test_shld_shrd(u32 *mem) >>>report("shrd (cl)", *mem == ((0x12345678 >> 3) | (5u << 29))); >>> } >>> >>> +#define INSN_SAVE \ >>> + "ret\n\t" \ >>> + "pushf\n\t" \ >>> + "push 136+save \n\t"\ >>> + "popf \n\t" \ >>> + "xchg %rax, 0+save \n\t"\ >>> + "xchg %rbx, 8+save \n\t"\ >>> + "xchg %rcx, 16+save \n\t" \ >>> + "xchg %rdx, 24+save \n\t" \ >>> + "xchg %rsi, 32+save \n\t" \ >>> + "xchg %rdi, 40+save \n\t" \ >>> + "xchg %rsp, 48+save \n\t" \ >>> + "xchg %rbp, 56+save \n\t" \ >>> + "xchg %r8, 64+save \n\t"\ >>> + "xchg %r9, 72+save \n\t"\ >>> + "xchg %r10, 80+save \n\t" \ >>> + "xchg %r11, 88+save \n\t" \ >>> + "xchg %r12, 96+save \n\t" \ >>> + "xchg %r13, 104+save \n\t" \ >>> + "xchg %r14, 112+save \n\t" \ >>> + "xchg %r15, 120+save \n\t" \ >>> + >>> +#define INSN_RESTORE \ >>> + "xchg %rax, 0+save \n\t"\ >>> + "xchg %rbx, 8+save \n\t"\ >>> + "xchg %rcx, 16+save \n\t" \ >>> + "xchg %rdx, 24+save \n\t" \ >>> + "xchg %rsi, 32+save \n\t" \ >>> + "xchg %rdi, 40+save \n\t" \ >>> + "xchg %rsp, 48+save \n\t" \ >>> + "xchg %rbp, 56+save \n\t" \ >>> + "xchg %r8, 64+save \n\t"\ >>> + "xchg %r9, 72+save \n\t"\ >>> + "xchg %r10, 80+save \n\t" \ >>> + "xchg %r11, 88+save \n\t" \ >>> + "xchg %r12, 96+save \n\t" \ >>> + "xchg %r13, 104+save \n\t" \ >>> + "xchg %r14, 112+save \n\t" \ >>> + "xchg %r15, 120+save \n\t" \ >>> + "pushf \n\t"\ >>> + "pop 136+save \n\t" \ >>> + "popf \n\t" \ >>> + "ret \n\t" \ >>> + >>> +#define INSN_TRAP \ >>> + "in (%dx),%al\n\t" \ >>> + ".