[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 48/58] pseries: Implement hcall-bulk hypervisor inte
From: |
Alexander Graf |
Subject: |
[Qemu-devel] [PATCH 48/58] pseries: Implement hcall-bulk hypervisor interface |
Date: |
Wed, 14 Sep 2011 10:43:12 +0200 |
From: David Gibson <address@hidden>
This patch adds support for the H_REMOVE_BULK hypercall on the pseries
machine. Strictly speaking this isn't necessarym since the kernel will
only attempt to use this if hcall-bulk is advertised in the device tree,
which previously it was not.
Adding this support may give a marginal performance increase, but more
importantly it reduces the differences between the emulated machine and
an existing PowerVM or kvm system, both of which already implement
hcall-bulk.
Signed-off-by: David Gibson <address@hidden>
Signed-off-by: Alexander Graf <address@hidden>
---
hw/spapr.c | 2 +-
hw/spapr_hcall.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 114 insertions(+), 13 deletions(-)
diff --git a/hw/spapr.c b/hw/spapr.c
index 91953cf..deb4ae5 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -75,7 +75,7 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
uint32_t end_prop = cpu_to_be32(initrd_base + initrd_size);
uint32_t pft_size_prop[] = {0, cpu_to_be32(hash_shift)};
char hypertas_prop[] = "hcall-pft\0hcall-term\0hcall-dabr\0hcall-interrupt"
- "\0hcall-tce\0hcall-vio\0hcall-splpar";
+ "\0hcall-tce\0hcall-vio\0hcall-splpar\0hcall-bulk";
uint32_t interrupt_server_ranges_prop[] = {0, cpu_to_be32(smp_cpus)};
int i;
char *modelname;
diff --git a/hw/spapr_hcall.c b/hw/spapr_hcall.c
index 0c61c10..84281be 100644
--- a/hw/spapr_hcall.c
+++ b/hw/spapr_hcall.c
@@ -174,20 +174,26 @@ static target_ulong h_enter(CPUState *env,
sPAPREnvironment *spapr,
return H_SUCCESS;
}
-static target_ulong h_remove(CPUState *env, sPAPREnvironment *spapr,
- target_ulong opcode, target_ulong *args)
+enum {
+ REMOVE_SUCCESS = 0,
+ REMOVE_NOT_FOUND = 1,
+ REMOVE_PARM = 2,
+ REMOVE_HW = 3,
+};
+
+static target_ulong remove_hpte(CPUState *env, target_ulong ptex,
+ target_ulong avpn,
+ target_ulong flags,
+ target_ulong *vp, target_ulong *rp)
{
- target_ulong flags = args[0];
- target_ulong pte_index = args[1];
- target_ulong avpn = args[2];
uint8_t *hpte;
target_ulong v, r, rb;
- if ((pte_index * HASH_PTE_SIZE_64) & ~env->htab_mask) {
- return H_PARAMETER;
+ if ((ptex * HASH_PTE_SIZE_64) & ~env->htab_mask) {
+ return REMOVE_PARM;
}
- hpte = env->external_htab + (pte_index * HASH_PTE_SIZE_64);
+ hpte = env->external_htab + (ptex * HASH_PTE_SIZE_64);
while (!lock_hpte(hpte, HPTE_V_HVLOCK)) {
/* We have no real concurrency in qemu soft-emulation, so we
* will never actually have a contested lock */
@@ -202,14 +208,106 @@ static target_ulong h_remove(CPUState *env,
sPAPREnvironment *spapr,
((flags & H_ANDCOND) && (v & avpn) != 0)) {
stq_p(hpte, v & ~HPTE_V_HVLOCK);
assert(!(ldq_p(hpte) & HPTE_V_HVLOCK));
- return H_NOT_FOUND;
+ return REMOVE_NOT_FOUND;
}
- args[0] = v & ~HPTE_V_HVLOCK;
- args[1] = r;
+ *vp = v & ~HPTE_V_HVLOCK;
+ *rp = r;
stq_p(hpte, 0);
- rb = compute_tlbie_rb(v, r, pte_index);
+ rb = compute_tlbie_rb(v, r, ptex);
ppc_tlb_invalidate_one(env, rb);
assert(!(ldq_p(hpte) & HPTE_V_HVLOCK));
+ return REMOVE_SUCCESS;
+}
+
+static target_ulong h_remove(CPUState *env, sPAPREnvironment *spapr,
+ target_ulong opcode, target_ulong *args)
+{
+ target_ulong flags = args[0];
+ target_ulong pte_index = args[1];
+ target_ulong avpn = args[2];
+ int ret;
+
+ ret = remove_hpte(env, pte_index, avpn, flags,
+ &args[0], &args[1]);
+
+ switch (ret) {
+ case REMOVE_SUCCESS:
+ return H_SUCCESS;
+
+ case REMOVE_NOT_FOUND:
+ return H_NOT_FOUND;
+
+ case REMOVE_PARM:
+ return H_PARAMETER;
+
+ case REMOVE_HW:
+ return H_HARDWARE;
+ }
+
+ assert(0);
+}
+
+#define H_BULK_REMOVE_TYPE 0xc000000000000000ULL
+#define H_BULK_REMOVE_REQUEST 0x4000000000000000ULL
+#define H_BULK_REMOVE_RESPONSE 0x8000000000000000ULL
+#define H_BULK_REMOVE_END 0xc000000000000000ULL
+#define H_BULK_REMOVE_CODE 0x3000000000000000ULL
+#define H_BULK_REMOVE_SUCCESS 0x0000000000000000ULL
+#define H_BULK_REMOVE_NOT_FOUND 0x1000000000000000ULL
+#define H_BULK_REMOVE_PARM 0x2000000000000000ULL
+#define H_BULK_REMOVE_HW 0x3000000000000000ULL
+#define H_BULK_REMOVE_RC 0x0c00000000000000ULL
+#define H_BULK_REMOVE_FLAGS 0x0300000000000000ULL
+#define H_BULK_REMOVE_ABSOLUTE 0x0000000000000000ULL
+#define H_BULK_REMOVE_ANDCOND 0x0100000000000000ULL
+#define H_BULK_REMOVE_AVPN 0x0200000000000000ULL
+#define H_BULK_REMOVE_PTEX 0x00ffffffffffffffULL
+
+#define H_BULK_REMOVE_MAX_BATCH 4
+
+static target_ulong h_bulk_remove(CPUState *env, sPAPREnvironment *spapr,
+ target_ulong opcode, target_ulong *args)
+{
+ int i;
+
+ for (i = 0; i < H_BULK_REMOVE_MAX_BATCH; i++) {
+ target_ulong *tsh = &args[i*2];
+ target_ulong tsl = args[i*2 + 1];
+ target_ulong v, r, ret;
+
+ if ((*tsh & H_BULK_REMOVE_TYPE) == H_BULK_REMOVE_END) {
+ break;
+ } else if ((*tsh & H_BULK_REMOVE_TYPE) != H_BULK_REMOVE_REQUEST) {
+ return H_PARAMETER;
+ }
+
+ *tsh &= H_BULK_REMOVE_PTEX | H_BULK_REMOVE_FLAGS;
+ *tsh |= H_BULK_REMOVE_RESPONSE;
+
+ if ((*tsh & H_BULK_REMOVE_ANDCOND) && (*tsh & H_BULK_REMOVE_AVPN)) {
+ *tsh |= H_BULK_REMOVE_PARM;
+ return H_PARAMETER;
+ }
+
+ ret = remove_hpte(env, *tsh & H_BULK_REMOVE_PTEX, tsl,
+ (*tsh & H_BULK_REMOVE_FLAGS) >> 26,
+ &v, &r);
+
+ *tsh |= ret << 60;
+
+ switch (ret) {
+ case REMOVE_SUCCESS:
+ *tsh |= (r & (HPTE_R_C | HPTE_R_R)) << 43;
+ break;
+
+ case REMOVE_PARM:
+ return H_PARAMETER;
+
+ case REMOVE_HW:
+ return H_HARDWARE;
+ }
+ }
+
return H_SUCCESS;
}
@@ -581,6 +679,9 @@ static void hypercall_init(void)
spapr_register_hypercall(H_REMOVE, h_remove);
spapr_register_hypercall(H_PROTECT, h_protect);
+ /* hcall-bulk */
+ spapr_register_hypercall(H_BULK_REMOVE, h_bulk_remove);
+
/* hcall-dabr */
spapr_register_hypercall(H_SET_DABR, h_set_dabr);
--
1.6.0.2
- [Qemu-devel] [PATCH 14/58] device tree: add nop_node, (continued)
- [Qemu-devel] [PATCH 14/58] device tree: add nop_node, Alexander Graf, 2011/09/14
- [Qemu-devel] [PATCH 38/58] pseries: interrupt controller should not have a 'reg' property, Alexander Graf, 2011/09/14
- [Qemu-devel] [PATCH 49/58] vscsi: send the CHECK_CONDITION status down together with autosense data, Alexander Graf, 2011/09/14
- [Qemu-devel] [PATCH 20/58] PPC: KVM: Remove kvmppc_read_host_property, Alexander Graf, 2011/09/14
- [Qemu-devel] [PATCH 40/58] PPC: Fix sync instructions problem in SMP, Alexander Graf, 2011/09/14
- [Qemu-devel] [PATCH 18/58] PPC: E500: Remove mpc8544_copy_soc_cell, Alexander Graf, 2011/09/14
- [Qemu-devel] [PATCH 02/58] spapr: prepare for qdevification of irq, Alexander Graf, 2011/09/14
- [Qemu-devel] [PATCH 17/58] PPC: E500: Use generic kvm function for freq, Alexander Graf, 2011/09/14
- [Qemu-devel] [PATCH 48/58] pseries: Implement hcall-bulk hypervisor interface,
Alexander Graf <=
- [Qemu-devel] [PATCH 50/58] pseries: Update SLOF firmware image, Alexander Graf, 2011/09/14
- Re: [Qemu-devel] [PATCH 50/58] pseries: Update SLOF firmware image, Peter Maydell, 2011/09/14
- Re: [Qemu-devel] [PATCH 50/58] pseries: Update SLOF firmware image, Alexander Graf, 2011/09/14
- Re: [Qemu-devel] [PATCH 50/58] pseries: Update SLOF firmware image, Peter Maydell, 2011/09/14
- Re: [Qemu-devel] [PATCH 50/58] pseries: Update SLOF firmware image, Anthony Liguori, 2011/09/14
- Re: [Qemu-devel] [PATCH 50/58] pseries: Update SLOF firmware image, Blue Swirl, 2011/09/14
- Re: [Qemu-devel] [PATCH 50/58] pseries: Update SLOF firmware image, Alexander Graf, 2011/09/19
- Re: [Qemu-devel] [Qemu-ppc] [PATCH 50/58] pseries: Update SLOF firmware image, David Gibson, 2011/09/20
- Re: [Qemu-devel] [Qemu-ppc] [PATCH 50/58] pseries: Update SLOF firmware image, Paolo Bonzini, 2011/09/24
- Re: [Qemu-devel] [Qemu-ppc] [PATCH 50/58] pseries: Update SLOF firmware image, David Gibson, 2011/09/26