[libvirt] [PATCH v3 0/5] Add runnability info to query-cpu-definitions

This series extends query-cpu-definitions to include an extra field: "unavailable-features". The new field can be used to find out reasons that prevent the CPU model from running in the current host. This will return information based on the current machine and accelerator only. In the future we may extend these mechanisms to allow querying other machines and other accelerators without restarting QEMU, but it will require some reorganization of QEMU's main code. Changes v2 -> v3: * Small documentation reword * Suggested-by: Markus Armbruster <armbru@redhat.com> * Create a x86_cpu_feature_name() function, to isolate the code that returns the property name Changes v1 -> v2: * Fixed documentation to say "(since 2.7)" * Removed @runnable field, improved documentation Example command output: { "return": [ { "unavailable-features": [], "static": false, "name": "host" }, { "unavailable-features": [], "static": false, "name": "qemu64" }, { "unavailable-features": [], "static": false, "name": "qemu32" }, { "unavailable-features": ["npt", "sse4a", "3dnow", "3dnowext", "fxsr-opt", "mmxext"], "static": false, "name": "phenom" }, { "unavailable-features": [], "static": false, "name": "pentium3" }, { "unavailable-features": [], "static": false, "name": "pentium2" }, { "unavailable-features": [], "static": false, "name": "pentium" }, { "unavailable-features": [], "static": false, "name": "n270" }, { "unavailable-features": [], "static": false, "name": "kvm64" }, { "unavailable-features": [], "static": false, "name": "kvm32" }, { "unavailable-features": [], "static": false, "name": "coreduo" }, { "unavailable-features": [], "static": false, "name": "core2duo" }, { "unavailable-features": ["3dnow", "3dnowext", "mmxext"], "static": false, "name": "athlon" }, { "unavailable-features": [], "static": false, "name": "Westmere" }, { "unavailable-features": ["xgetbv1", "xsavec", "3dnowprefetch", "smap", "adx", "rdseed", "mpx", "rtm", "hle"], "static": false, "name": "Skylake-Client" }, { "unavailable-features": [], "static": false, "name": "SandyBridge" }, { "unavailable-features": [], "static": false, "name": "Penryn" }, { "unavailable-features": ["tbm", "fma4", "xop", "3dnowprefetch", "misalignsse", "sse4a"], "static": false, "name": "Opteron_G5" }, { "unavailable-features": ["fma4", "xop", "3dnowprefetch", "misalignsse", "sse4a"], "static": false, "name": "Opteron_G4" }, { "unavailable-features": ["misalignsse", "sse4a"], "static": false, "name": "Opteron_G3" }, { "unavailable-features": [], "static": false, "name": "Opteron_G2" }, { "unavailable-features": [], "static": false, "name": "Opteron_G1" }, { "unavailable-features": [], "static": false, "name": "Nehalem" }, { "unavailable-features": [], "static": false, "name": "IvyBridge" }, { "unavailable-features": ["rtm", "hle"], "static": false, "name": "Haswell" }, { "unavailable-features": [], "static": false, "name": "Haswell-noTSX" }, { "unavailable-features": [], "static": false, "name": "Conroe" }, { "unavailable-features": ["3dnowprefetch", "smap", "adx", "rdseed", "rtm", "hle"], "static": false, "name": "Broadwell" }, { "unavailable-features": ["3dnowprefetch", "smap", "adx", "rdseed"], "static": false, "name": "Broadwell-noTSX" }, { "unavailable-features": [], "static": false, "name": "486" } ]} Cc: David Hildenbrand <dahi@linux.vnet.ibm.com> Cc: Michael Mueller <mimu@linux.vnet.ibm.com> Cc: Christian Borntraeger <borntraeger@de.ibm.com> Cc: Cornelia Huck <cornelia.huck@de.ibm.com> Cc: Jiri Denemark <jdenemar@redhat.com> Cc: libvir-list@redhat.com Eduardo Habkost (5): target-i386: List CPU models using subclass list target-i386: Move warning code outside x86_cpu_filter_features() target-i386: Define CPUID filtering functions before x86_cpu_list() qmp: Add runnability information to query-cpu-definitions target-i386: Return runnability information on query-cpu-definitions qapi-schema.json | 23 ++++- target-i386/cpu-qom.h | 4 + target-i386/cpu.c | 236 ++++++++++++++++++++++++++++++++++++-------------- 3 files changed, 199 insertions(+), 64 deletions(-) -- 2.7.4

Instead of using the builtin_x86_defs array, use the QOM subclass list to list CPU models on "-cpu ?" and "query-cpu-definitions". Signed-off-by: Andreas Färber <afaerber@suse.de> [ehabkost: copied code from a patch by Andreas: "target-i386: QOM'ify CPU", from March 2012] Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> --- target-i386/cpu-qom.h | 4 ++ target-i386/cpu.c | 103 ++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 78 insertions(+), 29 deletions(-) diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h index 5dde658..e724004 100644 --- a/target-i386/cpu-qom.h +++ b/target-i386/cpu-qom.h @@ -63,6 +63,10 @@ typedef struct X86CPUClass { bool kvm_required; + /* Optional description of CPU model. + * If unavailable, cpu_def->model_id is used */ + const char *model_description; + DeviceRealize parent_realize; void (*parent_reset)(CPUState *cpu); } X86CPUClass; diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 5a5299a..24682aa 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -1616,6 +1616,9 @@ static void host_x86_cpu_class_init(ObjectClass *oc, void *data) cpu_x86_fill_model_id(host_cpudef.model_id); xcc->cpu_def = &host_cpudef; + xcc->model_description = + "KVM processor with all supported host features " + "(only available in KVM mode)"; /* level, xlevel, xlevel2, and the feature words are initialized on * instance_init, because they require KVM to be initialized. @@ -2083,23 +2086,62 @@ static void listflags(FILE *f, fprintf_function print, const char **featureset) } } -/* generate CPU information. */ +/* Sort alphabetically by type name, listing kvm_required models last. */ +static gint x86_cpu_list_compare(gconstpointer a, gconstpointer b) +{ + ObjectClass *class_a = (ObjectClass *)a; + ObjectClass *class_b = (ObjectClass *)b; + X86CPUClass *cc_a = X86_CPU_CLASS(class_a); + X86CPUClass *cc_b = X86_CPU_CLASS(class_b); + const char *name_a, *name_b; + + if (cc_a->kvm_required != cc_b->kvm_required) { + /* kvm_required items go last */ + return cc_a->kvm_required ? 1 : -1; + } else { + name_a = object_class_get_name(class_a); + name_b = object_class_get_name(class_b); + return strcmp(name_a, name_b); + } +} + +static GSList *get_sorted_cpu_model_list(void) +{ + GSList *list = object_class_get_list(TYPE_X86_CPU, false); + list = g_slist_sort(list, x86_cpu_list_compare); + return list; +} + +static void x86_cpu_list_entry(gpointer data, gpointer user_data) +{ + ObjectClass *oc = data; + X86CPUClass *cc = X86_CPU_CLASS(oc); + CPUListState *s = user_data; + char *name = x86_cpu_class_get_model_name(cc); + const char *desc = cc->model_description; + if (!desc) { + desc = cc->cpu_def->model_id; + } + + (*s->cpu_fprintf)(s->file, "x86 %16s %-48s\n", + name, desc); + g_free(name); +} + +/* list available CPU models and flags */ void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf) { - X86CPUDefinition *def; - char buf[256]; int i; + CPUListState s = { + .file = f, + .cpu_fprintf = cpu_fprintf, + }; + GSList *list; - for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) { - def = &builtin_x86_defs[i]; - snprintf(buf, sizeof(buf), "%s", def->name); - (*cpu_fprintf)(f, "x86 %16s %-48s\n", buf, def->model_id); - } -#ifdef CONFIG_KVM - (*cpu_fprintf)(f, "x86 %16s %-48s\n", "host", - "KVM processor with all supported host features " - "(only available in KVM mode)"); -#endif + (*cpu_fprintf)(f, "Available CPUs:\n"); + list = get_sorted_cpu_model_list(); + g_slist_foreach(list, x86_cpu_list_entry, &s); + g_slist_free(list); (*cpu_fprintf)(f, "\nRecognized CPUID flags:\n"); for (i = 0; i < ARRAY_SIZE(feature_word_info); i++) { @@ -2111,26 +2153,29 @@ void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf) } } -CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp) +static void x86_cpu_definition_entry(gpointer data, gpointer user_data) { - CpuDefinitionInfoList *cpu_list = NULL; - X86CPUDefinition *def; - int i; + ObjectClass *oc = data; + X86CPUClass *cc = X86_CPU_CLASS(oc); + CpuDefinitionInfoList **cpu_list = user_data; + CpuDefinitionInfoList *entry; + CpuDefinitionInfo *info; - for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) { - CpuDefinitionInfoList *entry; - CpuDefinitionInfo *info; - - def = &builtin_x86_defs[i]; - info = g_malloc0(sizeof(*info)); - info->name = g_strdup(def->name); + info = g_malloc0(sizeof(*info)); + info->name = x86_cpu_class_get_model_name(cc); - entry = g_malloc0(sizeof(*entry)); - entry->value = info; - entry->next = cpu_list; - cpu_list = entry; - } + entry = g_malloc0(sizeof(*entry)); + entry->value = info; + entry->next = *cpu_list; + *cpu_list = entry; +} +CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp) +{ + CpuDefinitionInfoList *cpu_list = NULL; + GSList *list = get_sorted_cpu_model_list(); + g_slist_foreach(list, x86_cpu_definition_entry, &cpu_list); + g_slist_free(list); return cpu_list; } -- 2.7.4

x86_cpu_filter_features() will be reused by code that shouldn't print any warning. Move the warning code to a new x86_cpu_report_filtered_features() function, and call it from x86_cpu_realizefn(). Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> --- target-i386/cpu.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 24682aa..1a42233 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2218,9 +2218,6 @@ static int x86_cpu_filter_features(X86CPU *cpu) env->features[w] &= host_feat; cpu->filtered_features[w] = requested_features & ~env->features[w]; if (cpu->filtered_features[w]) { - if (cpu->check_cpuid || cpu->enforce_cpuid) { - report_unavailable_features(w, cpu->filtered_features[w]); - } rv = 1; } } @@ -2228,6 +2225,15 @@ static int x86_cpu_filter_features(X86CPU *cpu) return rv; } +static void x86_cpu_report_filtered_features(X86CPU *cpu) +{ + FeatureWord w; + + for (w = 0; w < FEATURE_WORDS; w++) { + report_unavailable_features(w, cpu->filtered_features[w]); + } +} + static void x86_cpu_apply_props(X86CPU *cpu, PropValue *props) { PropValue *pv; @@ -3042,12 +3048,16 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) env->cpuid_level = 7; } - if (x86_cpu_filter_features(cpu) && cpu->enforce_cpuid) { - error_setg(&local_err, - kvm_enabled() ? - "Host doesn't support requested features" : - "TCG doesn't support requested features"); - goto out; + if (x86_cpu_filter_features(cpu) && + (cpu->check_cpuid || cpu->enforce_cpuid)) { + x86_cpu_report_filtered_features(cpu); + if (cpu->enforce_cpuid) { + error_setg(&local_err, + kvm_enabled() ? + "Host doesn't support requested features" : + "TCG doesn't support requested features"); + goto out; + } } /* On AMD CPUs, some CPUID[8000_0001].EDX bits must match the bits on -- 2.7.4

Just move code to another place so the it can be reused by the query-cpu-definitions code. Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> --- target-i386/cpu.c | 68 +++++++++++++++++++++++++++---------------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 1a42233..a755309 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2071,6 +2071,40 @@ static void x86_cpu_parse_featurestr(const char *typename, char *features, } } +/* + * Filters CPU feature words based on host availability of each feature. + * + * Returns: 0 if all flags are supported by the host, non-zero otherwise. + */ +static int x86_cpu_filter_features(X86CPU *cpu) +{ + CPUX86State *env = &cpu->env; + FeatureWord w; + int rv = 0; + + for (w = 0; w < FEATURE_WORDS; w++) { + uint32_t host_feat = + x86_cpu_get_supported_feature_word(w, cpu->migratable); + uint32_t requested_features = env->features[w]; + env->features[w] &= host_feat; + cpu->filtered_features[w] = requested_features & ~env->features[w]; + if (cpu->filtered_features[w]) { + rv = 1; + } + } + + return rv; +} + +static void x86_cpu_report_filtered_features(X86CPU *cpu) +{ + FeatureWord w; + + for (w = 0; w < FEATURE_WORDS; w++) { + report_unavailable_features(w, cpu->filtered_features[w]); + } +} + /* Print all cpuid feature names in featureset */ static void listflags(FILE *f, fprintf_function print, const char **featureset) @@ -2200,40 +2234,6 @@ static uint32_t x86_cpu_get_supported_feature_word(FeatureWord w, return r; } -/* - * Filters CPU feature words based on host availability of each feature. - * - * Returns: 0 if all flags are supported by the host, non-zero otherwise. - */ -static int x86_cpu_filter_features(X86CPU *cpu) -{ - CPUX86State *env = &cpu->env; - FeatureWord w; - int rv = 0; - - for (w = 0; w < FEATURE_WORDS; w++) { - uint32_t host_feat = - x86_cpu_get_supported_feature_word(w, cpu->migratable); - uint32_t requested_features = env->features[w]; - env->features[w] &= host_feat; - cpu->filtered_features[w] = requested_features & ~env->features[w]; - if (cpu->filtered_features[w]) { - rv = 1; - } - } - - return rv; -} - -static void x86_cpu_report_filtered_features(X86CPU *cpu) -{ - FeatureWord w; - - for (w = 0; w < FEATURE_WORDS; w++) { - report_unavailable_features(w, cpu->filtered_features[w]); - } -} - static void x86_cpu_apply_props(X86CPU *cpu, PropValue *props) { PropValue *pv; -- 2.7.4

Add a new optional field to query-cpu-definitions schema: "unavailable-features". It will contain a list of QOM properties that prevent the CPU model from running in the current host. Cc: David Hildenbrand <dahi@linux.vnet.ibm.com> Cc: Michael Mueller <mimu@linux.vnet.ibm.com> Cc: Christian Borntraeger <borntraeger@de.ibm.com> Cc: Cornelia Huck <cornelia.huck@de.ibm.com> Cc: Jiri Denemark <jdenemar@redhat.com> Cc: libvir-list@redhat.com Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> --- Changes v2 -> v3: * Small documentation reword * Suggested-by: Markus Armbruster <armbru@redhat.com> Changes v1 -> v2: * Remove @runnable field, non-empty @unavailable-features is enough to report CPU model as not runnable. * Documentation updates: * Changed to "(since 2.7)"; * Add more details about the exact meaning of unavailable-features, and what it would mean to see read-only QOM properties in the list, and that implementations can return "type" if there's no extra information available; --- qapi-schema.json | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/qapi-schema.json b/qapi-schema.json index e507061..057c63d 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -3111,10 +3111,31 @@ # QEMU version, machine type, machine options and accelerator options. # A static model is always migration-safe. (since 2.8) # +# @unavailable-features: #optional List of properties that prevent +# the CPU model from running in the current +# host. (since 2.7) +# +# @unavailable-features is a list of QOM property names that +# represent CPU model attributes that prevent the CPU from running. +# If the QOM property is read-only, that means there's no known +# way to make the CPU model run in the current host. Implementations +# that choose not to provide specific information return the +# property name "type". +# If the property is read-write, it means that it MAY be possible +# to run the CPU model in the current host if that property is +# changed. Management software can use it as hints to suggest or +# choose an alternative for the user, or just to generate meaningful +# error messages explaining why the CPU model can't be used. +# If @unavailable-features is an empty list, the CPU model is +# runnable using the current host and machine-type. +# If @unavailable-features is not present, runnability +# information for the CPU is not available. +# # Since: 1.2.0 ## { 'struct': 'CpuDefinitionInfo', - 'data': { 'name': 'str', '*migration-safe': 'bool', 'static': 'bool' } } + 'data': { 'name': 'str', '*migration-safe': 'bool', 'static': 'bool', + '*unavailable-features': [ 'str' ] } } ## # @query-cpu-definitions: -- 2.7.4

On 09/19/2016 02:42 PM, Eduardo Habkost wrote:
Add a new optional field to query-cpu-definitions schema: "unavailable-features". It will contain a list of QOM properties that prevent the CPU model from running in the current host.
Cc: David Hildenbrand <dahi@linux.vnet.ibm.com> Cc: Michael Mueller <mimu@linux.vnet.ibm.com> Cc: Christian Borntraeger <borntraeger@de.ibm.com> Cc: Cornelia Huck <cornelia.huck@de.ibm.com> Cc: Jiri Denemark <jdenemar@redhat.com> Cc: libvir-list@redhat.com Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> ---
+++ b/qapi-schema.json @@ -3111,10 +3111,31 @@ # QEMU version, machine type, machine options and accelerator options. # A static model is always migration-safe. (since 2.8) # +# @unavailable-features: #optional List of properties that prevent +# the CPU model from running in the current +# host. (since 2.7)
We've missed 2.7; this should probably be 2.8. Otherwise reads okay to me; Reviewed-by: Eric Blake <eblake@redhat.com> -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On Tue, Sep 20, 2016 at 01:25:06PM -0500, Eric Blake wrote:
On 09/19/2016 02:42 PM, Eduardo Habkost wrote:
Add a new optional field to query-cpu-definitions schema: "unavailable-features". It will contain a list of QOM properties that prevent the CPU model from running in the current host.
Cc: David Hildenbrand <dahi@linux.vnet.ibm.com> Cc: Michael Mueller <mimu@linux.vnet.ibm.com> Cc: Christian Borntraeger <borntraeger@de.ibm.com> Cc: Cornelia Huck <cornelia.huck@de.ibm.com> Cc: Jiri Denemark <jdenemar@redhat.com> Cc: libvir-list@redhat.com Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> ---
+++ b/qapi-schema.json @@ -3111,10 +3111,31 @@ # QEMU version, machine type, machine options and accelerator options. # A static model is always migration-safe. (since 2.8) # +# @unavailable-features: #optional List of properties that prevent +# the CPU model from running in the current +# host. (since 2.7)
We've missed 2.7; this should probably be 2.8. Otherwise reads okay to me;
Reviewed-by: Eric Blake <eblake@redhat.com>
Oops! I will fix it before merging. Thanks for spotting! -- Eduardo

Fill the "unavailable-features" field on the x86 implementation of query-cpu-definitions. Cc: Jiri Denemark <jdenemar@redhat.com> Cc: libvir-list@redhat.com Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> --- Changes v2 -> v3: * Create a x86_cpu_feature_name() function, to isolate the code that returns the property name Changes v1 -> v2: * Updated to the new schema: no @runnable field, and always report @unavailable-features as present --- target-i386/cpu.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/target-i386/cpu.c b/target-i386/cpu.c index a755309..9b53ce5 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -1987,6 +1987,24 @@ static inline void feat2prop(char *s) } } +/* Return the feature property name for a feature flag bit */ +static char *x86_cpu_feature_name(FeatureWord w, int bitnr) +{ + char **parts, *r; + + /*TODO: This can be simplified later, by: + * 1) Moving the aliases outside the feat_names array + * (making g_strsplit() unnecessary) + * 2) Replacing "_" with "-" on all entries + * (making feat2prop() unnecessary) + */ + parts = g_strsplit(feature_word_info[w].feat_names[bitnr], "|", 2); + r = g_strdup(parts[0]); + feat2prop(r); + g_strfreev(parts); + return r; +} + /* Compatibily hack to maintain legacy +-feat semantic, * where +-feat overwrites any feature set by * feat=on|feat even if the later is parsed after +-feat @@ -2105,6 +2123,41 @@ static void x86_cpu_report_filtered_features(X86CPU *cpu) } } +/* Check for missing features that may prevent the CPU class from + * running using the current machine and accelerator. + */ +static void x86_cpu_class_check_missing_features(X86CPUClass *xcc, + strList **missing_feats) +{ + X86CPU *xc; + FeatureWord w; + + if (xcc->kvm_required && !kvm_enabled()) { + strList *new = g_new0(strList, 1); + new->value = g_strdup("kvm");; + *missing_feats = new; + return; + } + + xc = X86_CPU(object_new(object_class_get_name(OBJECT_CLASS(xcc)))); + if (x86_cpu_filter_features(xc)) { + for (w = 0; w < FEATURE_WORDS; w++) { + uint32_t filtered = xc->filtered_features[w]; + int i; + for (i = 0; i < 32; i++) { + if (filtered & (1UL << i)) { + strList *new = g_new0(strList, 1); + new->value = x86_cpu_feature_name(w, i); + new->next = *missing_feats; + *missing_feats = new; + } + } + } + } + + object_unref(OBJECT(xc)); +} + /* Print all cpuid feature names in featureset */ static void listflags(FILE *f, fprintf_function print, const char **featureset) @@ -2197,6 +2250,8 @@ static void x86_cpu_definition_entry(gpointer data, gpointer user_data) info = g_malloc0(sizeof(*info)); info->name = x86_cpu_class_get_model_name(cc); + x86_cpu_class_check_missing_features(cc, &info->unavailable_features); + info->has_unavailable_features = true; entry = g_malloc0(sizeof(*entry)); entry->value = info; -- 2.7.4

Hi, Your series failed automatic build test. Please find the testing commands and their output below. If you have docker installed, you can probably reproduce it locally. Subject: [libvirt] [PATCH v3 0/5] Add runnability info to query-cpu-definitions Message-id: 1474314175-24374-1-git-send-email-ehabkost@redhat.com Type: series === TEST SCRIPT BEGIN === #!/bin/bash set -e git submodule update --init dtc make J=8 docker-test-quick@centos6 make J=8 docker-test-mingw@fedora === TEST SCRIPT END === Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384 >From https://github.com/patchew-project/qemu * [new tag] patchew/1474314175-24374-1-git-send-email-ehabkost@redhat.com -> patchew/1474314175-24374-1-git-send-email-ehabkost@redhat.com * [new tag] patchew/c1a178ce-1c5e-2c26-0f55-6a4fbfe21a83@tuxfamily.org -> patchew/c1a178ce-1c5e-2c26-0f55-6a4fbfe21a83@tuxfamily.org Switched to a new branch 'test' 43f49c7 target-i386: Return runnability information on query-cpu-definitions 17a9434 qmp: Add runnability information to query-cpu-definitions 405e270 target-i386: Define CPUID filtering functions before x86_cpu_list() dc099e7 target-i386: Move warning code outside x86_cpu_filter_features() 21da10b target-i386: List CPU models using subclass list === OUTPUT BEGIN === Submodule 'dtc' (git://git.qemu-project.org/dtc.git) registered for path 'dtc' Cloning into 'dtc'... Submodule path 'dtc': checked out '65cc4d2748a2c2e6f27f1cf39e07a5dbabd80ebf' BUILD centos6 === OUTPUT END === Abort: command timeout (>3600 seconds) --- Email generated automatically by Patchew [http://patchew.org/]. Please send your feedback to patchew-devel@freelists.org
participants (3)
-
Eduardo Habkost
-
Eric Blake
-
no-reply@ec2-52-6-146-230.compute-1.amazonaws.com