[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 4 of 5] tools/ocaml: libxc bindings: Fix stub_xc_readconsolering()
There are two problems with this function: * The caml_{enter,leave}_blocking_section() calls mean that two threads can compete for use of the static ring[] buffer. * It fails to retrieve the entire buffer if the hypervisor has used 32K or more of its console ring. Rewrite the function using the new xc_consoleringsize() and xc_readconsolering_buffer() functions to efficiently grab the entire console ring. Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> diff -r 6b8c513cff4f -r a73d0c5a5b24 tools/ocaml/libs/xc/xenctrl_stubs.c --- a/tools/ocaml/libs/xc/xenctrl_stubs.c +++ b/tools/ocaml/libs/xc/xenctrl_stubs.c @@ -523,27 +523,61 @@ CAMLprim value stub_xc_evtchn_reset(valu CAMLreturn(Val_unit); } - -#define RING_SIZE 32768 -static char ring[RING_SIZE]; - +/* Maximum size of console ring we are prepared to read, 16MB */ +#define MAX_CONSOLE_RING_SIZE (1U << 24) CAMLprim value stub_xc_readconsolering(value xch) { - unsigned int size = RING_SIZE - 1; - char *ring_ptr = ring; - int retval; + uint64_t conring_size; + DECLARE_HYPERCALL_BUFFER(char, ring); + unsigned int nr_chars; + int r; CAMLparam1(xch); + CAMLlocal1(conring); + + r = xc_consoleringsize(_H(xch), &conring_size); + + if ( r ) + { + failwith_xc(_H(xch)); + CAMLreturn(Val_unit); + } + + /* Round conring_size up to the next page, for NULL terminator and + slop from a race with printk() in the hypervisor. */ + conring_size = (conring_size + XC_PAGE_SIZE) & XC_PAGE_MASK; + nr_chars = conring_size-1; + + if ( conring_size > MAX_CONSOLE_RING_SIZE ) + { + caml_failwith("Console ring too large"); + CAMLreturn(Val_unit); + } + + ring = xc_hypercall_buffer_alloc(_H(xch), ring, conring_size); + + if ( ! ring ) + { + failwith_xc(_H(xch)); + CAMLreturn(Val_unit); + } caml_enter_blocking_section(); - retval = xc_readconsolering(_H(xch), ring_ptr, &size, 0, 0, NULL); + r = xc_readconsolering_buffer(_H(xch), HYPERCALL_BUFFER(ring), + &nr_chars, 0, 0, NULL); caml_leave_blocking_section(); - if (retval) + if ( r ) + { failwith_xc(_H(xch)); + xc_hypercall_buffer_free(_H(xch), ring); + CAMLreturn(Val_unit); + } - ring[size] = '\0'; - CAMLreturn(caml_copy_string(ring)); + ring[nr_chars] = '\0'; + conring = caml_copy_string(ring); + xc_hypercall_buffer_free(_H(xch), ring); + CAMLreturn(conring); } CAMLprim value stub_xc_send_debug_keys(value xch, value keys) _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |