[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [Patch v6 06/13] tools/libxc: x86 common code
Save/restore records common to all x86 domain types (HVM, PV). This is only the TSC_INFO record. Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx> --- tools/libxc/saverestore/common_x86.c | 133 ++++++++++++++++++++++++++++++++++ tools/libxc/saverestore/common_x86.h | 26 +++++++ 2 files changed, 159 insertions(+) create mode 100644 tools/libxc/saverestore/common_x86.c create mode 100644 tools/libxc/saverestore/common_x86.h diff --git a/tools/libxc/saverestore/common_x86.c b/tools/libxc/saverestore/common_x86.c new file mode 100644 index 0000000..b64b291 --- /dev/null +++ b/tools/libxc/saverestore/common_x86.c @@ -0,0 +1,133 @@ +#include "common_x86.h" + +static void cpuid_count(uint32_t leaf, uint32_t subleaf, + uint32_t *eax, uint32_t *ebx, + uint32_t *ecx, uint32_t *edx) +{ + asm volatile ("cpuid" + : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx) + : "a" (leaf), "c" (subleaf)); +} + +static void cpuid(uint32_t leaf, + uint32_t *eax, uint32_t *ebx, + uint32_t *ecx, uint32_t *edx) +{ + cpuid_count(leaf, 0, eax, ebx, ecx, edx); +} + +static int get_processor_brand_string(char *str) +{ + uint32_t *parts = (uint32_t*)str; + uint32_t max_extd_leaf, dummy; + + cpuid(0x80000000, &max_extd_leaf, &dummy, &dummy, &dummy); + + if ( max_extd_leaf < 0x80000004 ) + return -1; + + cpuid(0x80000002, &parts[0], &parts[1], &parts[2], &parts[3]); + cpuid(0x80000003, &parts[4], &parts[5], &parts[6], &parts[7]); + cpuid(0x80000004, &parts[8], &parts[9], &parts[10], &parts[11]); + + return 0; +} + +int write_tsc_info(struct xc_sr_context *ctx) +{ + xc_interface *xch = ctx->xch; + struct xc_sr_rec_tsc_info tsc = { 0 }; + struct xc_sr_record rec = + { + .type = REC_TYPE_TSC_INFO, + .length = sizeof(tsc), + .data = &tsc + }; + + if ( xc_domain_get_tsc_info(xch, ctx->domid, &tsc.mode, + &tsc.nsec, &tsc.khz, &tsc.incarnation) < 0 ) + { + PERROR("Unable to obtain TSC information"); + return -1; + } + + return write_record(ctx, &rec); +} + +int handle_tsc_info(struct xc_sr_context *ctx, struct xc_sr_record *rec) +{ + xc_interface *xch = ctx->xch; + struct xc_sr_rec_tsc_info *tsc = rec->data; + + if ( rec->length != sizeof(*tsc) ) + { + ERROR("TSC_INFO record wrong size: length %"PRIu32", expected %zu", + rec->length, sizeof(*tsc)); + return -1; + } + + if ( xc_domain_set_tsc_info(xch, ctx->domid, tsc->mode, + tsc->nsec, tsc->khz, tsc->incarnation) ) + { + PERROR("Unable to set TSC information"); + return -1; + } + + return 0; +} + +int arch_write_saving_cpu(struct xc_sr_context *ctx) +{ + xc_interface *xch = ctx->xch; + char *brand_string = alloca(49); /* 48 from cpuid, and NUL. */ + struct xc_sr_record rec; + + if ( get_processor_brand_string(brand_string) ) + { + ERROR("Failed to obtain cpuid long processor brand string"); + return -1; + } + + brand_string[48] = '\0'; + while ( *brand_string == ' ' ) /* Strip leading spaces. */ + brand_string++; + + rec.type = REC_TYPE_SAVING_CPU; + rec.length = strlen(brand_string); + rec.data = brand_string; + + return write_record(ctx, &rec); +} + +int arch_handle_saving_cpu(struct xc_sr_context *ctx, struct xc_sr_record *rec) +{ + xc_interface *xch = ctx->xch; + char *brand_string = alloca(49); /* 48 from cpuid, and NUL. */ + + if ( rec->length == 0 ) + return 0; + + DPRINTF("Saving cpu was '%*s'", + (int)rec->length, (char*)rec->data); + + if ( !get_processor_brand_string(brand_string) ) + { + brand_string[48] = '\0'; + while ( *brand_string == ' ' ) /* Strip leading spaces. */ + brand_string++; + + DPRINTF("Current cpu is '%s'", brand_string); + } + + return 0; +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/tools/libxc/saverestore/common_x86.h b/tools/libxc/saverestore/common_x86.h new file mode 100644 index 0000000..5971bc5 --- /dev/null +++ b/tools/libxc/saverestore/common_x86.h @@ -0,0 +1,26 @@ +#ifndef __COMMON_X86__H +#define __COMMON_X86__H + +#include "common.h" + +/* + * Obtains a domains TSC information from Xen and writes a TSC_INFO record + * into the stream. + */ +int write_tsc_info(struct xc_sr_context *ctx); + +/* + * Parses a TSC_INFO record and applies the result to the domain. + */ +int handle_tsc_info(struct xc_sr_context *ctx, struct xc_sr_record *rec); + +#endif +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ -- 1.7.10.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |