[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Ping: [PATCH v2] x86emul: de-duplicate scatters to the same linear address
On 20.05.2021 15:34, Jan Beulich wrote: > The SDM specifically allows for earlier writes to fully overlapping > ranges to be dropped. If a guest did so, hvmemul_phys_mmio_access() > would crash it if varying data was written to the same address. Detect > overlaps early, as doing so in hvmemul_{linear,phys}_mmio_access() would > be quite a bit more difficult. To maintain proper faulting behavior, > instead of dropping earlier write instances of fully overlapping slots > altogether, write the data of the final of these slots multiple times. > (We also can't pull ahead the [single] write of the data of the last of > the slots, clearing all involved slots' op_mask bits together, as this > would yield incorrect results if there were intervening partially > overlapping ones.) > > Note that due to cache slot use being linear address based, there's no > similar issue with multiple writes to the same physical address (mapped > through different linear addresses). > > Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> As indicated before, this is an issue which - afaict - would be a security issue if introspection was security supported. As such I find it highly irritating that this has now been pending for well over half a year (counting from the submission of v1). Jan > --- > v2: Maintain correct faulting behavior. > > --- a/xen/arch/x86/x86_emulate/x86_emulate.c > +++ b/xen/arch/x86/x86_emulate/x86_emulate.c > @@ -10073,15 +10073,36 @@ x86_emulate( > > for ( i = 0; op_mask; ++i ) > { > - long idx = b & 1 ? index.qw[i] : index.dw[i]; > + long idx = (b & 1 ? index.qw[i] > + : index.dw[i]) * (1 << state->sib_scale); > + unsigned long offs = truncate_ea(ea.mem.off + idx); > + unsigned int j, slot; > > if ( !(op_mask & (1 << i)) ) > continue; > > - rc = ops->write(ea.mem.seg, > - truncate_ea(ea.mem.off + > - idx * (1 << state->sib_scale)), > - (void *)mmvalp + i * op_bytes, op_bytes, ctxt); > + /* > + * hvmemul_linear_mmio_access() will find a cache slot based on > + * linear address. hvmemul_phys_mmio_access() will crash the > + * domain if observing varying data getting written to the same > + * cache slot. Utilize that squashing earlier writes to fully > + * overlapping addresses is permitted by the spec. We can't, > + * however, drop the writes altogether, to maintain correct > + * faulting behavior. Instead write the data from the last of > + * the fully overlapping slots multiple times. > + */ > + for ( j = (slot = i) + 1; j < n; ++j ) > + { > + long idx2 = (b & 1 ? index.qw[j] > + : index.dw[j]) * (1 << state->sib_scale); > + > + if ( (op_mask & (1 << j)) && > + truncate_ea(ea.mem.off + idx2) == offs ) > + slot = j; > + } > + > + rc = ops->write(ea.mem.seg, offs, > + (void *)mmvalp + slot * op_bytes, op_bytes, > ctxt); > if ( rc != X86EMUL_OKAY ) > { > /* See comment in gather emulation. */ >
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |