[libvirt] [PATCH] Enable support for nested SVM
Jiri Denemark
jdenemar at redhat.com
Thu Sep 23 16:05:16 UTC 2010
> 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
More information about the libvir-list
mailing list