return tbuf_enable(xch, 0);
}
-int xc_tbuf_set_cpu_mask(xc_interface *xch, uint32_t mask)
+int xc_tbuf_set_cpu_mask(xc_interface *xch, xc_cpumap_t mask)
{
DECLARE_SYSCTL;
- DECLARE_HYPERCALL_BUFFER(uint8_t, bytemap);
+ DECLARE_HYPERCALL_BOUNCE(mask, 0, XC_HYPERCALL_BUFFER_BOUNCE_IN);
int ret = -1;
- uint64_t mask64 = mask;
+ int bits, cpusize;
- bytemap = xc_hypercall_buffer_alloc(xch, bytemap, sizeof(mask64));
- if ( bytemap == NULL )
+ cpusize = xc_get_cpumap_size(xch);
+ if (cpusize <= 0)
+ {
+ PERROR("Could not get number of cpus");
+ return -1;
+ }
+
+ HYPERCALL_BOUNCE_SET_SIZE(mask, cpusize);
+
+ bits = xc_get_max_cpus(xch);
+ if (bits <= 0)
+ {
+ PERROR("Could not get number of bits");
+ return -1;
+ }
+
+ if ( xc_hypercall_bounce_pre(xch, mask) )
{
PERROR("Could not allocate memory for xc_tbuf_set_cpu_mask hypercall");
goto out;
sysctl.interface_version = XEN_SYSCTL_INTERFACE_VERSION;
sysctl.u.tbuf_op.cmd = XEN_SYSCTL_TBUFOP_set_cpu_mask;
- bitmap_64_to_byte(bytemap, &mask64, sizeof (mask64) * 8);
-
- set_xen_guest_handle(sysctl.u.tbuf_op.cpu_mask.bitmap, bytemap);
- sysctl.u.tbuf_op.cpu_mask.nr_bits = sizeof(bytemap) * 8;
+ set_xen_guest_handle(sysctl.u.tbuf_op.cpu_mask.bitmap, mask);
+ sysctl.u.tbuf_op.cpu_mask.nr_bits = bits;
ret = do_sysctl(xch, &sysctl);
- xc_hypercall_buffer_free(xch, bytemap);
+ xc_hypercall_bounce_post(xch, mask);
out:
return ret;
return &tbufs;
}
+void print_cpu_mask(xc_cpumap_t map)
+{
+ unsigned int v, had_printed = 0;
+ int i;
+
+ fprintf(stderr, "change cpumask to 0x");
+
+ for ( i = xc_get_cpumap_size(xc_handle); i >= 0; i-- )
+ {
+ v = map[i];
+ if ( v || had_printed || !i ) {
+ if (had_printed)
+ fprintf(stderr,"%02x", v);
+ else
+ fprintf(stderr,"%x", v);
+ had_printed = 1;
+ }
+ }
+ fprintf(stderr, "\n");
+}
+
+static void set_cpu_mask(uint32_t mask)
+{
+ int i, ret = 0;
+ xc_cpumap_t map;
+
+ map = xc_cpumap_alloc(xc_handle);
+ if ( !map )
+ goto out;
+
+ /*
+ * If mask is set, copy the bits out of it. This still works for
+ * systems with more than 32 cpus, as the shift will just shift
+ * mask down to zero.
+ */
+ for ( i = 0; i < xc_get_cpumap_size(xc_handle); i++ )
+ map[i] = (mask >> (i * 8)) & 0xff;
+
+ ret = xc_tbuf_set_cpu_mask(xc_handle, map);
+ if ( ret != 0 )
+ goto out;
+
+ print_cpu_mask(map);
+ free(map);
+ return;
+out:
+ PERROR("Failure to get trace buffer pointer from Xen and set the new mask");
+ exit(EXIT_FAILURE);
+}
+
/**
- * set_mask - set the cpu/event mask in HV
+ * set_mask - set the event mask in HV
* @mask: the new mask
* @type: the new mask type,0-event mask, 1-cpu mask
*
*/
-static void set_mask(uint32_t mask, int type)
+static void set_evt_mask(uint32_t mask)
{
int ret = 0;
- if (type == 1) {
- ret = xc_tbuf_set_cpu_mask(xc_handle, mask);
- fprintf(stderr, "change cpumask to 0x%x\n", mask);
- } else if (type == 0) {
- ret = xc_tbuf_set_evt_mask(xc_handle, mask);
- fprintf(stderr, "change evtmask to 0x%x\n", mask);
- }
+ ret = xc_tbuf_set_evt_mask(xc_handle, mask);
+ fprintf(stderr, "change evtmask to 0x%x\n", mask);
if ( ret != 0 )
{
}
if ( opts.evt_mask != 0 )
- set_mask(opts.evt_mask, 0);
+ set_evt_mask(opts.evt_mask);
+
if ( opts.cpu_mask != 0 )
- set_mask(opts.cpu_mask, 1);
+ set_cpu_mask(opts.cpu_mask);
if ( opts.timeout != 0 )
alarm(opts.timeout);