All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alexey Kardashevskiy <aik@ozlabs.ru>
To: Alexander Graf <agraf@suse.de>, qemu-devel@nongnu.org
Cc: qemu-ppc@nongnu.org
Subject: Re: [Qemu-devel] [PATCH v2 8/9] spapr: Implement processor compatibility in ibm, client-architecture-support
Date: Wed, 21 May 2014 19:36:57 +1000	[thread overview]
Message-ID: <537C73B9.9060803@ozlabs.ru> (raw)
In-Reply-To: <537C7002.5090100@suse.de>

On 05/21/2014 07:21 PM, Alexander Graf wrote:
> 
> On 21.05.14 10:27, Alexey Kardashevskiy wrote:
>> Modern Linux kernels support last POWERPC CPUs so when a kernel boots,
>> in most cases it can find a matching cpu_spec in the kernel's cpu_specs
>> list. However if the kernel is quite old, it may be missing a definition
>> of the actual CPU. To provide an ability for old kernels to work on modern
>> hardware, a Processor Compatibility Mode has been introduced
>> by the PowerISA specification.
>>
>>  From the hardware prospective, it is supported by the Processor
>> Compatibility Register (PCR) which is defined in PowerISA. The register
>> enables one of the compatibility modes (2.05/2.06/2.07).
>> Since PCR is a hypervisor privileged register and cannot be
>> directly accessed from the guest, the mode selection is done via
>> ibm,client-architecture-support (CAS) RTAS call using which the guest
>> specifies what "raw" and "architected" CPU versions it supports.
>> QEMU works out the best match, changes a "cpu-version" property of
>> every CPU and notifies the guest about the change by setting these
>> properties in the buffer passed as a response on a custom H_CAS hypercall.
>>
>> This implements ibm,client-architecture-support parameters parsing
>> (now only for PVRs) and cooks the device tree diff with new values for
>> "cpu-version", "ibm,ppc-interrupt-server#s" and
>> "ibm,ppc-interrupt-server#s" properties.
>>
>> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
>> ---
>>   hw/ppc/spapr.c       |  4 ++-
>>   hw/ppc/spapr_hcall.c | 85
>> ++++++++++++++++++++++++++++++++++++++++++++++++++++
>>   trace-events         |  4 +++
>>   3 files changed, 92 insertions(+), 1 deletion(-)
>>
>> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
>> index 14c72d9..020426a 100644
>> --- a/hw/ppc/spapr.c
>> +++ b/hw/ppc/spapr.c
>> @@ -34,6 +34,7 @@
>>   #include "sysemu/kvm.h"
>>   #include "kvm_ppc.h"
>>   #include "mmu-hash64.h"
>> +#include "qom/cpu.h"
>>     #include "hw/boards.h"
>>   #include "hw/ppc/ppc.h"
>> @@ -601,7 +602,8 @@ int spapr_h_cas_compose_response(target_ulong addr,
>> target_ulong size)
>>       _FDT((fdt_open_into(fdt_skel, fdt, size)));
>>       g_free(fdt_skel);
>>   -    /* Place to make changes to the tree */
>> +    /* Fix skeleton up */
>> +    _FDT((spapr_fixup_cpu_dt(fdt, spapr)));
>>         /* Pack resulting tree */
>>       _FDT((fdt_pack(fdt)));
>> diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
>> index 2f6aa5c..2e0a49c 100644
>> --- a/hw/ppc/spapr_hcall.c
>> +++ b/hw/ppc/spapr_hcall.c
>> @@ -3,6 +3,9 @@
>>   #include "helper_regs.h"
>>   #include "hw/ppc/spapr.h"
>>   #include "mmu-hash64.h"
>> +#include "cpu-models.h"
>> +#include "trace.h"
>> +#include "kvm_ppc.h"
>>     struct SPRSyncState {
>>       CPUState *cs;
>> @@ -752,12 +755,94 @@ out:
>>       return ret;
>>   }
>>   +#define get_compat_level(cpuver) ( \
>> +    ((cpuver) == CPU_POWERPC_LOGICAL_2_05) ? 2050 : \
>> +    ((cpuver) == CPU_POWERPC_LOGICAL_2_06) ? 2060 : \
>> +    ((cpuver) == CPU_POWERPC_LOGICAL_2_06_PLUS) ? 2061 : \
>> +    ((cpuver) == CPU_POWERPC_LOGICAL_2_07) ? 2070 : 0)
>> +
>>   static target_ulong h_client_architecture_support(PowerPCCPU *cpu_,
>>                                                     sPAPREnvironment *spapr,
>>                                                     target_ulong opcode,
>>                                                     target_ulong *args)
>>   {
>>       target_ulong list = args[0];
>> +    PowerPCCPUClass *pcc_ = POWERPC_CPU_GET_CLASS(cpu_);
>> +    CPUState *cs;
>> +    bool cpu_match = false;
>> +    unsigned old_cpu_version = cpu_->cpu_version;
>> +    unsigned compat_lvl = 0, cpu_version = 0;
>> +    unsigned max_lvl = get_compat_level(cpu_->max_compat);
>> +
>> +    /* Parse PVR list */
>> +    for ( ; ; ) {
>> +        uint32_t pvr, pvr_mask;
>> +
>> +        pvr_mask = rtas_ld(list, 0);
>> +        list += 4;
>> +        pvr = rtas_ld(list, 0);
>> +        list += 4;
>> +
>> +        trace_spapr_cas_pvr_try(pvr);
>> +        if (!max_lvl &&
>> +            ((cpu_->env.spr[SPR_PVR] & pvr_mask) == (pvr & pvr_mask))) {
>> +            cpu_match = true;
>> +            cpu_version = 0;
>> +        } else if (pvr == cpu_->cpu_version) {
>> +            cpu_match = true;
>> +            cpu_version = cpu_->cpu_version;
>> +        } else if (!cpu_match) {
>> +            /* If it is a logical PVR, try to determine the highest
>> level */
>> +            unsigned lvl = get_compat_level(pvr);
>> +            if (lvl) {
>> +                bool is205 = (pcc_->pcr_mask & PCR_COMPAT_2_05) &&
>> +                     (lvl == get_compat_level(CPU_POWERPC_LOGICAL_2_05));
>> +                bool is206 = (pcc_->pcr_mask & PCR_COMPAT_2_06) &&
>> +                    ((lvl == get_compat_level(CPU_POWERPC_LOGICAL_2_06)) ||
>> +                    (lvl ==
>> get_compat_level(CPU_POWERPC_LOGICAL_2_06_PLUS)));
>> +
>> +                if (is205 || is206) {
>> +                    if (!max_lvl) {
>> +                        /* User did not set the level, choose the
>> highest */
>> +                        if (compat_lvl <= lvl) {
>> +                            compat_lvl = lvl;
>> +                            cpu_version = pvr;
>> +                        }
>> +                    } else if (max_lvl >= lvl) {
>> +                        /* User chose the level, don't set higher than
>> this */
>> +                        compat_lvl = lvl;
>> +                        cpu_version = pvr;
>> +                    }
>> +                }
>> +            }
>> +        }
>> +        /* Terminator record */
>> +        if (~pvr_mask & pvr) {
> 
> This loop can be used by the guest to stall QEMU for a long period of time,
> no? Better add a safety net check somewhere to allow for early abort.

Like what? No more than 64 PVRs would be enough?



>> +            break;
>> +        }
>> +    }
>> +
>> +    /* For the future use: here @list points to the first capability */
>> +
>> +    /* Parsing finished */
>> +    trace_spapr_cas_pvr(cpu_->cpu_version, cpu_match,
>> +                        cpu_version, pcc_->pcr_mask);
>> +
>> +    /* Update CPUs */
>> +    if (old_cpu_version != cpu_version) {
>> +        CPU_FOREACH(cs) {
>> +            PowerPCCPU *cpu = POWERPC_CPU(cs);
>> +
>> +            if (ppc_set_compat(cpu, cpu_version) < 0) {
> 
> Please run the updates on the vcpu threads themselves.

Ouch. Forgot. Sorry :(


-- 
Alexey

  reply	other threads:[~2014-05-21  9:37 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-05-21  8:27 [Qemu-devel] [PATCH v2 0/9] spapr: Enable ibm, client-architecture-support Alexey Kardashevskiy
2014-05-21  8:27 ` [Qemu-devel] [PATCH v2 1/9] target-ppc: Add "compat" CPU option Alexey Kardashevskiy
2014-05-21  8:27 ` [Qemu-devel] [PATCH v2 2/9] spapr: Move SMT-related properties out of skeleton fdt Alexey Kardashevskiy
2014-05-21  8:27 ` [Qemu-devel] [PATCH v2 3/9] target-ppc: Implement "compat" CPU option Alexey Kardashevskiy
2014-05-21  8:27 ` [Qemu-devel] [PATCH v2 4/9] target-ppc: Define Processor Compatibility Masks Alexey Kardashevskiy
2014-05-21  8:27 ` [Qemu-devel] [PATCH v2 5/9] spapr: Add ibm, client-architecture-support call Alexey Kardashevskiy
2014-05-21  8:27 ` [Qemu-devel] [PATCH v2 6/9] spapr: Rework spapr_fixup_cpu_dt() Alexey Kardashevskiy
2014-05-21  8:27 ` [Qemu-devel] [PATCH v2 7/9] spapr: Limit threads per core according to current compatibility mode Alexey Kardashevskiy
2014-05-21  8:27 ` [Qemu-devel] [PATCH v2 8/9] spapr: Implement processor compatibility in ibm, client-architecture-support Alexey Kardashevskiy
2014-05-21  9:21   ` Alexander Graf
2014-05-21  9:36     ` Alexey Kardashevskiy [this message]
2014-05-21  9:57       ` Alexander Graf
2014-05-21  8:27 ` [Qemu-devel] [PATCH v2 9/9] KVM: PPC: Enable compatibility mode Alexey Kardashevskiy
2014-05-21  8:44 ` [Qemu-devel] [PATCH v2 0/9] spapr: Enable ibm, client-architecture-support Alexander Graf

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=537C73B9.9060803@ozlabs.ru \
    --to=aik@ozlabs.ru \
    --cc=agraf@suse.de \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.