aboutsummaryrefslogtreecommitdiffstats
path: root/tools/libxc/xc_private.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/libxc/xc_private.c')
-rw-r--r--tools/libxc/xc_private.c150
1 files changed, 149 insertions, 1 deletions
diff --git a/tools/libxc/xc_private.c b/tools/libxc/xc_private.c
index e4316e6994..65aa1085e0 100644
--- a/tools/libxc/xc_private.c
+++ b/tools/libxc/xc_private.c
@@ -4,6 +4,7 @@
* Helper functions for the rest of the library.
*/
+#include <zlib.h>
#include "xc_private.h"
void *xc_map_foreign_batch(int xc_handle, u32 dom, int prot,
@@ -159,12 +160,13 @@ int finish_mmu_updates(int xc_handle, mmu_t *mmu)
}
-long long xc_domain_get_cpu_usage( int xc_handle, domid_t domid )
+long long xc_domain_get_cpu_usage( int xc_handle, domid_t domid, int vcpu )
{
dom0_op_t op;
op.cmd = DOM0_GETDOMAININFO;
op.u.getdomaininfo.domain = (domid_t)domid;
+ op.u.getdomaininfo.exec_domain = (u16)vcpu;
op.u.getdomaininfo.ctxt = NULL;
if ( (do_dom0_op(xc_handle, &op) < 0) ||
((u16)op.u.getdomaininfo.domain != domid) )
@@ -201,5 +203,151 @@ unsigned long xc_get_m2p_start_mfn ( int xc_handle )
return mfn;
}
+int xc_get_pfn_list(int xc_handle,
+ u32 domid,
+ unsigned long *pfn_buf,
+ unsigned long max_pfns)
+{
+ dom0_op_t op;
+ int ret;
+ op.cmd = DOM0_GETMEMLIST;
+ op.u.getmemlist.domain = (domid_t)domid;
+ op.u.getmemlist.max_pfns = max_pfns;
+ op.u.getmemlist.buffer = pfn_buf;
+
+
+ if ( mlock(pfn_buf, max_pfns * sizeof(unsigned long)) != 0 )
+ {
+ PERROR("Could not lock pfn list buffer");
+ return -1;
+ }
+
+ ret = do_dom0_op(xc_handle, &op);
+
+ (void)munlock(pfn_buf, max_pfns * sizeof(unsigned long));
+
+#if 0
+#ifdef DEBUG
+ DPRINTF(("Ret for xc_get_pfn_list is %d\n", ret));
+ if (ret >= 0) {
+ int i, j;
+ for (i = 0; i < op.u.getmemlist.num_pfns; i += 16) {
+ fprintf(stderr, "0x%x: ", i);
+ for (j = 0; j < 16; j++)
+ fprintf(stderr, "0x%lx ", pfn_buf[i + j]);
+ fprintf(stderr, "\n");
+ }
+ }
+#endif
+#endif
+
+ return (ret < 0) ? -1 : op.u.getmemlist.num_pfns;
+}
+
+long xc_get_tot_pages(int xc_handle, u32 domid)
+{
+ dom0_op_t op;
+ op.cmd = DOM0_GETDOMAININFO;
+ op.u.getdomaininfo.domain = (domid_t)domid;
+ op.u.getdomaininfo.exec_domain = 0;
+ op.u.getdomaininfo.ctxt = NULL;
+ return (do_dom0_op(xc_handle, &op) < 0) ?
+ -1 : op.u.getdomaininfo.tot_pages;
+}
+
+int xc_copy_to_domain_page(int xc_handle,
+ u32 domid,
+ unsigned long dst_pfn,
+ void *src_page)
+{
+ void *vaddr = xc_map_foreign_range(
+ xc_handle, domid, PAGE_SIZE, PROT_WRITE, dst_pfn);
+ if ( vaddr == NULL )
+ return -1;
+ memcpy(vaddr, src_page, PAGE_SIZE);
+ munmap(vaddr, PAGE_SIZE);
+ return 0;
+}
+
+unsigned long xc_get_filesz(int fd)
+{
+ u16 sig;
+ u32 _sz = 0;
+ unsigned long sz;
+
+ lseek(fd, 0, SEEK_SET);
+ read(fd, &sig, sizeof(sig));
+ sz = lseek(fd, 0, SEEK_END);
+ if ( sig == 0x8b1f ) /* GZIP signature? */
+ {
+ lseek(fd, -4, SEEK_END);
+ read(fd, &_sz, 4);
+ sz = _sz;
+ }
+ lseek(fd, 0, SEEK_SET);
+
+ return sz;
+}
+char *xc_read_kernel_image(const char *filename, unsigned long *size)
+{
+ int kernel_fd = -1;
+ gzFile kernel_gfd = NULL;
+ char *image = NULL;
+ unsigned int bytes;
+ if ( (kernel_fd = open(filename, O_RDONLY)) < 0 )
+ {
+ PERROR("Could not open kernel image");
+ goto out;
+ }
+
+ *size = xc_get_filesz(kernel_fd);
+
+ if ( (kernel_gfd = gzdopen(kernel_fd, "rb")) == NULL )
+ {
+ PERROR("Could not allocate decompression state for state file");
+ goto out;
+ }
+
+ if ( (image = malloc(*size)) == NULL )
+ {
+ PERROR("Could not allocate memory for kernel image");
+ goto out;
+ }
+
+ if ( (bytes = gzread(kernel_gfd, image, *size)) != *size )
+ {
+ PERROR("Error reading kernel image, could not"
+ " read the whole image (%d != %ld).", bytes, *size);
+ free(image);
+ image = NULL;
+ }
+
+ out:
+ if ( kernel_gfd != NULL )
+ gzclose(kernel_gfd);
+ else if ( kernel_fd >= 0 )
+ close(kernel_fd);
+ return image;
+}
+
+void xc_map_memcpy(unsigned long dst, char *src, unsigned long size,
+ int xch, u32 dom, unsigned long *parray,
+ unsigned long vstart)
+{
+ char *va;
+ unsigned long chunksz, done, pa;
+
+ for ( done = 0; done < size; done += chunksz )
+ {
+ pa = dst + done - vstart;
+ va = xc_map_foreign_range(
+ xch, dom, PAGE_SIZE, PROT_WRITE, parray[pa>>PAGE_SHIFT]);
+ chunksz = size - done;
+ if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
+ chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1));
+ memcpy(va + (pa & (PAGE_SIZE-1)), src + done, chunksz);
+ munmap(va, PAGE_SIZE);
+ }
+}