> diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c > index def6974..c7a282e 100644 > --- a/src/cpu/cpu.c > +++ b/src/cpu/cpu.c > @@ -424,3 +424,27 @@ cpuUpdate(virCPUDefPtr guest, > > return driver->update(guest, host); > } > + > +bool > +cpuHasFeature(const char *arch, > + const union cpuData *data, > + const char *feature) > +{ > + struct cpuArchDriver *driver; > + > + VIR_DEBUG("arch=%s, data=%p, feature=%s", > + arch, data, feature); > + > + if ((driver = cpuGetSubDriver(arch)) == NULL) > + return -1; > + > + if (driver->hasFeature == NULL) { > + virCPUReportError(VIR_ERR_NO_SUPPORT, > + _("cannot check guest CPU data for %s architecture"), > + arch); > + return -1; > + } > + > + return driver->hasFeature(arch, data, feature); No need to pass arch down here. > +} > + > diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h > index a745917..405af48 100644 > --- a/src/cpu/cpu.h > +++ b/src/cpu/cpu.h > @@ -82,6 +82,11 @@ typedef int > (*cpuArchUpdate) (virCPUDefPtr guest, > const virCPUDefPtr host); > > +typedef bool > +(*cpuArchHasFeature) (const char *arch, > + const union cpuData *data, > + const char *feature); > + The 'arch' argument is not needed here since cpuHasFeature already selected appropriate implementation according to CPU architecture. > struct cpuArchDriver { > const char *name; > @@ -95,6 +100,7 @@ struct cpuArchDriver { > cpuArchGuestData guestData; > cpuArchBaseline baseline; > cpuArchUpdate update; > + cpuArchHasFeature hasFeature; > }; > > > @@ -151,4 +157,10 @@ extern int > cpuUpdate (virCPUDefPtr guest, > const virCPUDefPtr host); > > +extern bool > +cpuHasFeature(const char *arch, > + const union cpuData *data, > + const char *feature); > + > + > #endif /* __VIR_CPU_H__ */ > diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c > index 1937901..cc82d58 100644 > --- a/src/cpu/cpu_x86.c > +++ b/src/cpu/cpu_x86.c > @@ -1754,6 +1754,55 @@ cleanup: > return ret; > } > > +static bool x86HasFeature(const char *arch ATTRIBUTE_UNUSED, > + const union cpuData *data, > + const char *name) No arch argument needed here as well. > +{ > + struct x86_map *map; > + struct x86_feature *feature; > + bool ret = false; > + int i; > + > + if (!(map = x86LoadMap())) > + return false; > + > + if (!(feature = x86FeatureFind(map, name))) > + goto cleanup; > + > + for (i = 0 ; i < data->x86.basic_len ; i++) { > + if (data->x86.basic[i].function == feature->cpuid->function && > + ((data->x86.basic[i].eax & feature->cpuid->eax) > + == feature->cpuid->eax) && > + ((data->x86.basic[i].ebx & feature->cpuid->ebx) > + == feature->cpuid->ebx) && > + ((data->x86.basic[i].ecx & feature->cpuid->ecx) > + == feature->cpuid->ecx) && > + ((data->x86.basic[i].edx & feature->cpuid->edx) > + == feature->cpuid->edx)) { > + ret = true; > + goto cleanup; > + } > + } > + > + for (i = 0 ; i < data->x86.extended_len ; i++) { > + if (data->x86.extended[i].function == feature->cpuid->function && > + ((data->x86.extended[i].eax & feature->cpuid->eax) > + == feature->cpuid->eax) && > + ((data->x86.extended[i].ebx & feature->cpuid->ebx) > + == feature->cpuid->ebx) && > + ((data->x86.extended[i].ecx & feature->cpuid->ecx) > + == feature->cpuid->ecx) && > + ((data->x86.extended[i].edx & feature->cpuid->edx) > + == feature->cpuid->edx)) { > + ret = true; > + goto cleanup; > + } > + } The two for loops should be replaced by the following single loop (which in practise will be walked through only once): for (i = 0; i < feature->ncpuid; i++) { struct cpuX86cpuid *cpuid; cpuid = x86DataCpuid(data, feature->cpuid[i].function); if (cpuid && x86cpuidMatchMasked(cpuid, feature->cpuid + i)) { ret = true; goto cleanup; } } > + > +cleanup: > + x86MapFree(map); > + return ret; > +} > > struct cpuArchDriver cpuDriverX86 = { > .name = "x86", > @@ -1771,4 +1820,5 @@ struct cpuArchDriver cpuDriverX86 = { > .guestData = x86GuestData, > .baseline = x86Baseline, > .update = x86Update, > + .hasFeature = x86HasFeature, > }; The current code would actually work so this is not a show stopper and the changes could be done as part of a bigger cleanup patch for cpu_x86.c that I have in my git tree. However I won't send the cleanup patch before I finish unit tests for all this to check the cleanup doesn't break anything. The rest looks fine. Jirka -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list