summaryrefslogtreecommitdiff
path: root/include/hw/ppc/spapr.h
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2017-05-12 15:46:49 +1000
committerDavid Gibson <david@gibson.dropbear.id.au>2017-07-17 15:07:05 +1000
commit0b0b831016ae93bc14698a5d7202eb77feafea75 (patch)
treef4605882b421f4381a68eb9131e35711d6447f07 /include/hw/ppc/spapr.h
parent30f4b05bd090564181554d0890605eb2c143e4ea (diff)
downloadqemu-0b0b831016ae93bc14698a5d7202eb77feafea75.tar.gz
pseries: Implement HPT resizing
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>
Diffstat (limited to 'include/hw/ppc/spapr.h')
-rw-r--r--include/hw/ppc/spapr.h6
1 files changed, 6 insertions, 0 deletions
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 10ddb90711..3dd62d81f6 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -13,6 +13,7 @@ struct sPAPRPHBState;
struct sPAPRNVRAM;
typedef struct sPAPREventLogEntry sPAPREventLogEntry;
typedef struct sPAPREventSource sPAPREventSource;
+typedef struct sPAPRPendingHPT sPAPRPendingHPT;
#define HPTE64_V_HPTE_DIRTY 0x0000000000000040ULL
#define SPAPR_ENTRY_POINT 0x100
@@ -85,6 +86,8 @@ struct sPAPRMachineState {
void *htab;
uint32_t htab_shift;
uint64_t patb_entry; /* Process tbl registed in H_REGISTER_PROCESS_TABLE */
+ sPAPRPendingHPT *pending_hpt; /* in-progress resize */
+
hwaddr rma_size;
int vrma_adjust;
ssize_t rtas_size;
@@ -656,6 +659,7 @@ void spapr_hotplug_req_add_by_count_indexed(sPAPRDRConnectorType drc_type,
void spapr_hotplug_req_remove_by_count_indexed(sPAPRDRConnectorType drc_type,
uint32_t count, uint32_t index);
void spapr_cpu_parse_features(sPAPRMachineState *spapr);
+int spapr_hpt_shift_for_ramsize(uint64_t ramsize);
/* CPU and LMB DRC release callbacks. */
void spapr_core_release(DeviceState *dev);
@@ -696,4 +700,6 @@ int spapr_rng_populate_dt(void *fdt);
void spapr_do_system_reset_on_cpu(CPUState *cs, run_on_cpu_data arg);
+#define HTAB_SIZE(spapr) (1ULL << ((spapr)->htab_shift))
+
#endif /* HW_SPAPR_H */