diff mbox series

[v2,5/5] xen/common: move device initialization code to common code

Message ID 0b4d49742f58549ec644944ce1e02c98d7551845.1726579819.git.oleksii.kurochko@gmail.com (mailing list archive)
State Superseded
Headers show
Series Move {acpi_}device_init() and device_get_class() to common code | expand

Commit Message

Oleksii Kurochko Sept. 17, 2024, 4:15 p.m. UTC
Remove the device initialization code from `xen/arch/arm/device.c`
and move it to the common code to avoid duplication and make it accessible
for both ARM and other architectures.
device_get_class(), device_init(), _sdevice[] and _edevice[] are wrapped by
"#ifdef CONFIG_HAS_DEVICE_TREE" for the case if an arch doesn't support
device tree.

Remove unnecessary inclusions of <asm/device.h> and <xen/init.h> from
`xen/arch/arm/device.c` as no code in the file relies on these headers.
Fix the inclusion order by moving <asm/setup.h> after <xen/*> headers to
resolve a compilation error:
   ./include/public/xen.h:968:35: error: unknown type name 'uint64_t'
    968 | __DEFINE_XEN_GUEST_HANDLE(uint64, uint64_t);
        |                                   ^~~~~~~~
   ./include/public/arch-arm.h:191:21: note: in definition of macro '___DEFINE_XEN_GUEST_HANDLE'
   191 |     typedef union { type *p; uint64_aligned_t q; }              \
       |                     ^~~~
   ./include/public/xen.h:968:1: note: in expansion of macro '__DEFINE_XEN_GUEST_HANDLE'
   968 | __DEFINE_XEN_GUEST_HANDLE(uint64, uint64_t);
because <asm/setup.h> includes <public/version.h>, which in turn includes
"xen.h", which requires <xen/types.h> to be processed correctly.
Additionally, add <xen/device_tree.h> to `device.c` as functions from this
header are used within the file.

Introduce new CONFIG_DEVICE_INIT to compile `device.o` conditionally,
ensuring the correct device initialization code is included as needed.

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
Changes in v2:
 - Introduce CONFIG_DEVICE_INIT to make common/device.o compilable only for Arm,
   PPC and RIS-V.
 - Move declaration of acpi_device_desc _asdevice[], _aedevice[] inside
   #ifdef CONFIG_ACPI ... #endif.
 - Include <asm/device.h> instead of <asm-generic/device.h> as <asm/device.h>
   will be included <asm-generic/device.h> anyway.
---
 xen/arch/arm/device.c | 71 ++-----------------------------------
 xen/common/Kconfig    |  8 +++++
 xen/common/Makefile   |  1 +
 xen/common/device.c   | 82 +++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 93 insertions(+), 69 deletions(-)
 create mode 100644 xen/common/device.c

Comments

Jan Beulich Sept. 23, 2024, 2:43 p.m. UTC | #1
On 17.09.2024 18:15, Oleksii Kurochko wrote:
> --- a/xen/common/Kconfig
> +++ b/xen/common/Kconfig
> @@ -12,6 +12,14 @@ config CORE_PARKING
>  	bool
>  	depends on NR_CPUS > 1
>  
> +config DEVICE_INIT
> +	bool
> +	default !X86

This can simply be "def_bool y" as ...

> +	depends on !X86 && (ACPI || HAS_DEVICE_TREE)

... this enforces all restrictions. As indicated before I'd prefer if we
could get away without yet another Kconfig constant, which would then
also eliminate my concern about the expression not really covering for
the case where x86 would obtain DT support (and hence likely needing the
initialization here, too). What about ...

> --- a/xen/common/Makefile
> +++ b/xen/common/Makefile
> @@ -6,6 +6,7 @@ obj-$(CONFIG_HYPFS_CONFIG) += config_data.o
>  obj-$(CONFIG_CORE_PARKING) += core_parking.o
>  obj-y += cpu.o
>  obj-$(CONFIG_DEBUG_TRACE) += debugtrace.o
> +obj-$(CONFIG_DEVICE_INIT) += device.o

obj-$(CONFIG_HAS_DEVICE_TREE) += device.o
obj-$(filter-out $(CONFIG_X86),$(CONFIG_ACPI)) += device.o

? (Eventually we could then simplify this to just obj-$(CONFIG_ACPI),
to allow DT on x86, making sure the ACPI part of the file builds for
x86 but does nothing there.)

Jan
Oleksii Kurochko Sept. 24, 2024, 10:16 a.m. UTC | #2
On Mon, 2024-09-23 at 16:43 +0200, Jan Beulich wrote:
> On 17.09.2024 18:15, Oleksii Kurochko wrote:
> > --- a/xen/common/Kconfig
> > +++ b/xen/common/Kconfig
> > @@ -12,6 +12,14 @@ config CORE_PARKING
> >  	bool
> >  	depends on NR_CPUS > 1
> >  
> > +config DEVICE_INIT
> > +	bool
> > +	default !X86
> 
> This can simply be "def_bool y" as ...
> 
> > +	depends on !X86 && (ACPI || HAS_DEVICE_TREE)
> 
> ... this enforces all restrictions. As indicated before I'd prefer if
> we
> could get away without yet another Kconfig constant, which would then
> also eliminate my concern about the expression not really covering
> for
> the case where x86 would obtain DT support (and hence likely needing
> the
> initialization here, too). What about ...
> 
> > --- a/xen/common/Makefile
> > +++ b/xen/common/Makefile
> > @@ -6,6 +6,7 @@ obj-$(CONFIG_HYPFS_CONFIG) += config_data.o
> >  obj-$(CONFIG_CORE_PARKING) += core_parking.o
> >  obj-y += cpu.o
> >  obj-$(CONFIG_DEBUG_TRACE) += debugtrace.o
> > +obj-$(CONFIG_DEVICE_INIT) += device.o
> 
> obj-$(CONFIG_HAS_DEVICE_TREE) += device.o
> obj-$(filter-out $(CONFIG_X86),$(CONFIG_ACPI)) += device.o
> 
> ? (Eventually we could then simplify this to just obj-$(CONFIG_ACPI),
> to allow DT on x86, making sure the ACPI part of the file builds for
> x86 but does nothing there.)
I am okay with this solution. It seems I misunderstood you in the first
version of this patch series. When "obj-$(or ... )" was used, I decided
it wasn’t a good approach to use 'or', 'filter-out', or other similar
functions in Makefiles for such cases. I couldn't come up with a better
solution at the time, so I introduced a new config instead.

The only issue I see with this approach is that in device.c, there is
the following code:
   #ifdef CONFIG_ACPI
   
   extern const struct acpi_device_desc _asdevice[], _aedevice[];
   
   int __init acpi_device_init(enum device_class class, const void *data,
   int class_type)
      ...
   
   #endif
This shouldn't be compiled for X86. However, it will still be compiled
if we simplify to:
   obj-$(CONFIG_HAS_DEVICE_TREE) += device.o
   obj-$(CONFIG_ACPI) += device.o
The situation where we have CONFIG_HAS_DEVICE_TREE=y and CONFIG_ACPI=y
is possible ( if X86 will start or already using CONFIG_HAS_DEVICE_TREE
). The same will be if the second obj looks like: "obj-$(filter-out
$(CONFIG_X86),$(CONFIG_ACPI)) += device.o" and X86 will use
CONFIG_HAS_DEVICE_TREE.

To resolve this, we probably need two separate files: device-dt.c and
device-acpi.c, and then use:
   obj-$(CONFIG_HAS_DEVICE_TREE) += device-dt.o
   obj-$(filter-out $(CONFIG_X86),$(CONFIG_ACPI)) += device-acpi.o

Alternatively, we could make an exception in device.c and add a
!CONFIG_X86 condition:
   #if defined(CONFIG_ACPI) && !defined(CONFIG_X86)
   extern const struct acpi_device_desc _asdevice[], _aedevice[];
   
   int __init acpi_device_init(enum device_class class, const void
   *data, int class_type)
   ...
   #endif

~ Oleksii
Jan Beulich Sept. 24, 2024, 11:12 a.m. UTC | #3
On 24.09.2024 12:16, oleksii.kurochko@gmail.com wrote:
> On Mon, 2024-09-23 at 16:43 +0200, Jan Beulich wrote:
>> On 17.09.2024 18:15, Oleksii Kurochko wrote:
>>> --- a/xen/common/Kconfig
>>> +++ b/xen/common/Kconfig
>>> @@ -12,6 +12,14 @@ config CORE_PARKING
>>>  	bool
>>>  	depends on NR_CPUS > 1
>>>  
>>> +config DEVICE_INIT
>>> +	bool
>>> +	default !X86
>>
>> This can simply be "def_bool y" as ...
>>
>>> +	depends on !X86 && (ACPI || HAS_DEVICE_TREE)
>>
>> ... this enforces all restrictions. As indicated before I'd prefer if
>> we
>> could get away without yet another Kconfig constant, which would then
>> also eliminate my concern about the expression not really covering
>> for
>> the case where x86 would obtain DT support (and hence likely needing
>> the
>> initialization here, too). What about ...
>>
>>> --- a/xen/common/Makefile
>>> +++ b/xen/common/Makefile
>>> @@ -6,6 +6,7 @@ obj-$(CONFIG_HYPFS_CONFIG) += config_data.o
>>>  obj-$(CONFIG_CORE_PARKING) += core_parking.o
>>>  obj-y += cpu.o
>>>  obj-$(CONFIG_DEBUG_TRACE) += debugtrace.o
>>> +obj-$(CONFIG_DEVICE_INIT) += device.o
>>
>> obj-$(CONFIG_HAS_DEVICE_TREE) += device.o
>> obj-$(filter-out $(CONFIG_X86),$(CONFIG_ACPI)) += device.o
>>
>> ? (Eventually we could then simplify this to just obj-$(CONFIG_ACPI),
>> to allow DT on x86, making sure the ACPI part of the file builds for
>> x86 but does nothing there.)
> I am okay with this solution. It seems I misunderstood you in the first
> version of this patch series. When "obj-$(or ... )" was used, I decided
> it wasn’t a good approach to use 'or', 'filter-out', or other similar
> functions in Makefiles for such cases. I couldn't come up with a better
> solution at the time, so I introduced a new config instead.
> 
> The only issue I see with this approach is that in device.c, there is
> the following code:
>    #ifdef CONFIG_ACPI
>    
>    extern const struct acpi_device_desc _asdevice[], _aedevice[];
>    
>    int __init acpi_device_init(enum device_class class, const void *data,
>    int class_type)
>       ...
>    
>    #endif
> This shouldn't be compiled for X86. However, it will still be compiled
> if we simplify to:
>    obj-$(CONFIG_HAS_DEVICE_TREE) += device.o
>    obj-$(CONFIG_ACPI) += device.o

Which is why I said "eventually". For now it'll be the $(filter-out ...).
How to best adjust the code to permit above simplification is to be
determined; what you outlined matches what I had thought of as an option.

Jan
diff mbox series

Patch

diff --git a/xen/arch/arm/device.c b/xen/arch/arm/device.c
index 3e02cff008..5610cddcba 100644
--- a/xen/arch/arm/device.c
+++ b/xen/arch/arm/device.c
@@ -8,79 +8,12 @@ 
  * Copyright (C) 2013 Linaro Limited.
  */
 
