

Xen port notes

Mathieu Desnoyers, April 2006

Useful files :

common/trace.c
include/xen/trace.h and the dom0 op in include/public/dom0_ops.h

alloc buffer (alloc_trace_bufs) :
alloc_xenheap_pages

Shared buffer between dom0 and hypervisor :
share_xen_page_with_privileged_guests



trace_create / trace_destroy :

call xen hooks from dom0 to allocate a new buffer, get the newly allocated 
struct trace pointer.
Share struct traces with dom0 to have offset and consumed counts.
Share the buffers with dom0 too.

Create a new "xen" channel.


Create 4 new xen facilities (see include/public/trace.h) :
xen_sched  (grep TRC_SCHED)
  sched_dom_add
	sched_dom_rem
	sched_sleep
	sched_wake
	sched_yield
	sched_block
	sched_shutdown
	sched_ctl
	sched_switch
	sched_s_timer_fn
	sched_t_timer_fn
	sched_dom_timer_fn
	sched_dom_timer_fn
	sched_switch_infprev
	sched_switch_infnext
xen_dom0op (grep TRC_DOM0OP)
  dom0op_enter_base
  dom0op_leave_base
xen_vmx (grep TRC_VMX)
  vmx_vmexit
  vmx_vmentry
	vmx_timer_intr
	vmx_int
	vmx_io
xen_mem (grep TRC_MEM)
  mem_page_grant_map
	mem_page_grant_unmap
	mem_page_grant_transfer


How to share xen pages efficiently ?
Pages allocated in xen heap, the shared with dom0.

How buffers are accessed in dom0 ?
directly from pointers to buffers contained in get_info control information.

do_dom0_op

tbufcontrol -> control info
  int tb_control(dom0_tbufcontrol_t *tbc)

DOM0_TBUF_GET_INFO  buffer_mfn   __pa(t_bufs[0]) >> PAGE_SHIFT;


create trace :

in : 
trace name
buffer size
return : 0 success, 1 failure
do :
alloc buffer xen
share with dom0

destroy trace :
in :
trace name
do : unshare buffer / free.


start/stop : 
tb_control that will update the control structure.
in : trace name
start : put active to 1 + inc. nb_active traces
stop : put active to 0 + dec nb_active traces.
return : 0 success, 1 failure.

consume :
in : trace name
tb_control that will update the consumed count.
in : old count.
return : 0 success, 1 failure (pushed).

get_info :
tb_control that returns a fresh copy of trace control info.



NOTE 8-11-2006

Xen 3.0.3
Only one init of buffers (cannot change buffer size)
tbc->buffer_mfn = opt_tbuf_size ? virt_to_mfn(per_cpu(t_bufs, 0)) : 0;
/* Convert between Xen-heap virtual addresses and machine frame numbers. */
#define virt_to_mfn(va)     (virt_to_maddr(va) >> PAGE_SHIFT)

struct t_buf *tbufs_mapped;

    tbufs_mapped = xc_map_foreign_range(xc_handle, DOMID_XEN,
                                        size * num, PROT_READ | PROT_WRITE,
                                        tbufs_mfn);

int fd = open("/proc/xen/privcmd", O_RDWR);

/* sleep for this long (milliseconds) between checking the trace buffers */
#define POLL_SLEEP_MILLIS 100


netfront.c
xenbus_alloc_evtchn
bind_evtchn_to_irqhandler


virq :

include/public/xen.h VIRQ_TBUF
			/* G. (DOM0) Trace buffer has records available. */

trace_notify_guest : send_guest_global_virq(dom0, VIRQ_TBUF);

see arch/i386/oprofile/xenoprof.c
bind_virq



