Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions tools/include/libxl.h
Original file line number Diff line number Diff line change
Expand Up @@ -3007,6 +3007,11 @@ static inline int libxl_qemu_monitor_command_0x041200(libxl_ctx *ctx,
*/
int libxl_clear_domid_history(libxl_ctx *ctx);

/*
* Used to retrieve for a domain using coco
*/
int libxl_domain_attestation(libxl_ctx *ctx, uint32_t domid, int file, bool is_mmonce_file, char *mmonce);

#endif /* LIBXL_H */

/*
Expand Down
33 changes: 17 additions & 16 deletions tools/include/xenctrl.h
Original file line number Diff line number Diff line change
Expand Up @@ -434,11 +434,11 @@ static inline bool dominfo_shutdown_with(const xc_domaininfo_t *info,
(dominfo_shutdown_reason(info) == expected_reason);
}

typedef union
typedef union
{
#if defined(__i386__) || defined(__x86_64__)
vcpu_guest_context_x86_64_t x64;
vcpu_guest_context_x86_32_t x32;
vcpu_guest_context_x86_32_t x32;
#endif
vcpu_guest_context_t c;
} vcpu_guest_context_any_t;
Expand Down Expand Up @@ -735,7 +735,7 @@ int xc_domain_hvm_getcontext(xc_interface *xch,
* This function returns one element of the context of a hvm domain
* @parm xch a handle to an open hypervisor interface
* @parm domid the domain to get information from
* @parm typecode which type of elemnt required
* @parm typecode which type of elemnt required
* @parm instance which instance of the type
* @parm ctxt_buf a pointer to a structure to store the execution context of
* the hvm domain
Expand Down Expand Up @@ -917,7 +917,7 @@ xc_sched_arinc653_schedule_get(
* @parm xch a handle to an open hypervisor interface
* @parm domid the domain id to send trigger
* @parm trigger the trigger type
* @parm vcpu the vcpu number to send trigger
* @parm vcpu the vcpu number to send trigger
* return 0 on success, -1 on failure
*/
int xc_domain_send_trigger(xc_interface *xch,
Expand All @@ -938,11 +938,11 @@ int xc_domain_setdebugging(xc_interface *xch,
unsigned int enable);

/**
* This function audits the (top level) p2m of a domain
* This function audits the (top level) p2m of a domain
* and returns the different error counts, if any.
*
* @parm xch a handle to an open hypervisor interface
* @parm domid the domain id whose top level p2m we
* @parm domid the domain id whose top level p2m we
* want to audit
* @parm orphans count of m2p entries for valid
* domain pages containing an invalid value
Expand All @@ -951,14 +951,14 @@ int xc_domain_setdebugging(xc_interface *xch,
* @parm p2m_bad count of p2m entries for this domain
* mismatching the associated m2p entry
* return 0 on success, -1 on failure
* errno values on failure include:
* errno values on failure include:
* -ENOSYS: not implemented
* -EFAULT: could not copy results back to guest
*/
int xc_domain_p2m_audit(xc_interface *xch,
uint32_t domid,
uint64_t *orphans,
uint64_t *m2p_bad,
uint64_t *m2p_bad,
uint64_t *p2m_bad);

/**
Expand Down Expand Up @@ -1093,7 +1093,7 @@ typedef int xc_evtchn_port_or_error_t;
* This function allocates an unbound port. Ports are named endpoints used for
* interdomain communication. This function is most useful in opening a
* well-known port within a domain to receive events on.
*
*
* NOTE: If you are allocating a *local* unbound port, you probably want to
* use xc_evtchn_bind_unbound_port(). This function is intended for allocating
* ports *only* during domain creation.
Expand Down Expand Up @@ -1165,7 +1165,7 @@ int xc_machphys_mfn_list(xc_interface *xch,

typedef struct xen_sysctl_cpuinfo xc_cpuinfo_t;
int xc_getcpuinfo(xc_interface *xch, int max_cpus,
xc_cpuinfo_t *info, int *nr_cpus);
xc_cpuinfo_t *info, int *nr_cpus);

int xc_domain_setmaxmem(xc_interface *xch,
uint32_t domid,
Expand Down Expand Up @@ -1398,7 +1398,7 @@ void *xc_memalign(xc_interface *xch, size_t alignment, size_t size);
* as 4M superpages, or guests using PSE36). Only used for debugging.
*
* Translates a virtual address in the context of a given domain and
* vcpu returning the GFN containing the address (that is, an MFN for
* vcpu returning the GFN containing the address (that is, an MFN for
* PV guests, a PFN for HVM guests). Returns 0 for failure.
*
* @parm xch a handle on an open hypervisor interface
Expand Down Expand Up @@ -1434,7 +1434,7 @@ long xc_get_tot_pages(xc_interface *xch, uint32_t domid);
/**
* This function retrieves the the number of bytes available
* in the heap in a specific range of address-widths and nodes.
*
*
* @parm xch a handle to an open hypervisor interface
* @parm domid the domain to query
* @parm min_width the smallest address width to query (0 if don't care)
Expand Down Expand Up @@ -1685,6 +1685,7 @@ int xc_get_hvm_param(xc_interface *handle, uint32_t dom, int param, unsigned lon

int xc_coco_platform_status(xc_interface *handle, coco_platform_status_t *status);
int xc_coco_prepare_initial_mem(xc_interface *handle, coco_prepare_initial_mem_t *cmd);
int xc_coco_get_attestation(xc_interface *handle, coco_attestation_report_t *report);

/* HVM guest pass-through */
int xc_assign_device(xc_interface *xch,
Expand Down Expand Up @@ -1904,8 +1905,8 @@ int xc_cpu_offline(xc_interface *xch, int cpu);
int xc_smt_enable(xc_interface *xch);
int xc_smt_disable(xc_interface *xch);

/*
* cpufreq para name of this structure named
/*
* cpufreq para name of this structure named
* same as sysfs file name of native linux
*/
typedef struct xen_userspace xc_userspace_t;
Expand Down Expand Up @@ -2017,7 +2018,7 @@ int xc_altp2m_get_vcpu_p2m_idx(xc_interface *handle, uint32_t domid,
int xc_altp2m_set_visibility(xc_interface *handle, uint32_t domid,
uint16_t view_id, bool visible);

/**
/**
* Mem paging operations.
* Paging is supported only on the x86 architecture in 64 bit mode, with
* Hardware-Assisted Paging (i.e. Intel EPT, AMD NPT). Moreover, AMD NPT
Expand All @@ -2033,7 +2034,7 @@ int xc_mem_paging_prep(xc_interface *xch, uint32_t domain_id, uint64_t gfn);
int xc_mem_paging_load(xc_interface *xch, uint32_t domain_id,
uint64_t gfn, void *buffer);

/**
/**
* Access tracking operations.
* Supported only on Intel EPT 64 bit processors.
*/
Expand Down
26 changes: 23 additions & 3 deletions tools/libs/ctrl/xc_domain.c
Original file line number Diff line number Diff line change
Expand Up @@ -655,7 +655,7 @@ long long xc_logdirty_control(xc_interface *xch,
if ( stats )
memcpy(stats, &domctl.u.shadow_op.stats,
sizeof(xc_shadow_op_stats_t));

return (rc == 0) ? domctl.u.shadow_op.pages : rc;
}

Expand Down Expand Up @@ -1532,6 +1532,26 @@ int xc_coco_prepare_initial_mem(xc_interface *handle, coco_prepare_initial_mem_t
return rc;
}

int xc_coco_get_attestation(xc_interface *handle, coco_attestation_report_t *cmd)
{
DECLARE_HYPERCALL_BUFFER(coco_attestation_report_t, arg);
int rc;

arg = xc_hypercall_buffer_alloc(handle, arg, sizeof(*arg));
if ( arg == NULL )
return -1;
memcpy(arg, cmd, sizeof(coco_attestation_report_t));

rc = xencall2(handle->xcall, __HYPERVISOR_coco_op, XEN_COCO_attestation_report,
HYPERCALL_BUFFER_AS_ARG(arg));

if (!rc) {
memcpy(cmd, arg, sizeof(coco_attestation_report_t));
}
xc_hypercall_buffer_free(handle, arg);
return rc;
}

int xc_domain_setdebugging(xc_interface *xch,
uint32_t domid,
unsigned int enable)
Expand Down Expand Up @@ -2060,10 +2080,10 @@ int xc_domain_debug_control(xc_interface *xc, uint32_t domid, uint32_t sop, uint
return do_domctl(xc, &domctl);
}

int xc_domain_p2m_audit(xc_interface *xch,
int xc_domain_p2m_audit(xc_interface *xch,
uint32_t domid,
uint64_t *orphans,
uint64_t *m2p_bad,
uint64_t *m2p_bad,
uint64_t *p2m_bad)
{
struct xen_domctl domctl = {};
Expand Down
62 changes: 62 additions & 0 deletions tools/libs/light/libxl_domain.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#include "libxl_osdeps.h"

#include "libxl_internal.h"
#include "xenctrl.h"
#include <stdint.h>

#define PAGE_TO_MEMKB(pages) ((pages) * 4)

Expand Down Expand Up @@ -2621,6 +2623,66 @@ static void retrieve_domain_configuration_end(libxl__egc *egc,
libxl__ao_complete(egc, ao, rc);
}

static int hex_char_to_int(char c) {
if ('0' <= c && c <= '9') return c - '0';
if ('a' <= c && c <= 'f') return c - 'a' + 10;
if ('A' <= c && c <= 'F') return c - 'A' + 10;
return -1;
}

int libxl_domain_attestation(libxl_ctx *ctx, uint32_t domid, int file, bool is_mmonce_file, char *mmonce) {
coco_attestation_report_t report;
int rc, r;

if (is_mmonce_file) {
int datalen = 0;
void *data = NULL;

r = libxl_read_file_contents(ctx, mmonce, &data, &datalen);

if (datalen != 16) {
fprintf(stderr, "Error: invalid mmonce length\n");
return ERROR_INVAL;
}
memcpy(&report.mnonce, data, 16);
free(data);
} else {
if (strnlen(mmonce, 33) != 32) {
fprintf(stderr, "Error: invalid mmonce length\n");
}
for (int i = 0; i < 16; i++) {
int hi = hex_char_to_int(mmonce[2*i]);
int lo = hex_char_to_int(mmonce[2*i + 1]);

if (hi < 0 || lo < 0) {
fprintf(stderr, "Error: invalid hex character\n");
return -1;
}

report.mnonce[i] = (hi << 4) | lo;
}

}

report.domid = domid;
report.len = 0;

rc = xc_coco_get_attestation(ctx->xch, &report);

if (!rc) {
size_t written = write(file, &report.sev, report.len);
// the union used does not matter, we use the pointer
if (written != report.len) {
perror("write");
close(file);
return -1;
}
}

close(file);
return rc;
}

/*
* Local variables:
* mode: C
Expand Down
6 changes: 3 additions & 3 deletions tools/libs/light/libxl_x86.c
Original file line number Diff line number Diff line change
Expand Up @@ -810,15 +810,15 @@ static int domain_construct_memmap(libxl__gc *gc,
{
e820[nr].type = XEN_HVM_MEMMAP_TYPE_SHARED_INFO;
e820[nr].addr = special_region_offset;
e820[nr].size = PAGE_SIZE;
e820[nr].size = page_size;
special_region_offset += e820[nr].size;
nr++;

if ( gnttab_frame_count )
{
e820[nr].type = XEN_HVM_MEMMAP_TYPE_GRANT_TABLE;
e820[nr].addr = special_region_offset;
e820[nr].size = gnttab_frame_count * PAGE_SIZE;
e820[nr].size = gnttab_frame_count * page_size;
special_region_offset += e820[nr].size;
nr++;
}
Expand All @@ -827,7 +827,7 @@ static int domain_construct_memmap(libxl__gc *gc,
{
e820[nr].type = XEN_HVM_MEMMAP_TYPE_GNTTAB_STATUS;
e820[nr].addr = special_region_offset;
e820[nr].size = gnttab_status_frame_count * PAGE_SIZE;
e820[nr].size = gnttab_status_frame_count * page_size;
special_region_offset += e820[nr].size;
nr++;
}
Expand Down
1 change: 1 addition & 0 deletions tools/xl/xl.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ int main_psr_mba_set(int argc, char **argv);
int main_psr_mba_show(int argc, char **argv);
#endif
int main_qemu_monitor_command(int argc, char **argv);
int main_attestation(int argc, char **argv);

void help(const char *command);

Expand Down
5 changes: 5 additions & 0 deletions tools/xl/xl_cmdtable.c
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,11 @@ const struct cmd_spec cmd_table[] = {
"Issue a qemu monitor command to the device model of a domain",
"<Domain> <Command>",
},
{ "attestation",
&main_attestation, 0, 0,
"request attestation for a coco and put it into a file",
"<options> <Domain>",
},
#ifdef LIBXL_HAVE_DT_OVERLAY
{ "dt-overlay",
&main_dt_overlay, 0, 1,
Expand Down
50 changes: 50 additions & 0 deletions tools/xl/xl_misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* GNU Lesser General Public License for more details.
*/

#include <fcntl.h>
#include <limits.h>
#include <stdlib.h>

Expand Down Expand Up @@ -363,6 +364,55 @@ int main_config_update(int argc, char **argv)
return 0;
}

int main_attestation(int argc, char **argv) {
int rc;
int dst_file = 1;
char * mmonce = NULL;
uint32_t domid;
bool is_mmonce_file = false;

int opt;
static struct option opts[] = {
{"file", 1, 0, 'f'},
{"print", 0, 0, 'p'},
{"mmonce", 1, 0, 'm'},
{"mmonce-file", 1, 0, 'n'},
COMMON_LONG_OPTS
};

SWITCH_FOREACH_OPT(opt, "f:pm:n:", opts, "attestation", 0) {
case 'p':
dst_file = 1;
break;
case 'f':
dst_file = open(optarg, O_WRONLY | O_CREAT, 0644);
if (!dst_file) {
perror("open");
return -1;
}
break;
case 'm':
mmonce = optarg;
is_mmonce_file = false;
break;
case 'n':
mmonce = optarg;
is_mmonce_file = true;
break;
}

if (mmonce == NULL) {
fprintf(stderr, "Error: no mmonce provided\n");
return 1;
}

domid = find_domain(argv[optind]);

rc = libxl_domain_attestation(ctx, domid, dst_file, is_mmonce_file, mmonce);

return rc;
}

/*
* Local variables:
* mode: C
Expand Down
Loading