-#include <asm/device.h>
-#include <asm/setup.h>
+#include <xen/device_tree.h>
 #include <xen/errno.h>
-#include <xen/init.h>
 #include <xen/iocap.h>
 #include <xen/lib.h>
 
-extern const struct device_desc _sdevice[], _edevice[];
-
-#ifdef CONFIG_ACPI
-extern const struct acpi_device_desc _asdevice[], _aedevice[];
-#endif
-
-int __init device_init(struct dt_device_node *dev, enum device_class class,
-                       const void *data)
-{
-    const struct device_desc *desc;
-
-    ASSERT(dev != NULL);
-
-    if ( !dt_device_is_available(dev) || dt_device_for_passthrough(dev) )
-        return  -ENODEV;
-
-    for ( desc = _sdevice; desc != _edevice; desc++ )
-    {
-        if ( desc->class != class )
-            continue;
-
-        if ( dt_match_node(desc->dt_match, dev) )
-        {
-            ASSERT(desc->init != NULL);
-
-            return desc->init(dev, data);
-        }
-
-    }
-
-    return -EBADF;
-}
-
-#ifdef CONFIG_ACPI
-int __init acpi_device_init(enum device_class class, const void *data, int class_type)
-{
-    const struct acpi_device_desc *desc;
-
-    for ( desc = _asdevice; desc != _aedevice; desc++ )
-    {
-        if ( ( desc->class != class ) || ( desc->class_type != class_type ) )
-            continue;
-
-        ASSERT(desc->init != NULL);
-
-        return desc->init(data);
-    }
-
-    return -EBADF;
-}
-#endif
-
-enum device_class device_get_class(const struct dt_device_node *dev)
-{
-    const struct device_desc *desc;
-
-    ASSERT(dev != NULL);
-
-    for ( desc = _sdevice; desc != _edevice; desc++ )
-    {
-        if ( dt_match_node(desc->dt_match, dev) )
-            return desc->class;
-    }
-
-    return DEVICE_UNKNOWN;
-}
+#include <asm/setup.h>
 
 int map_irq_to_domain(struct domain *d, unsigned int irq,
                       bool need_mapping, const char *devname)
