aboutsummaryrefslogtreecommitdiff
path: root/target/ppc/mmu-hash64.h
AgeCommit message (Collapse)Author
2019-02-26target/ppc: Support for POWER9 native hashBenjamin Herrenschmidt
(Might need more patch splitting) Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Cédric Le Goater <clg@kaod.org> Message-Id: <20190215170029.15641-12-clg@kaod.org> [dwg: Hack to fix compile with some earlier include tweaks of mine] Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-02-26target/ppc: Add basic support for "new format" HPTE as found on POWER9Benjamin Herrenschmidt
POWER9 (arch v3) slightly changes the HPTE format. The B bits move from the first to the second half of the HPTE, and the AVPN/ARPN are slightly shorter. However, under SPAPR, the hypercalls still take the old format (and probably will for the foreseable future). The simplest way to support this is thus to convert the HPTEs from new to old format when reading them if the MMU model is v3 and there is no virtual hypervisor, leaving the rest of the code unchanged. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Cédric Le Goater <clg@kaod.org> Message-Id: <20190215170029.15641-8-clg@kaod.org> [dwg: Moved function to .c since there was no real need for it in the .h] Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2018-06-22target/ppc: Add ppc_hash64_filter_pagesizes()David Gibson
The paravirtualized PAPR platform sometimes needs to restrict the guest to using only some of the page sizes actually supported by the host's MMU. At the moment this is handled in KVM specific code, but for consistency we want to apply the same limitations to all accelerators. This makes a start on this by providing a helper function in the cpu code to allow platform code to remove some of the cpu's page size definitions via a caller supplied callback. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Cédric Le Goater <clg@kaod.org> Reviewed-by: Greg Kurz <groug@kaod.org>
2018-05-04target/ppc: Add ppc_store_lpcr() helperDavid Gibson
There are some fields in the cpu state which need to be updated when the LPCR register is changed, which is done by ppc_hash64_update_rmls() and ppc_hash64_update_vrma(). Code which alters env->spr[SPR_LPCR] needs to call them afterwards to make sure the state is up to date. That's easy to get wrong. The normal way of dealing with sitautions like that is to use a helper which both updates the basic register value and the derived state. So, do that. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Cédric Le Goater <clg@kaod.org> Tested-by: Cédric Le Goater <clg@kaod.org> Reviewed-by: Greg Kurz <groug@kaod.org>
2018-05-04target/ppc: return a nil HPT base address on sPAPR machinesCédric Le Goater
commit e57ca75ce3b2 ("target/ppc: Manage external HPT via virtual hypervisor") exported a set of methods to manipulate the HPT from the core hash MMU. But SPR_SDR1 is still used under some circumstances to get the base address of the HPT, which is incorrect for the sPAPR machines. Only the logging should be impacted. Signed-off-by: Cédric Le Goater <clg@kaod.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2018-04-27target/ppc: Fold slb_nr into PPCHash64OptionsDavid Gibson
The env->slb_nr field gives the size of the SLB (Segment Lookaside Buffer). This is another static-after-initialization parameter of the specific version of the 64-bit hash MMU in the CPU. So, this patch folds the field into PPCHash64Options with the other hash MMU options. This is a bit more complicated that the things previously put in there, because slb_nr was foolishly included in the migration stream. So we need some of the usual dance to handle backwards compatible migration. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Greg Kurz <groug@kaod.org>
2018-04-27target/ppc: Fold ci_large_pages flag into PPCHash64OptionsDavid Gibson
The ci_large_pages boolean in CPUPPCState is only relevant to 64-bit hash MMU machines, indicating whether it's possible to map large (> 4kiB) pages as cache-inhibitied (i.e. for IO, rather than memory). Fold it as another flag into the PPCHash64Options structure. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Cédric Le Goater <clg@kaod.org> Reviewed-by: Greg Kurz <groug@kaod.org>
2018-04-27target/ppc: Move 1T segment and AMR options to PPCHash64OptionsDavid Gibson
Currently env->mmu_model is a bit of an unholy mess of an enum of distinct MMU types, with various flag bits as well. This makes which bits of the field should be compared pretty confusing. Make a start on cleaning that up by moving two of the flags bits - POWERPC_MMU_1TSEG and POWERPC_MMU_AMR - which are specific to the 64-bit hash MMU into a new flags field in PPCHash64Options structure. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Cédric Le Goater <clg@kaod.org> Reviewed-by: Greg Kurz <groug@kaod.org>
2018-04-27target/ppc: Make hash64_opts field mandatory for 64-bit hash MMUsDavid Gibson
Currently some cpus set the hash64_opts field in the class structure, with specific details of their variant of the 64-bit hash mmu. For the remaining cpus with that mmu, ppc_hash64_realize() fills in defaults. But there are only a couple of cpus that use those fallbacks, so just have them to set the has64_opts field instead, simplifying the logic. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Cédric Le Goater <clg@kaod.org> Reviewed-by: Greg Kurz <groug@kaod.org>
2018-04-27target/ppc: Split page size information into a separate allocationDavid Gibson
env->sps contains page size encoding information as an embedded structure. Since this information is specific to 64-bit hash MMUs, split it out into a separately allocated structure, to reduce the basic env size for other cpus. Along the way we make a few other cleanups: * Rename to PPCHash64Options which is more in line with qemu name conventions, and reflects that we're going to merge some more hash64 mmu specific details in there in future. Also rename its substructures to match qemu conventions. * Move structure definitions to the mmu-hash64.[ch] files. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Greg Kurz <groug@kaod.org> Reviewed-by: Cédric Le Goater <clg@kaod.org>
2018-04-27target/ppc: Move page size setup to helper functionDavid Gibson
Initialization of the env->sps structure at the end of instance_init is specific to the 64-bit hash MMU, so move the code into a helper function in mmu-hash64.c. We also create a corresponding function to be called at finalize time - it's empty for now, but we'll need it shortly. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Cédric Le Goater <clg@kaod.org> Reviewed-by: Greg Kurz <groug@kaod.org>
2018-04-27target/ppc: Avoid taking "env" parameter to mmu-hash64 functionsDavid Gibson
In most cases we prefer to pass a PowerPCCPU rather than the (embedded) CPUPPCState. For ppc_hash64_update_{rmls,vrma}() change to take "cpu" instead of "env". For ppc_hash64_set_{dsi,isi}() remove the redundant "env" parameter. In theory this makes more work for the functions, but since "cs", "cpu" and "env" are related by at most constant offsets, the compiler should be able to optimize out the difference at effectively zero cost. helper_*() functions are left alone - since they're more closely tied to the TCG generated code, passing "env" is still the standard there. While we're there, fix an incorrect indentation. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Greg Kurz <groug@kaod.org> Reviewed-by: Cédric Le Goater <clg@kaod.org>
2017-07-17pseries: Implement HPT resizingDavid Gibson
This patch implements hypercalls allowing a PAPR guest to resize its own hash page table. This will eventually allow for more flexible memory hotplug. The implementation is partially asynchronous, handled in a special thread running the hpt_prepare_thread() function. The state of a pending resize is stored in SPAPR_MACHINE->pending_hpt. The H_RESIZE_HPT_PREPARE hypercall will kick off creation of a new HPT, or, if one is already in progress, monitor it for completion. If there is an existing HPT resize in progress that doesn't match the size specified in the call, it will cancel it, replacing it with a new one matching the given size. The H_RESIZE_HPT_COMMIT completes transition to a resized HPT, and can only be called successfully once H_RESIZE_HPT_PREPARE has successfully completed initialization of a new HPT. The guest must ensure that there are no concurrent accesses to the existing HPT while this is called (this effectively means stop_machine() for Linux guests). For now H_RESIZE_HPT_COMMIT goes through the whole old HPT, rehashing each HPTE into the new HPT. This can have quite high latency, but it seems to be of the order of typical migration downtime latencies for HPTs of size up to ~2GiB (which would be used in a 256GiB guest). In future we probably want to move more of the rehashing to the "prepare" phase, by having H_ENTER and other hcalls update both current and pending HPTs. That's a project for another day, but should be possible without any changes to the guest interface. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2017-03-01target/ppc: Correct SDR1 maskingDavid Gibson
SDR_64_HTABORG, which indicates the bits of the SDR1 register to use for the base of a 64-bit machine's hashed page table (HPT) isn't correct. It includes the top 46 bits of the register, but in fact the top 4 bits must be zero (according to the ISA v2.07). No actual implementation has supported close to 2^60 bytes of physical address space, so it's kind of irrelevant, but we might as well correct this. In addition, although we checked for bad size values in SDR1, we never reported an error if entirely invalid bits were set there. Add this check to ppc_store_sdr1(). Reported-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2017-03-01target/ppc: Remove the function ppc_hash64_set_sdr1()Suraj Jitindar Singh
The function ppc_hash64_set_sdr1 basically checked the htabsize and set an error if it was too big, otherwise it just stored the value in SPR_SDR1. Given that the only function which calls ppc_hash64_set_sdr1() is ppc_store_sdr1(), why not handle the checking in ppc_store_sdr1() to avoid the extra function call. Note that ppc_store_sdr1() already stores the value in SPR_SDR1 anyway, so we were doing it twice. Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com> [dwg: Remove unnecessary error temporary] Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2017-03-01target/ppc: Manage external HPT via virtual hypervisorDavid Gibson
The pseries machine type implements the behaviour of a PAPR compliant hypervisor, without actually executing such a hypervisor on the virtual CPU. To do this we need some hooks in the CPU code to make hypervisor facilities get redirected to the machine instead of emulated internally. For hypercalls this is managed through the cpu->vhyp field, which points to a QOM interface with a method implementing the hypercall. For the hashed page table (HPT) - also a hypervisor resource - we use an older hack. CPUPPCState has an 'external_htab' field which when non-NULL indicates that the HPT is stored in qemu memory, rather than within the guest's address space. For consistency - and to make some future extensions easier - this merges the external HPT mechanism into the vhyp mechanism. Methods are added to vhyp for the basic operations the core hash MMU code needs: map_hptes() and unmap_hptes() for reading the HPT, store_hpte() for updating it and hpt_mask() to retrieve its size. To match this, the pseries machine now sets these vhyp fields in its existing vhyp class, rather than reaching into the cpu object to set the external_htab field. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
2017-03-01target/ppc: Eliminate htab_base and htab_mask variablesDavid Gibson
CPUPPCState includes fields htab_base and htab_mask which store the base address (GPA) and size (as a mask) of the guest's hashed page table (HPT). These are set when the SDR1 register is updated. Keeping these in sync with the SDR1 is actually a little bit fiddly, and probably not useful for performance, since keeping them expands the size of CPUPPCState. It also makes some upcoming changes harder to implement. This patch removes these fields, in favour of calculating them directly from the SDR1 contents when necessary. This does make a change to the behaviour of attempting to write a bad value (invalid HPT size) to the SDR1 with an mtspr instruction. Previously, the bad value would be stored in SDR1 and could be retrieved with a later mfspr, but the HPT size as used by the softmmu would be, clamped to the allowed values. Now, writing a bad value is treated as a no-op. An error message is printed in both new and old versions. I'm not sure which behaviour, if either, matches real hardware. I don't think it matters that much, since it's pretty clear that if an OS writes a bad value to SDR1, it's not going to boot. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru>
2017-03-01target/ppc: Cleanup HPTE accessors for 64-bit hash MMUDavid Gibson
Accesses to the hashed page table (HPT) are complicated by the fact that the HPT could be in one of three places: 1) Within guest memory - when we're emulating a full guest CPU at the hardware level (e.g. powernv, mac99, g3beige) 2) Within qemu, but outside guest memory - when we're emulating user and supervisor instructions within TCG, but instead of emulating the CPU's hypervisor mode, we just emulate a hypervisor's behaviour (pseries in TCG or KVM-PR) 3) Within the host kernel - a pseries machine using KVM-HV acceleration. Mostly accesses to the HPT are handled by KVM, but there are a few cases where qemu needs to access it via a special fd for the purpose. In order to batch accesses to the fd in case (3), we use a somewhat awkward ppc_hash64_start_access() / ppc_hash64_stop_access() pair, which for case (3) reads / releases several HPTEs from the kernel as a batch (usually a whole PTEG). For cases (1) & (2) it just returns an address value. The actual HPTE load helpers then need to interpret the returned token differently in the 3 cases. This patch keeps the same basic structure, but simplfiies the details. First start_access() / stop_access() are renamed to map_hptes() and unmap_hptes() to make their operation more obvious. Second, map_hptes() now always returns a qemu pointer, which can always be used in the same way by the load_hpte() helpers. In case (1) it comes from address_space_map() in case (2) directly from qemu's HPT buffer and in case (3) from a temporary buffer read from the KVM fd. While we're at it, make things a bit more consistent in terms of types and variable names: avoid variables named 'index' (it shadows index(3) which can lead to confusing results), use 'hwaddr ptex' for HPTE indices and uint64_t for each of the HPTE words, use ptex throughout the call stack instead of pte_offset in some places (we still need that at the bottom layer, but nowhere else). Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2017-03-01target/ppc: Fix KVM-HV HPTE accessorsDavid Gibson
When a 'pseries' guest is running with KVM-HV, the guest's hashed page table (HPT) is stored within the host kernel, so it is not directly accessible to qemu. Most of the time, qemu doesn't need to access it: we're using the hardware MMU, and KVM itself implements the guest hypercalls for manipulating the HPT. However, qemu does need access to the in-KVM HPT to implement get_phys_page_debug() for the benefit of the gdbstub, and maybe for other debug operations. To allow this, 7c43bca "target-ppc: Fix page table lookup with kvm enabled" added kvmppc_hash64_read_pteg() to target/ppc/kvm.c to read in a batch of HPTEs from the KVM table. Unfortunately, there are a couple of problems with this: First, the name of the function implies it always reads a whole PTEG from the HPT, but in fact in some cases it's used to grab individual HPTEs (which ends up pulling 8 HPTEs, not aligned to a PTEG from the kernel). Second, and more importantly, the code to read the HPTEs from KVM is simply wrong, in general. The data from the fd that KVM provides is designed mostly for compact migration rather than this sort of one-off access, and so needs some decoding for this purpose. The current code will work in some cases, but if there are invalid HPTEs then it will not get sane results. This patch rewrite the HPTE reading function to have a simpler interface (just read n HPTEs into a caller provided buffer), and to correctly decode the stream from the kernel. For consistency we also clean up the similar function for altering HPTEs within KVM (introduced in c138593 "target-ppc: Update ppc_hash64_store_hpte to support updating in-kernel htab"). Cc: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2017-02-02target/ppc/mmu_hash64: Fix incorrect shift value in amr calculationSuraj Jitindar Singh
We are calculating the authority mask register key value wrong. The pte entry contains the key value with the two upper bits and the three lower bits stored separately. We should use these two portions to get a 5 bit value, not or them together which will only give us a 3 bit value. Fix this. Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2016-12-20Move target-* CPU file into a target/ folderThomas Huth
We've currently got 18 architectures in QEMU, and thus 18 target-xxx folders in the root folder of the QEMU source tree. More architectures (e.g. RISC-V, AVR) are likely to be included soon, too, so the main folder of the QEMU sources slowly gets quite overcrowded with the target-xxx folders. To disburden the main folder a little bit, let's move the target-xxx folders into a dedicated target/ folder, so that target-xxx/ simply becomes target/xxx/ instead. Acked-by: Laurent Vivier <laurent@vivier.eu> [m68k part] Acked-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de> [tricore part] Acked-by: Michael Walle <michael@walle.cc> [lm32 part] Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com> [s390x part] Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com> [s390x part] Acked-by: Eduardo Habkost <ehabkost@redhat.com> [i386 part] Acked-by: Artyom Tarasenko <atar4qemu@gmail.com> [sparc part] Acked-by: Richard Henderson <rth@twiddle.net> [alpha part] Acked-by: Max Filippov <jcmvbkbc@gmail.com> [xtensa part] Reviewed-by: David Gibson <david@gibson.dropbear.id.au> [ppc part] Acked-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> [cris&microblaze part] Acked-by: Guan Xuetao <gxt@mprc.pku.edu.cn> [unicore32 part] Signed-off-by: Thomas Huth <thuth@redhat.com>