pseries: Don't allow duplicate registration of hcalls or RTAS calls
authorDavid Gibson <david@gibson.dropbear.id.au>
Mon, 8 Oct 2012 18:17:36 +0000 (18:17 +0000)
committerAlexander Graf <agraf@suse.de>
Mon, 29 Oct 2012 10:45:54 +0000 (11:45 +0100)
Currently the pseries machine code allows a callback to be registered
for a hypercall number twice, as long as it's the same callback the second
time.  We don't test for duplicate registrations of RTAS callbacks at all
so it will effectively be last registratiojn wins.

This was originally done because it was awkward to ensure that the
registration happened exactly once, but the code has since been
restructured so that's no longer the case.

Duplicate registration of a hypercall or RTAS call could well suggest
a duplicate initialization which could cause other problems, so this patch
makes duplicate registrations a bug, to prevent the old behaviour from
hiding other bugs.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
hw/spapr_hcall.c
hw/spapr_rtas.c

index 194d9c24b545b63e48b2a690112fe5eaf3d3a2a1..762493a0f722b608eb9da22f6d26a17a5af74308 100644 (file)
@@ -670,11 +670,10 @@ void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn)
     } else {
         assert((opcode >= KVMPPC_HCALL_BASE) && (opcode <= KVMPPC_HCALL_MAX));
 
-
         slot = &kvmppc_hypercall_table[opcode - KVMPPC_HCALL_BASE];
     }
 
-    assert(!(*slot) || (fn == *slot));
+    assert(!(*slot));
     *slot = fn;
 }
 
index 67da27ba51dcade40c9d5476bb75865e9f763b97..ce76c5856a9bd160de37c363e12d5ff1dc106b72 100644 (file)
@@ -241,6 +241,15 @@ target_ulong spapr_rtas_call(sPAPREnvironment *spapr,
 
 void spapr_rtas_register(const char *name, spapr_rtas_fn fn)
 {
+    int i;
+
+    for (i = 0; i < (rtas_next - rtas_table); i++) {
+        if (strcmp(name, rtas_table[i].name) == 0) {
+            fprintf(stderr, "RTAS call \"%s\" registered twice\n", name);
+            exit(1);
+        }
+    }
+
     assert(rtas_next < (rtas_table + TOKEN_MAX));
 
     rtas_next->name = name;