diff --git a/xen/common/Kconfig b/xen/common/Kconfig
index 90268d9249..6c6ad30d99 100644
--- a/xen/common/Kconfig
+++ b/xen/common/Kconfig
@@ -12,6 +12,14 @@  config CORE_PARKING
 	bool
 	depends on NR_CPUS > 1
 
+config DEVICE_INIT
+	bool
+	default !X86
+	depends on !X86 && (ACPI || HAS_DEVICE_TREE)
+	help
+	  Enable support for device initialization using device tree or ACPI.
+	  It is not available for X86 systems.
+
 config GRANT_TABLE
 	bool "Grant table support" if EXPERT
 	default y
diff --git a/xen/common/Makefile b/xen/common/Makefile
index fc52e0857d..1d5a4bb18d 100644
--- a/xen/common/Makefile
+++ b/xen/common/Makefile
@@ -6,6 +6,7 @@  obj-$(CONFIG_HYPFS_CONFIG) += config_data.o
 obj-$(CONFIG_CORE_PARKING) += core_parking.o
 obj-y += cpu.o
 obj-$(CONFIG_DEBUG_TRACE) += debugtrace.o
+obj-$(CONFIG_DEVICE_INIT) += device.o
 obj-$(CONFIG_HAS_DEVICE_TREE) += device-tree/
 obj-$(CONFIG_IOREQ_SERVER) += dm.o
 obj-y += domain.o
