summaryrefslogtreecommitdiff
path: root/system/xen/xsa/xsa190.patch
diff options
context:
space:
mode:
Diffstat (limited to 'system/xen/xsa/xsa190.patch')
-rw-r--r--system/xen/xsa/xsa190.patch173
1 files changed, 0 insertions, 173 deletions
diff --git a/system/xen/xsa/xsa190.patch b/system/xen/xsa/xsa190.patch
deleted file mode 100644
index 3c242e6cc2..0000000000
--- a/system/xen/xsa/xsa190.patch
+++ /dev/null
@@ -1,173 +0,0 @@
-x86emul: honor guest CR0.TS and CR0.EM
-
-We must not emulate any instructions accessing respective registers
-when either of these flags is set in the guest view of the register, or
-else we may do so on data not belonging to the guest's current task.
-
-Being architecturally required behavior, the logic gets placed in the
-instruction emulator instead of hvmemul_get_fpu(). It should be noted,
-though, that hvmemul_get_fpu() being the only current handler for the
-get_fpu() callback, we don't have an active problem with CR4: Both
-CR4.OSFXSR and CR4.OSXSAVE get handled as necessary by that function.
-
-This is XSA-190.
-
-Signed-off-by: Jan Beulich <jbeulich@suse.com>
-Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
----
-v4: Only raise #NM on FWAIT when CR0.TS and CR0.MP are set.
-v3: Correct which exception to raise upon set CR0.EM.
-v2: Require the read_cr hook to be set, which then requires a change to
- the test code too.
----
-The change to xen/arch/x86/hvm/emulate.c isn't strictly needed for
-fixing the security issue, but the patch would be rather incomplete
-without.
-
---- a/tools/tests/x86_emulator/test_x86_emulator.c
-+++ b/tools/tests/x86_emulator/test_x86_emulator.c
-@@ -158,6 +158,22 @@ static inline uint64_t xgetbv(uint32_t x
- (ebx & (1U << 5)) != 0; \
- })
-
-+static int read_cr(
-+ unsigned int reg,
-+ unsigned long *val,
-+ struct x86_emulate_ctxt *ctxt)
-+{
-+ /* Fake just enough state for the emulator's _get_fpu() to be happy. */
-+ switch ( reg )
-+ {
-+ case 0:
-+ *val = 0x00000001; /* PE */
-+ return X86EMUL_OKAY;
-+ }
-+
-+ return X86EMUL_UNHANDLEABLE;
-+}
-+
- int get_fpu(
- void (*exception_callback)(void *, struct cpu_user_regs *),
- void *exception_callback_arg,
-@@ -189,6 +205,7 @@ static struct x86_emulate_ops emulops =
- .write = write,
- .cmpxchg = cmpxchg,
- .cpuid = cpuid,
-+ .read_cr = read_cr,
- .get_fpu = get_fpu,
- };
-
---- a/xen/arch/x86/hvm/emulate.c
-+++ b/xen/arch/x86/hvm/emulate.c
-@@ -1628,14 +1628,14 @@ static int hvmemul_get_fpu(
- switch ( type )
- {
- case X86EMUL_FPU_fpu:
-+ case X86EMUL_FPU_wait:
- break;
- case X86EMUL_FPU_mmx:
- if ( !cpu_has_mmx )
- return X86EMUL_UNHANDLEABLE;
- break;
- case X86EMUL_FPU_xmm:
-- if ( (curr->arch.hvm_vcpu.guest_cr[0] & X86_CR0_EM) ||
-- !(curr->arch.hvm_vcpu.guest_cr[4] & X86_CR4_OSFXSR) )
-+ if ( !(curr->arch.hvm_vcpu.guest_cr[4] & X86_CR4_OSFXSR) )
- return X86EMUL_UNHANDLEABLE;
- break;
- case X86EMUL_FPU_ymm:
---- a/xen/arch/x86/x86_emulate/x86_emulate.c
-+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
-@@ -420,6 +420,9 @@ typedef union {
-
- /* Control register flags. */
- #define CR0_PE (1<<0)
-+#define CR0_MP (1<<1)
-+#define CR0_EM (1<<2)
-+#define CR0_TS (1<<3)
- #define CR4_TSD (1<<2)
-
- /* EFLAGS bit definitions. */
-@@ -447,6 +450,7 @@ typedef union {
- #define EXC_OF 4
- #define EXC_BR 5
- #define EXC_UD 6
-+#define EXC_NM 7
- #define EXC_TS 10
- #define EXC_NP 11
- #define EXC_SS 12
-@@ -746,10 +750,45 @@ static void fpu_handle_exception(void *_
- regs->eip += fic->insn_bytes;
- }
-
-+static int _get_fpu(
-+ enum x86_emulate_fpu_type type,
-+ struct fpu_insn_ctxt *fic,
-+ struct x86_emulate_ctxt *ctxt,
-+ const struct x86_emulate_ops *ops)
-+{
-+ int rc;
-+
-+ fic->exn_raised = 0;
-+
-+ fail_if(!ops->get_fpu);
-+ rc = ops->get_fpu(fpu_handle_exception, fic, type, ctxt);
-+
-+ if ( rc == X86EMUL_OKAY )
-+ {
-+ unsigned long cr0;
-+
-+ fail_if(!ops->read_cr);
-+ rc = ops->read_cr(0, &cr0, ctxt);
-+ if ( rc != X86EMUL_OKAY )
-+ return rc;
-+ if ( cr0 & CR0_EM )
-+ {
-+ generate_exception_if(type == X86EMUL_FPU_fpu, EXC_NM, -1);
-+ generate_exception_if(type == X86EMUL_FPU_mmx, EXC_UD, -1);
-+ generate_exception_if(type == X86EMUL_FPU_xmm, EXC_UD, -1);
-+ }
-+ generate_exception_if((cr0 & CR0_TS) &&
-+ (type != X86EMUL_FPU_wait || (cr0 & CR0_MP)),
-+ EXC_NM, -1);
-+ }
-+
-+ done:
-+ return rc;
-+}
-+
- #define get_fpu(_type, _fic) \
--do{ (_fic)->exn_raised = 0; \
-- fail_if(ops->get_fpu == NULL); \
-- rc = ops->get_fpu(fpu_handle_exception, _fic, _type, ctxt); \
-+do { \
-+ rc = _get_fpu(_type, _fic, ctxt, ops); \
- if ( rc ) goto done; \
- } while (0)
- #define _put_fpu() \
-@@ -2879,8 +2918,14 @@ x86_emulate(
- }
-
- case 0x9b: /* wait/fwait */
-- emulate_fpu_insn("fwait");
-+ {
-+ struct fpu_insn_ctxt fic = { .insn_bytes = 1 };
-+
-+ get_fpu(X86EMUL_FPU_wait, &fic);
-+ asm volatile ( "fwait" ::: "memory" );
-+ put_fpu(&fic);
- break;
-+ }
-
- case 0x9c: /* pushf */
- src.val = _regs.eflags;
---- a/xen/arch/x86/x86_emulate/x86_emulate.h
-+++ b/xen/arch/x86/x86_emulate/x86_emulate.h
-@@ -115,6 +115,7 @@ struct __packed segment_register {
- /* FPU sub-types which may be requested via ->get_fpu(). */
- enum x86_emulate_fpu_type {
- X86EMUL_FPU_fpu, /* Standard FPU coprocessor instruction set */
-+ X86EMUL_FPU_wait, /* WAIT/FWAIT instruction */
- X86EMUL_FPU_mmx, /* MMX instruction set (%mm0-%mm7) */
- X86EMUL_FPU_xmm, /* SSE instruction set (%xmm0-%xmm7/15) */
- X86EMUL_FPU_ymm /* AVX/XOP instruction set (%ymm0-%ymm7/15) */