qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH] pseries: Add device tree properties for VMX/VSX


From: Alexander Graf
Subject: Re: [Qemu-devel] [PATCH] pseries: Add device tree properties for VMX/VSX and DFP under kvm
Date: Wed, 21 Sep 2011 09:53:22 +0200

On 21.09.2011, at 08:35, David Gibson wrote:

> Sufficiently recent PAPR specifications define properties "ibm,vmx"
> and "ibm,dfp" on the CPU node which advertise whether the VMX vector
> extensions (or the later VSX version) and/or the Decimal Floating
> Point operations from IBM's recent POWER CPUs are available.
> 
> Currently we do not put these in the guest device tree and the guest
> kernel will consequently assume they are not available.  This is good,
> because they are not supported under TCG.  VMX is similar enough to
> Altivec that it might be trivial to support, but VSX and DFP would
> both require significant work to support in TCG.
> 
> However, when running under kvm on a host which supports these
> instructions, there's no reason not to let the guest use them.  This
> patch, therefore, checks for the relevant support on the host CPU
> and, if present, advertises them to the guest as well.
> 
> Signed-off-by: David Gibson <address@hidden>
> ---
> hw/spapr.c           |   13 ++++++++++
> target-ppc/kvm.c     |   60 ++++++++++++++++++++++++++++++++++++++++++++++++++
> target-ppc/kvm_ppc.h |   12 ++++++++++
> 3 files changed, 85 insertions(+), 0 deletions(-)
> 
> diff --git a/hw/spapr.c b/hw/spapr.c
> index b118975..573392d 100644
> --- a/hw/spapr.c
> +++ b/hw/spapr.c
> @@ -168,6 +168,9 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
>                            0xffffffff, 0xffffffff};
>         uint32_t tbfreq = kvm_enabled() ? kvmppc_get_tbfreq() : TIMEBASE_FREQ;
>         uint32_t cpufreq = kvm_enabled() ? kvmppc_get_clockfreq() : 
> 1000000000;
> +        /* Currently TCG doesn't implement VMX or DFP instructions */
> +        uint32_t vmx = kvm_enabled() ? kvmppc_get_vmx() : 0;
> +        uint32_t dfp = kvm_enabled() ? kvmppc_get_dfp() : 0;

This should also take the target CPU into account. If the target CPU can't do 
VMX/DFP, it shouldn' be announced. Imagine running a guest with the 
compatibility mode bit set, so we're virtualization the previous generation.

When did dfp get introduced? Was that POWER6 or POWER7? Also, isn't there this 
twice-as-wide VMX extension too?

> 
>         if (asprintf(&nodename, "address@hidden", modelname, index) < 0) {
>             fprintf(stderr, "Allocation failure\n");
> @@ -202,6 +205,16 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
>                                segs, sizeof(segs))));
>         }
> 
> +        /* Advertise VMX/VSX (vector extensions) if available */
> +        if (vmx) {
> +            _FDT((fdt_property_cell(fdt, "ibm,vmx", vmx)));
> +        }
> +
> +        /* Advertise DFP (Decimal Floating Point) if available */
> +        if (dfp) {
> +            _FDT((fdt_property_cell(fdt, "ibm,dfp", dfp)));
> +        }
> +
>         _FDT((fdt_end_node(fdt)));
>     }
> 
> diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
> index 35a6f10..397a803 100644
> --- a/target-ppc/kvm.c
> +++ b/target-ppc/kvm.c
> @@ -673,6 +673,66 @@ uint64_t kvmppc_get_clockfreq(void)
>     return 0;
> }
> 
> +uint32_t kvmppc_get_vmx(void)
> +{
> +    char buf[512];
> +    uint32_t vmx;
> +    FILE *f;
> +    int len;
> +
> +    if (kvmppc_find_cpu_dt(buf, sizeof(buf))) {
> +        return 0;
> +    }
> +
> +    strncat(buf, "/ibm,vmx", sizeof(buf) - strlen(buf));
> +
> +    f = fopen(buf, "rb");
> +    if (!f) {
> +        /* Assume -ENOENT, which indicates that VMX is not available */
> +        return 0;
> +    }
> +
> +    len = fread(&vmx, sizeof(vmx), 1, f);
> +    fclose(f);
> +
> +    if (len != 1) {
> +        /* Malformed ibm,vmx property, assume no vmx or vsx */
> +        return 0;
> +    }
> +
> +    return be32_to_cpu(vmx);
> +}
> +
> +uint32_t kvmppc_get_dfp(void)
> +{
> +    char buf[512];
> +    uint32_t dfp;
> +    FILE *f;
> +    int len;
> +
> +    if (kvmppc_find_cpu_dt(buf, sizeof(buf))) {
> +        return 0;
> +    }
> +
> +    strncat(buf, "/ibm,dfp", sizeof(buf) - strlen(buf));
> +
> +    f = fopen(buf, "rb");
> +    if (!f) {
> +        /* Assume -ENOENT, which indicates that DFP is not available */
> +        return 0;
> +    }
> +
> +    len = fread(&dfp, sizeof(dfp), 1, f);
> +    fclose(f);
> +
> +    if (len != 1) {
> +        /* Malformed ibm,dfp property, assume no DFP */
> +        return 0;
> +    }
> +
> +    return be32_to_cpu(dfp);
> +}

Could you please fold those two into a single helper function to read out a 
32-bit dt property and then just use that? :)

Please also document somewhere in the code what the return value means (0 = 
unavailable, 1 = available).


Apart from that, nice patch!

Alex




reply via email to

[Prev in Thread] Current Thread [Next in Thread]