aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/x86_emulate
Commit message (Collapse)AuthorAgeFilesLines
* x86: properly set up fbld emulation operand addressJan Beulich2013-09-301-2/+2
| | | | | | | This is CVE-2013-4361 / XSA-66. Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
* x86_emulate: fix wrap around handling for repeated string instructionsJan Beulich2013-09-231-8/+16
| | | | | | | | | | | | | | | | | | | | | | | | | For one, repeat count clipping for MOVS must be done taking into consideration both source and destination addresses. And then we should allow a wrap on the final iteration only if either the wrap is a precise one (i.e. the access itself doesn't wrap, just the resulting index register value would) or if there is just one iteration. In all other cases we should do a bulk operation first without hitting the wrap, and then issue an individual iteration. If we don't do it that way, - the last iteration not completing successfully will cause the whole operation to fail (i.e. registers not get updated to the failure point) - hvmemul_virtual_to_linear() may needlessly enforce non-repeated operation Additionally with the prior implementation there was a case (df=1, ea=~0, reps=~0, bytes_per_rep=1) where we'd end up passing zero reps back to the caller, yet various places assume that there's at least on iteration. Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Keir Fraser <keir@xen.org>
* x86_emulate: fold wide readsJan Beulich2013-09-201-13/+5
| | | | | | | | | | | | | With HVM's MMIO operand handling now being capable of splitting large reads, there's no need to issue at most machine word size reads when we really need wider operands. Not that this is not done everywhere - there are a couple of cases where keeping the reads separate is more natural (and folding them would complicate the code rather than simplifying it). Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Keir Fraser <keir@xen.org>
* x86_emulate: fix flag setting for 8-bit signed multiplicationJan Beulich2013-09-201-39/+17
| | | | | | | | | | | | | | | We really need to check for a signed overflow of 8 bits, while the previous check compared the sign-extended 8-bit result with the zero-extended 16-bit one (which was wrong for all negative results). Once at it - also adjust the 16-bit comparison for symmetry - improve the 8-bit multiplication (no need to zero-extend to 32-bits the sign-extended to 16 bits original 8-bit value) - fold both signed multiplication variants Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Keir Fraser <keir@xen.org>
* x86_emulate: PUSH <mem> must read source operand just onceJan Beulich2013-09-201-46/+48
| | | | | | | | | | | ... for the case of accessing MMIO. Rather than doing the early operand type adjustment for just for that case, do it for all of the 0xF6, 0xF7, and 0xFF groups (allowing some other code to be dropped instead). Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Keir Fraser <keir@xen.org>
* x86_emulate: MOVSXD must read source operand just onceJan Beulich2013-09-201-10/+21
| | | | | | | | | | | | ... for the case of accessing MMIO. Also streamline the ARPL emulation a little, and add tests for both instructions (the MOVSXD one requires a few other adjustments, as we now need to run in a mode where the emulator's mode_64bit() returns true). Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Keir Fraser <keir@xen.org>
* x86: AVX instruction emulation fixesJan Beulich2013-08-281-9/+7
| | | | | | | | | | | | | | | | | | | - we used the C4/C5 (first prefix) byte instead of the apparent ModR/M one as the second prefix byte - early decoding normalized vex.reg, thus corrupting it for the main consumer (copy_REX_VEX()), resulting in #UD on the two-operand instructions we emulate Also add respective test cases to the testing utility plus - fix get_fpu() (the fall-through order was inverted) - add cpu_has_avx2, even if it's currently unused (as in the new test cases I decided to refrain from using AVX2 instructions in order to be able to actually run all the tests on the hardware I have) - slightly tweak cpu_has_avx to more consistently express the outputs we don't care about (sinking them all into the same variable) Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Keir Fraser <keir@xen.org>
* x86/emul: only emulate possibly operand sizes for POPAJan Beulich2012-11-081-7/+4
| | | | | | | | | This opcode neither supports 1-byte operands, nor does it support 8-byte ones (since the opcode is undefined in 64-bit mode). Simplify the code accordingly. Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Keir Fraser <keir@xen.org>
* x86: save/restore only partial register state where possibleJan Beulich2012-10-301-4/+4
| | | | | | | | | | | | | | | | | | | | | | | | ... and make restore conditional not only upon having saved the state, but also upon whether saved state was actually modified (and register values are known to have been preserved). Note that RBP is unconditionally considered a volatile register (i.e. irrespective of CONFIG_FRAME_POINTER), since the RBP handling would become overly complicated due to the need to save/restore it on the compat mode hypercall path [6th argument]. Note further that for compat mode code paths, saving/restoring R8...R15 is entirely unnecessary - we don't allow those guests to enter 64-bit mode, and hence they have no way of seeing these registers' contents (and there consequently also is no information leak, except if the context saving domctl would be considered such). Finally, note that this may not properly deal with gdbstub's needs, yet (but if so, I can't really suggest adjustments, as I don't know that code). Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Keir Fraser <keir@xen.org>
* x86_emulate: Do not push an error code onto a #UD exception stackKeir Fraser2012-03-231-7/+7
| | | | Signed-off-by: Keir Fraser <keir@xen.org>
* x86_emulate: raise #UD rather than #GP on invalid use of LOCK prefixAndrew Cooper2012-03-231-4/+4
| | | | | | From: Andrew Cooper <andrew.cooper3@citrix.com> Signed-off-by: Keir Fraser <keir@xen.org> Committed-by: Keir Fraser <keir@xen.org>
* x86: emulate lea with two register operands correctlyDavid Vrabel2012-01-051-0/+1
| | | | | | | | | | | | An lea instruction with two register operands should raise an undefined instruction exception. Skype does such a instruction and will crash when starting if it does not get the exception. Signed-off-by: David Vrabel <david.vrabel@citrix.com> Signed-off-by: Keir Fraser <keir@xen.org> Committed-by: Keir Fraser <keir@xen.org>
* x86/emulator: workaround for AMD erratum 573Jan Beulich2011-12-161-1/+3
| | | | | | | | | | | | | | | | | The only cases where we might end up emulating fsincos (as any other x87 operations without memory operands) are - when a HVM guest is in real mode (not applicable on AMD) - between two half page table updates in PAE mode (unlikely, and not doing the emulation here does affect only performance, not correctness) - when a guest maliciously (or erroneously) modifies an (MMIO or page table update) instruction under emulation (unspecified behavior) Hence, in order to avoid the erratum to cause harm to the entire host, don't emulate fsincos on the affected AMD CPU families. Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Keir Fraser <keir@xen.org>
* x86/emulator: cleanupJan Beulich2011-12-011-16/+17
| | | | | | | | | | Utilize some of the additions in the prior patches to clean up other code: - keep track of REP prefixes in only one variable - use REX_W in a few more places (instead of a literal number) Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Keir Fraser <keir@xen.org>
* x86/emulator: properly handle lzcnt and tzcntJan Beulich2011-12-011-8/+37
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | These instructions are prefix selected flavors of bsf and bsr respectively, and hence the presences of the F3 prefix must be handled in the emulation code in order to avoid running into problems on newer CPUs. Signed-off-by: Jan Beulich <jbeulich@suse.com> --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -1058,6 +1058,9 @@ static bool_t vcpu_has( return rc == X86EMUL_OKAY; } +#define vcpu_has_lzcnt() vcpu_has(0x80000001, ECX, 5, ctxt, ops) +#define vcpu_has_bmi1() vcpu_has(0x00000007, EBX, 3, ctxt, ops) + #define vcpu_must_have(leaf, reg, bit) \ generate_exception_if(!vcpu_has(leaf, reg, bit, ctxt, ops), EXC_UD, -1) #define vcpu_must_have_mmx() vcpu_must_have(0x00000001, EDX, 23) @@ -4357,13 +4360,24 @@ x86_emulate( dst.val = (uint8_t)src.val; break; - case 0xbc: /* bsf */ { - int zf; + case 0xbc: /* bsf or tzcnt */ { + bool_t zf; asm ( "bsf %2,%0; setz %b1" : "=r" (dst.val), "=q" (zf) - : "r" (src.val), "1" (0) ); + : "r" (src.val) ); _regs.eflags &= ~EFLG_ZF; - if ( zf ) + if ( (rep_prefix == REPE_PREFIX) && vcpu_has_bmi1() ) + { + _regs.eflags &= ~EFLG_CF; + if ( zf ) + { + _regs.eflags |= EFLG_CF; + dst.val = op_bytes * 8; + } + else if ( !dst.val ) + _regs.eflags |= EFLG_ZF; + } + else if ( zf ) { _regs.eflags |= EFLG_ZF; dst.type = OP_NONE; @@ -4371,13 +4385,28 @@ x86_emulate( break; } - case 0xbd: /* bsr */ { - int zf; + case 0xbd: /* bsr or lzcnt */ { + bool_t zf; asm ( "bsr %2,%0; setz %b1" : "=r" (dst.val), "=q" (zf) - : "r" (src.val), "1" (0) ); + : "r" (src.val) ); _regs.eflags &= ~EFLG_ZF; - if ( zf ) + if ( (rep_prefix == REPE_PREFIX) && vcpu_has_lzcnt() ) + { + _regs.eflags &= ~EFLG_CF; + if ( zf ) + { + _regs.eflags |= EFLG_CF; + dst.val = op_bytes * 8; + } + else + { + dst.val = op_bytes * 8 - 1 - dst.val; + if ( !dst.val ) + _regs.eflags |= EFLG_ZF; + } + } + else if ( zf ) { _regs.eflags |= EFLG_ZF; dst.type = OP_NONE;
* x86/emulator: add emulation of SIMD FP movesJan Beulich2011-12-011-2/+82
| | | | | | | | | | Clone the existing movq emulation to also support the most fundamental SIMD FP moves. Extend the testing code to also exercise these instructions. Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Keir Fraser <keir@xen.org>
* x86/emulator: generalize movq emulation (SSE2 and AVX variants)Jan Beulich2011-12-012-35/+200
| | | | | | | | | | | | Extend the existing movq emulation to also support its SSE2 and AVX variants, the latter implying the addition of VEX decoding. Fold the read and write cases (as most of the logic is identical), and add movntq and variants (as they're very similar). Extend the testing code to also exercise these instructions. Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Keir Fraser <keir@xen.org>
* x86/emulator: add feature checks for newer instructionsJan Beulich2011-11-161-0/+47
| | | | | | | | | | | Certain instructions were introduced only after the i686 or original x86-64 architecture, so we should not try to emulate them if the guest is not seeing the respective feature enabled (or, worse, if the underlying hardware doesn't support them). This affects fisttp, movnti, and cmpxchg16b. Signed-off-by: Jan Beulich <jbeulich@suse.com> Signed-off-by: Keir Fraser <keir@xen.org>
* x86_emulate: Define and use BUG() and bool_t.Keir Fraser2011-11-161-12/+12
| | | | | Original patch by Jan Beulich <jbeulich@suse.com> Signed-off-by: Keir Fraser <keir@xen.org>
* x86_emulate: Fix decode of FUCOMIP %stN.Keir Fraser2011-06-151-1/+1
| | | | Signed-off-by: Keir Fraser <keir@xen.org>
* x86_emulate: FPU 0xda instructions have a 32-bit memory operand, not 64-bit.Keir Fraser2011-03-081-9/+9
| | | | Signed-off-by: Keir Fraser <keir@xen.org>
* x86_emulate: Fix emulation of FIMUL m32i.Keir Fraser2011-03-081-1/+1
| | | | | | Need to emit assembler instruction fimull not fimul/fimuls. Signed-off-by: Keir Fraser <keir@xen.org>
* x86: add explicit size suffixes to some assembly instructions.Tim Deegan2011-03-071-13/+13
| | | | | | | This is needed to compile xen with clang. Signed-off-by: Tim Deegan <Tim.Deegan@citrix.com> Acked-by: Keir Fraser <keir@xen.org>
* x86_emulate: set the operand size for SMSW/reg writeback.Keir Fraser2011-01-191-2/+1
| | | | | | | Otherwise it defaults to 0 bytes. Signed-off-by: Tim Deegan <Tim.Deegan@citrix.com> Signed-off-by: Keir Fraser <keir@xen.org>
* x86_emulate: Fix build with some versions of gcc targeting i386.Keir Fraser2010-10-311-0/+2
| | | | Signed-off-by: Keir Fraser <keir@xen.org>
* Xen: fix various checks of unsigned integers < 0Keir Fraser2010-10-291-1/+1
| | | | | | | Some of these could be benignly discarded by the compiler but some are actual bugs. Signed-off-by: Tim Deegan <Tim.Deegan@citrix.com>
* x86_emulate: Emulate CLFLUSH instructionKeir Fraser2010-04-151-1/+15
| | | | | | | | | | | | | | We recently found that FreeBSD 8.0 guest failed to install and boot on Xen. The reason was that FreeBSD detected clflush feature and invoked this instruction to flush MMIO space. This caused a page fault; but x86_emulate.c failed to emulate this instruction (not supported). As a result, a page fault was detected inside FreeBSD. A similar issue was reported earlier. http://lists.xensource.com/archives/html/xen-devel/2010-03/msg00362.html From: Wei Huang <wei.huang2@amd.com> Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
* x86_emulate: Emulate RDTSCP instruction.Keir Fraser2009-12-161-1/+12
| | | | Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
* Miscellaneous data placement adjustmentsKeir Fraser2009-10-282-12/+12
| | | | | | | Make various data items const or __read_mostly where possible/reasonable. Signed-off-by: Jan Beulich <jbeulich@novell.com>
* Cleanup: Make local functions static and remove unused functions.Keir Fraser2009-09-301-3/+2
| | | | Signed-off-by: Christoph Egger <Christoph.Egger@amd.com>
* x86_emulate: honor failure of in_longmode()Keir Fraser2009-08-311-2/+8
| | | | | | | Failure of in_longmode() shouldn't be treated the same as the function returning 'true'. Signed-off-by: Jan Beulich <jbeulich@novell.com>
* x86: miscellaneous emulator adjustmentsKeir Fraser2009-08-191-49/+39
| | | | | | | | | | | | | | | | | | Defer fail_if()-s as much as possible (in favor of possibly generating exceptions), and avoid generating exceptions when not strictly necessary. Avoid fail_if()-s for simple return code checks (making the code that used them consistent with other, longer existing code). Eliminate redundant generate_exception_if()-s checking lock_prefix (which is already covered by the general check prior to decoding operands). Also fix the testing code to add PROT_EXEC for the mapping that is intended to have instruction executed from. Signed-off-by: Jan Beulich <jbeulich@novell.com>
* x86-64: adjust emulation of control transfersKeir Fraser2009-08-191-11/+14
| | | | | | | | | | | | | | | | | | | | | | While Intel and AMD implementations differ in various respects when it comes to non-default operand sizes of control transfer instructions and segment register loads (lfs, lgs, lss), it seems to make senss to (a) match their behavior if they agree and (b) prefer the more permissive behavior if they don't agree: - honor operand size overrides on near brances (AMD does, Intel doesn't) - honor operand size overrides on far branches (both Intel and AMD do) - honor REX.W on far branches (Intel does, AMD doesn't except on far returns) - honor REX.W on lfs, lgs, and lss (Intel does, AMD doesn't) Also, do not permit emulation of pushing/popping segment registers other than fs and gs as well as that of les and lds (the latter are particularly important due to the re-use of the respective opcodes as VEX prefixes in AVX). Signed-off-by: Jan Beulich <jbeulich@novell.com>
* x86_emulate: Fixes for 'mov rm16,sreg'Keir Fraser2009-08-071-1/+2
| | | | | | | 1. Memory reads should be 16 bits only 2. Attempt to load %cs should result in #UD Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
* x86_emulate: protmode_load_seg() cannot load system segments in long mode.Keir Fraser2009-08-071-2/+11
| | | | Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
* x86_emulate: Remove cmpxchg retry loop from protmode_load_seg().Keir Fraser2009-08-061-68/+64
| | | | | | It is safer to retry in a loop via the caller. Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
* x86: Fix 32-bit build.Keir Fraser2009-05-271-5/+7
| | | | Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
* x86 hvm: Allow cross-vendor migrationKeir Fraser2009-05-261-3/+209
| | | | | | | Intercept #UD and emulate SYSCALL/SYSENTER/SYSEXIT as necessary. Signed-off-by: Christoph Egger <Christoph.Egger@amd.com> Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
* x86_emulate: Emulate LLDT and LTR instructions.Keir Fraser2009-05-191-10/+25
| | | | Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
* Use virtual 8086 mode for VMX guests with CR0.PE == 0Keir Fraser2008-12-091-0/+1
| | | | | | | | | | | | | When a VMX guest tries to enter real mode, put it in virtual 8086 mode instead, if that's possible. Handle all errors and corner cases by falling back to the real-mode emulator. This is similar to the old VMXASSIST system except it uses Xen's x86_emulate emulator instead of having a partial emulator in the guest firmware. It more than doubles the speed of real-mode operation on VMX. Signed-off-by: Tim Deegan <Tim.Deegan@citrix.com>
* x86_emulate: Fix for test harness and simplify some opcodes.Keir Fraser2008-11-271-49/+24
| | | | | | | | - Need to use EFLG_DF rather than EF_DF - No need to force EAX destination for many opcodes, as this will be the default behaviour for DstReg with no ModRM. Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
* x86: add movnti emulationKeir Fraser2008-10-201-1/+8
| | | | | | | | Linux added the use of movnti for copying from user to kernel space in certain cases, and as per reports we got this may happen with the destination being in MMIO. Signed-off-by: Jan Beulich <jbeulich@novell.com>
* x86_emulate: Fix after decode changes. Valid opcode decode values mustKeir Fraser2008-10-141-7/+8
| | | | | | be non-zero. Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
* x86, hvm: Hyper-V guest interface support with small set of enlightenmentsKeir Fraser2008-10-141-765/+752
| | | | | | | | | | | | | A minimal implementation of the Viridian (Hyper-V) guest interface. The only enlightenments advertised and supported are vAPIC MSRs and long-spin-wait notifications. The set of enlightenments can easily be extended in future, as they are found to provide a performance win, and configured via an extended HVM_PARAM_VIRIDIAN hvm parameter. Signed-off-by: Peter Johnston <peter.johnston@citrix.com> Signed-off-by: Tim Deegan <tim.deegan@citrix.com> Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
* x86_emulate: Do not request emulation of REP instructions beyond theKeir Fraser2008-08-191-4/+13
| | | | | | | | point at which the index register (SI/DI) wraps. This can cause a discontinuity in the address range accessed by the repeated instruction. Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
* x86_emulate: fix unintended writeback on cmp/test instructionsKeir Fraser2008-07-251-0/+2
| | | | | | | | | | | This patch fixes an issue when x86_emulate is called with force_writeback=1 set. It resulted in cmp and test instructions with memory operands to have the mem value written back after instruction emulation finished. This caused false alarms on writes to RO mem, and might have caused other issues if unintended writes occured to device registers in mmio space. Signed-off-by: Trolle Selander <trolle.selander@eu.citrix.com>
* x86_emulate: (Almost) complete FPU emulation.Keir Fraser2008-07-011-36/+458
| | | | | | | | | | | | | Provide emulation for all FPU instructions except fsave/frstore & fnstenv/fldenv. While the main purpose of the patch is to avoid current and future "gotchas" on FPU intructions used by various OS boot-loaders, it is complete enough to run DOS realmode FPU applications and benchmarks, but don't expect to set any speed records. Signed-off-by: Trolle Selander <trolle.selander@eu.citrix.com> Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
* x86_emulate: read/write/insn_fetch emulation hooks now all take aKeir Fraser2008-06-302-101/+127
| | | | | | | pointer to emulator data buffer, and an arbitrary byte count (up to the size of a page of memory). Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
* x86: Emulation of LMSW must only affect CR0 bits 0-3.Keir Fraser2008-06-271-3/+4
| | | | | | | Emulation of SMSW is only restricted to 16-bit operation on memory operands. Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
* hvm: Fix lmsw handlingKeir Fraser2008-06-271-1/+1
| | | | | | | The lmsw instruction can be used to set CR0_PE, but can never clear it, once set. Signed-off-by: Trolle Selander <trolle.selander@eu.citrix.com>