[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] x86/HVM: fix hvmemul_rep_outs_set_context()
commit 378d31ab3e007d7a059b3e26d4062d7ac318eef4 Author: Jan Beulich <jbeulich@xxxxxxxx> AuthorDate: Fri Dec 15 11:11:36 2017 +0100 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Fri Dec 15 11:11:36 2017 +0100 x86/HVM: fix hvmemul_rep_outs_set_context() There were two issues with this function: Its use of hvmemul_do_pio_buffer() was wrong (the function deals only with individual port accesses, not repeated ones, i.e. passing it "*reps * bytes_per_rep" does not have the intended effect). And it could have processed a larger set of operations in one go than was probably intended (limited just by the size that xmalloc() can hand back). By converting to proper use of hvmemul_do_pio_buffer(), no intermediate buffer is needed at all. As a result a preemption check is being added. Also drop unused parameters from the function. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> Reviewed-by: Razvan Cojocaru <rcojocaru@xxxxxxxxxxxxxxx> Reviewed-by: Paul Durrant <paul.durrant@xxxxxxxxxx> --- xen/arch/x86/hvm/emulate.c | 44 ++++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/xen/arch/x86/hvm/emulate.c b/xen/arch/x86/hvm/emulate.c index c9fae88..3b82455 100644 --- a/xen/arch/x86/hvm/emulate.c +++ b/xen/arch/x86/hvm/emulate.c @@ -1349,28 +1349,41 @@ static int hvmemul_rep_ins( } static int hvmemul_rep_outs_set_context( - enum x86_segment src_seg, - unsigned long src_offset, uint16_t dst_port, unsigned int bytes_per_rep, - unsigned long *reps, - struct x86_emulate_ctxt *ctxt) + unsigned long *reps) { - unsigned int bytes = *reps * bytes_per_rep; - char *buf; - int rc; - - buf = xmalloc_array(char, bytes); + const struct arch_vm_event *ev = current->arch.vm_event; + const uint8_t *ptr; + unsigned int avail; + unsigned long done; + int rc = X86EMUL_OKAY; - if ( buf == NULL ) + ASSERT(bytes_per_rep <= 4); + if ( !ev ) return X86EMUL_UNHANDLEABLE; - rc = set_context_data(buf, bytes); + ptr = ev->emul.read.data; + avail = ev->emul.read.size; - if ( rc == X86EMUL_OKAY ) - rc = hvmemul_do_pio_buffer(dst_port, bytes, IOREQ_WRITE, buf); + for ( done = 0; done < *reps; ++done ) + { + unsigned int size = min(bytes_per_rep, avail); + uint32_t data = 0; - xfree(buf); + if ( done && hypercall_preempt_check() ) + break; + + memcpy(&data, ptr, size); + avail -= size; + ptr += size; + + rc = hvmemul_do_pio_buffer(dst_port, bytes_per_rep, IOREQ_WRITE, &data); + if ( rc != X86EMUL_OKAY ) + break; + } + + *reps = done; return rc; } @@ -1392,8 +1405,7 @@ static int hvmemul_rep_outs( int rc; if ( unlikely(hvmemul_ctxt->set_context) ) - return hvmemul_rep_outs_set_context(src_seg, src_offset, dst_port, - bytes_per_rep, reps, ctxt); + return hvmemul_rep_outs_set_context(dst_port, bytes_per_rep, reps); rc = hvmemul_virtual_to_linear( src_seg, src_offset, bytes_per_rep, reps, hvm_access_read, -- generated by git-patchbot for /home/xen/git/xen.git#master _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |