Patchwork [11/12] spapr-vio: pass type to spapr_vio_find_by_reg()

login
register
mail settings
Submitter Anthony Liguori
Date June 19, 2013, 8:40 p.m.
Message ID <1371674435-14973-12-git-send-email-aliguori@us.ibm.com>
Download mbox | patch
Permalink /patch/252662/
State New
Headers show

Comments

Anthony Liguori - June 19, 2013, 8:40 p.m.
Today if an invalid hcall is made to an otherwise valid device we
abort due to QOM casting.  This adds a parameter to find_by_reg()
to indicate which type of device we're looking for.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/char/spapr_vty.c        | 14 ++++----------
 hw/net/spapr_llan.c        | 15 ++++++++++-----
 hw/ppc/spapr_vio.c         | 24 +++++++++++++++---------
 include/hw/ppc/spapr_vio.h |  3 ++-
 4 files changed, 31 insertions(+), 25 deletions(-)
Alexander Graf - June 19, 2013, 9:38 p.m.
On 19.06.2013, at 22:40, Anthony Liguori wrote:

> Today if an invalid hcall is made to an otherwise valid device we
> abort due to QOM casting.  This adds a parameter to find_by_reg()
> to indicate which type of device we're looking for.

This should also adjust the hack to only match reg=0 for TYPE_VIO_SPAPR_VTY_DEVICE, no?


Alex
Anthony Liguori - June 19, 2013, 9:56 p.m.
Alexander Graf <agraf@suse.de> writes:

> On 19.06.2013, at 22:40, Anthony Liguori wrote:
>
>> Today if an invalid hcall is made to an otherwise valid device we
>> abort due to QOM casting.  This adds a parameter to find_by_reg()
>> to indicate which type of device we're looking for.
>
> This should also adjust the hack to only match reg=0 for
> TYPE_VIO_SPAPR_VTY_DEVICE, no?

Yup, that'll result in a bad cast otherwise.  Nice catch.

I'll respin.

Regards,

Anthony Liguori

>
>
> Alex

Patch

diff --git a/hw/char/spapr_vty.c b/hw/char/spapr_vty.c
index bbd5ecb..aa56f10 100644
--- a/hw/char/spapr_vty.c
+++ b/hw/char/spapr_vty.c
@@ -94,15 +94,12 @@  static target_ulong h_put_term_char(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     uint8_t buf[16];
     int i;
 
-    sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+    sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg,
+                                 TYPE_VIO_SPAPR_VTY_DEVICE);
     if (!sdev) {
         return H_PARAMETER;
     }
 
-    if (!object_dynamic_cast(OBJECT(sdev), TYPE_VIO_SPAPR_VTY_DEVICE)) {
-        return H_PARAMETER;
-    }
-
     if (len > 16) {
         return H_PARAMETER;
     }
@@ -128,15 +125,12 @@  static target_ulong h_get_term_char(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     uint8_t buf[16];
     int i;
 
-    sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+    sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg,
+                                 TYPE_VIO_SPAPR_VTY_DEVICE);
     if (!sdev) {
         return H_PARAMETER;
     }
 
-    if (!object_dynamic_cast(OBJECT(sdev), TYPE_VIO_SPAPR_VTY_DEVICE)) {
-        return H_PARAMETER;
-    }
-
     len = spapr_vty_getchars(VIO_SPAPR_VTY_DEVICE(sdev), buf, sizeof(buf));
 
     args[0] = len;
diff --git a/hw/net/spapr_llan.c b/hw/net/spapr_llan.c
index 03a09f2..429d020 100644
--- a/hw/net/spapr_llan.c
+++ b/hw/net/spapr_llan.c
@@ -285,7 +285,8 @@  static target_ulong h_register_logical_lan(PowerPCCPU *cpu,
     target_ulong buf_list = args[1];
     target_ulong rec_queue = args[2];
     target_ulong filter_list = args[3];
-    VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+    VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg,
+                                                 TYPE_VIO_SPAPR_VLAN_DEVICE);
     VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
     vlan_bd_t filter_list_bd;
 
@@ -346,7 +347,8 @@  static target_ulong h_free_logical_lan(PowerPCCPU *cpu, sPAPREnvironment *spapr,
                                        target_ulong opcode, target_ulong *args)
 {
     target_ulong reg = args[0];
-    VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+    VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg,
+                                                 TYPE_VIO_SPAPR_VLAN_DEVICE);
     VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
 
     if (!dev) {
@@ -370,7 +372,8 @@  static target_ulong h_add_logical_lan_buffer(PowerPCCPU *cpu,
 {
     target_ulong reg = args[0];
     target_ulong buf = args[1];
-    VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+    VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg,
+                                                 TYPE_VIO_SPAPR_VLAN_DEVICE);
     VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
     vlan_bd_t bd;
 
@@ -418,7 +421,8 @@  static target_ulong h_send_logical_lan(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     target_ulong reg = args[0];
     target_ulong *bufs = args + 1;
     target_ulong continue_token = args[7];
-    VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+    VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg,
+                                                 TYPE_VIO_SPAPR_VLAN_DEVICE);
     VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
     unsigned total_len;
     uint8_t *lbuf, *p;
@@ -485,7 +489,8 @@  static target_ulong h_multicast_ctrl(PowerPCCPU *cpu, sPAPREnvironment *spapr,
                                      target_ulong opcode, target_ulong *args)
 {
     target_ulong reg = args[0];
-    VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+    VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg,
+                                                 TYPE_VIO_SPAPR_VLAN_DEVICE);
 
     if (!dev) {
         return H_PARAMETER;
diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c
index ee99eec..b4ef48b 100644
--- a/hw/ppc/spapr_vio.c
+++ b/hw/ppc/spapr_vio.c
@@ -114,7 +114,8 @@  static VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus)
     return selected;
 }
 
-VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg)
+VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg,
+                                      const char *typename)
 {
     BusChild *kid;
     VIOsPAPRDevice *dev = NULL;
@@ -129,8 +130,8 @@  VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg)
     }
 
     QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
-        dev = (VIOsPAPRDevice *)kid->child;
-        if (dev->reg == reg) {
+        dev = VIO_SPAPR_DEVICE(kid->child);
+        if (dev->reg == reg && object_dynamic_cast(OBJECT(dev), typename)) {
             return dev;
         }
     }
@@ -212,7 +213,8 @@  static target_ulong h_reg_crq(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     target_ulong reg = args[0];
     target_ulong queue_addr = args[1];
     target_ulong queue_len = args[2];
-    VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+    VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg,
+                                                TYPE_VIO_SPAPR_DEVICE);
 
     if (!dev) {
         hcall_dprintf("Unit 0x" TARGET_FMT_lx " does not exist\n", reg);
@@ -268,7 +270,8 @@  static target_ulong h_free_crq(PowerPCCPU *cpu, sPAPREnvironment *spapr,
                                target_ulong opcode, target_ulong *args)
 {
     target_ulong reg = args[0];
-    VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+    VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg,
+                                                TYPE_VIO_SPAPR_DEVICE);
 
     if (!dev) {
         hcall_dprintf("Unit 0x" TARGET_FMT_lx " does not exist\n", reg);
@@ -284,7 +287,8 @@  static target_ulong h_send_crq(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     target_ulong reg = args[0];
     target_ulong msg_hi = args[1];
     target_ulong msg_lo = args[2];
-    VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+    VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg,
+                                                TYPE_VIO_SPAPR_DEVICE);
     uint64_t crq_mangle[2];
 
     if (!dev) {
@@ -305,7 +309,8 @@  static target_ulong h_enable_crq(PowerPCCPU *cpu, sPAPREnvironment *spapr,
                                  target_ulong opcode, target_ulong *args)
 {
     target_ulong reg = args[0];
-    VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+    VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg,
+                                                TYPE_VIO_SPAPR_DEVICE);
 
     if (!dev) {
         hcall_dprintf("Unit 0x" TARGET_FMT_lx " does not exist\n", reg);
@@ -382,7 +387,7 @@  static void rtas_set_tce_bypass(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     }
     unit = rtas_ld(args, 0);
     enable = rtas_ld(args, 1);
-    dev = spapr_vio_find_by_reg(bus, unit);
+    dev = spapr_vio_find_by_reg(bus, unit, TYPE_VIO_SPAPR_DEVICE);
     if (!dev) {
         rtas_st(rets, 0, -3);
         return;
@@ -513,7 +518,8 @@  static target_ulong h_vio_signal(PowerPCCPU *cpu, sPAPREnvironment *spapr,
 {
     target_ulong reg = args[0];
     target_ulong mode = args[1];
-    VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+    VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg,
+                                                TYPE_VIO_SPAPR_DEVICE);
     VIOsPAPRDeviceClass *pc;
 
     if (!dev) {
diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h
index f55eb90..e513889 100644
--- a/include/hw/ppc/spapr_vio.h
+++ b/include/hw/ppc/spapr_vio.h
@@ -77,7 +77,8 @@  struct VIOsPAPRBus {
 };
 
 extern VIOsPAPRBus *spapr_vio_bus_init(void);
-extern VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg);
+extern VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg,
+                                             const char *typename);
 extern int spapr_populate_vdevice(VIOsPAPRBus *bus, void *fdt);
 extern int spapr_populate_chosen_stdout(void *fdt, VIOsPAPRBus *bus);