diff --git a/xen/common/device.c b/xen/common/device.c
new file mode 100644
index 0000000000..33e0d58f2f
--- /dev/null
+++ b/xen/common/device.c
@@ -0,0 +1,82 @@ 
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Based on the code from:
+ *   xen/arch/arm/device.c
+ */
+
+#include <xen/bug.h>
+#include <xen/device_tree.h>
+#include <xen/errno.h>
+#include <xen/init.h>
+
+#include <asm/device.h>
+
+#ifdef CONFIG_HAS_DEVICE_TREE
+
+extern const struct device_desc _sdevice[], _edevice[];
+
+int __init device_init(struct dt_device_node *dev, enum device_class class,
+                       const void *data)
+{
+    const struct device_desc *desc;
+
+    ASSERT(dev != NULL);
+
+    if ( !dt_device_is_available(dev) || dt_device_for_passthrough(dev) )
+        return  -ENODEV;
+
+    for ( desc = _sdevice; desc != _edevice; desc++ )
+    {
+        if ( desc->class != class )
+            continue;
+
+        if ( dt_match_node(desc->dt_match, dev) )
+        {
+            ASSERT(desc->init != NULL);
+
+            return desc->init(dev, data);
+        }
+    }
+
+    return -EBADF;
+}
+
+enum device_class device_get_class(const struct dt_device_node *dev)
+{
+    const struct device_desc *desc;
+
+    ASSERT(dev != NULL);
+
+    for ( desc = _sdevice; desc != _edevice; desc++ )
+    {
+        if ( dt_match_node(desc->dt_match, dev) )
+            return desc->class;
+    }
+
+    return DEVICE_UNKNOWN;
+}
+
+#endif
+
+#ifdef CONFIG_ACPI
+
+extern const struct acpi_device_desc _asdevice[], _aedevice[];
+
+int __init acpi_device_init(enum device_class class, const void *data, int class_type)
+{
+    const struct acpi_device_desc *desc;
+
+    for ( desc = _asdevice; desc != _aedevice; desc++ )
+    {
+        if ( ( desc->class != class ) || ( desc->class_type != class_type ) )
+            continue;
+
+        ASSERT(desc->init != NULL);
+
+        return desc->init(data);
+    }
+
+    return -EBADF;
+}
+
+#endif