Skip to contentSkip to conversation

Add ACPI support for arm64 on Xen

PATCH In review shannon.zhao at linaro.org 10 participants 352 messages Nov 17, 2015 – Jan 8, 2016 Arm Samsung Exynos Page 2 of 3

lore
Share & tools
lore
#169 lore raw

Re: [PATCH v3 32/62] arm/acpi: Parse GTDT to initialize timer

In reply to shannon.zhao at linaro.org
Quoted 49 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Parth Dixit <[email protected]>

Parse GTDT (Generic Timer Descriptor Table) to initialize timer. Using the information presented by GTDT to initialize the arch timer (not memory-mapped).

---
 xen/arch/arm/time.c | 73 +++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 62 insertions(+), 11 deletions(-)
xen/arch/arm/time.c +21 -0
index 5ded30c..adbfc2a 100644
@@ -29,6 +29,7 @@
 #include <xen/time.h>
 #include <xen/sched.h>
 #include <xen/event.h>
+#include <xen/acpi.h>
 #include <asm/system.h>
 #include <asm/time.h>
 #include <asm/gic.h>
@@ -65,8 +66,45 @@ unsigned int timer_get_irq(enum timer_ppi ppi)
 
 static __initdata struct dt_device_node *timer;
 
+#ifdef CONFIG_ACPI
+/* Initialize per-processor generic timer */
+static int __init arch_timer_acpi_init(struct acpi_table_header *table)
+{
+    unsigned int irq_type;
+    struct acpi_table_gtdt *gtdt;
+
+    gtdt = container_of(table, struct acpi_table_gtdt, header);
+
+    /* Initialize all the generic timer IRQ variable from GTDT table */
+    irq_type = acpi_get_irq_type(gtdt->non_secure_el1_flags);
+    irq_set_type(gtdt->non_secure_el1_interrupt, irq_type);
+    timer_irq[TIMER_PHYS_NONSECURE_PPI] = gtdt->non_secure_el1_interrupt;
+
+    irq_type = acpi_get_irq_type(gtdt->secure_el1_flags);
+    irq_set_type(gtdt->secure_el1_interrupt, irq_type);
+    timer_irq[TIMER_PHYS_SECURE_PPI] = gtdt->secure_el1_interrupt;
+
+    irq_type = acpi_get_irq_type(gtdt->virtual_timer_flags);
+    irq_set_type(gtdt->virtual_timer_interrupt, irq_type);

xen/arch/arm/time.c unsigned int timer_get_irq(enum timer_ppi ppi) · line 98

Quoted 10 lines
xen/arch/arm/time.c +10 -0
+    timer_irq[TIMER_VIRT_PPI] = gtdt->virtual_timer_interrupt;
+
+    irq_type = acpi_get_irq_type(gtdt->non_secure_el2_flags);
+    irq_set_type(gtdt->non_secure_el2_interrupt, irq_type);
+    timer_irq[TIMER_HYP_PPI] = gtdt->non_secure_el2_interrupt;
+
+    return 0;
+}
+
+void __init acpi_preinit_xen_time(void)

static?

Quoted 22 lines
xen/arch/arm/time.c +8 -2
+{
+	acpi_table_parse(ACPI_SIG_GTDT, arch_timer_acpi_init);
+}
+#else
+static inline void acpi_preinit_xen_time(void) { }
+#endif
+
 /* Set up the timer on the boot CPU (early init function) */
-void __init preinit_xen_time(void)
+static void __init dt_preinit_xen_time(void)
 {
     static const struct dt_device_match timer_ids[] __initconst =
     {
@@ -74,7 +112,6 @@ void __init preinit_xen_time(void)
         { /* sentinel */ },
     };
     int res;
-    u32 rate;
 
     timer = dt_find_matching_node(NULL, timer_ids);
     if ( !timer )

xen/arch/arm/time.c void __init preinit_xen_time(void) · line 124

Quoted 2 lines
xen/arch/arm/time.c +0 -0
@@ -86,8 +123,19 @@ void __init preinit_xen_time(void)
     if ( res )
         panic("Timer: Cannot initialize platform timer");

Don't we want to call platform_init_time on ARM too? It doesn't look like something DT specific. I guess we should move the call to the generic init function?

xen/arch/arm/time.c void __init preinit_xen_time(void) · line 90

Quoted 2 lines
xen/arch/arm/time.c +0 -2
-    res = dt_property_read_u32(timer, "clock-frequency", &rate);
-    if ( res )

I think we should keep the clock-frequency DT read in dt_preinit_xen_time.

Quoted 6 lines
xen/arch/arm/time.c +6 -0
+}
+
+void __init preinit_xen_time(void)
+{
+    u32 rate;
+

xen/arch/arm/time.c void __init preinit_xen_time(void) · line 141

Quoted 10 lines
xen/arch/arm/time.c +7 -0
+    /* Initialize all the generic timers presented in GTDT */
+    if ( acpi_disabled )
+        dt_preinit_xen_time();
+    else
+        acpi_preinit_xen_time();
+
+    if( acpi_disabled && dt_property_read_u32(timer, "clock-frequency", &rate) )
     {
         cpu_khz = rate / 1000;
         timer_dt_clock_frequency = rate;

I don't think we want to read a DT property from a generic initialization function.

Quoted 13 lines
xen/arch/arm/time.c +1 -7
@@ -104,14 +152,17 @@ int __init init_xen_time(void)
     int res;
     unsigned int i;
 
-    /* Retrieve all IRQs for the timer */
-    for ( i = TIMER_PHYS_SECURE_PPI; i < MAX_TIMER_PPI; i++ )
+    if( acpi_disabled )
     {
-        res = platform_get_irq(timer, i);
-
-        if ( res < 0 )
-            panic("Timer: Unable to retrieve IRQ %u from the device tree", i);
-        timer_irq[i] = res;

xen/arch/arm/time.c int __init init_xen_time(void) · line 166

Quoted 10 lines
xen/arch/arm/time.c +9 -0
+        /* Retrieve all IRQs for the timer */
+        for ( i = TIMER_PHYS_SECURE_PPI; i < MAX_TIMER_PPI; i++ )
+        {
+            res = platform_get_irq(timer, i);
+
+            if ( res < 0 )
+                panic("Timer: Unable to retrieve IRQ %u from the device tree", i);
+            timer_irq[i] = res;
+        }
     }

Can't be just move this into the DT specific init function?

Quoted 11 lines
xen/arch/arm/time.c +0 -0
     /* Check that this CPU supports the Generic Timer interface */
Signature · 7 lines
2.1.0


_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
#170 lore raw

PATCH v3 33/62 arm/uart: Create generic uart initialization function

In reply to shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

Rename dt-uart.c to arm-uart.c and create new generic uart init function. Move dt_uart_init to arm_uart_init.

---
 xen/arch/arm/setup.c        |   2 +-
 xen/drivers/char/Makefile   |   2 +-
 xen/drivers/char/arm-uart.c | 136 ++++++++++++++++++++++++++++++++++++++++++++
 xen/drivers/char/dt-uart.c  | 107 ----------------------------------
 xen/include/xen/serial.h    |   2 +-
 5 files changed, 139 insertions(+), 110 deletions(-)
 create mode 100644 xen/drivers/char/arm-uart.c
 delete mode 100644 xen/drivers/char/dt-uart.c
xen/arch/arm/setup.c +1 -1
index c15a09d..63feadf 100644
@@ -766,7 +766,7 @@ void __init start_xen(unsigned long boot_phys_offset,
 
     gic_preinit();
 
-    dt_uart_init();
+    arm_uart_init();
     console_init_preirq();
     console_init_ring();
 
xen/drivers/char/Makefile +1 -1
index 47fc3f9..a8f65c1 100644
@@ -6,5 +6,5 @@ obj-$(HAS_EXYNOS4210) += exynos4210-uart.o
 obj-$(HAS_OMAP) += omap-uart.o
 obj-$(HAS_SCIF) += scif-uart.o
 obj-$(HAS_EHCI) += ehci-dbgp.o
-obj-$(CONFIG_ARM) += dt-uart.o
+obj-$(CONFIG_ARM) += arm-uart.o
 obj-y += serial.o
xen/drivers/char/arm-uart.c new file +136 -0

136 lines not on this page · raw message

xen/drivers/char/dt-uart.c deleted +0 -107

107 lines not on this page · raw message

xen/include/xen/serial.h +1 -1
index 71e6ade..5e1a536 100644
@@ -170,7 +170,7 @@ struct ns16550_defaults {
 void ns16550_init(int index, struct ns16550_defaults *defaults);
 void ehci_dbgp_init(void);
 
-void __init dt_uart_init(void);
+void __init arm_uart_init(void);
 
 struct physdev_dbgp_op;
 int dbgp_op(const struct physdev_dbgp_op *);
Signature · 1 line
2.1.0
#171 lore raw

PATCH v3 33/62 arm/uart: Create generic uart initialization function

Hi Shannon,

Quoted 4 lines · shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

Rename dt-uart.c to arm-uart.c and create new generic uart init function. Move dt_uart_init to arm_uart_init.

It's very hard to review a patch to move existing code and add new one. Please split it in 2.

Regards,

Signature · 1 line
Julien Grall
#172 lore raw

PATCH v3 33/62 arm/uart: Create generic uart initialization function

Quoted 11 lines · Julien Grall

Hi Shannon,

Quoted 4 lines · shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

Rename dt-uart.c to arm-uart.c and create new generic uart init function. Move dt_uart_init to arm_uart_init.

It's very hard to review a patch to move existing code and add new one. Please split it in 2.

Ok, thanks.

Signature · 1 line
Shannon
#173 lore raw

Re: [PATCH v3 33/62] arm/uart: Create generic uart initialization function

In reply to Julien Grall
Quoted 11 lines · Julien Grall

Hi Shannon,

Quoted 4 lines · On 17/11/15 09:40, [email protected] wrote:

From: Parth Dixit <[email protected]>

Rename dt-uart.c to arm-uart.c and create new generic uart init function. Move dt_uart_init to arm_uart_init.

It's very hard to review a patch to move existing code and add new one. Please split it in 2.

Ok, thanks.

Signature · 1 line
Shannon
#174 lore raw

Re: [PATCH v3 33/62] arm/uart: Create generic uart initialization function

In reply to shannon.zhao at linaro.org

Hi Shannon,

Quoted 4 lines · On 17/11/15 09:40, [email protected] wrote:

From: Parth Dixit <[email protected]>

Rename dt-uart.c to arm-uart.c and create new generic uart init function. Move dt_uart_init to arm_uart_init.

It's very hard to review a patch to move existing code and add new one. Please split it in 2.

Regards,

Signature · 1 line
Julien Grall
#175 lore raw

PATCH v3 34/62 pl011: Refactor pl011 driver to dt and common initialization parts

In reply to shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Refactor pl011 driver to dt and common initialization parts. This will be useful later when acpi specific uart initialization function is introduced.

---
 xen/drivers/char/pl011.c | 64 ++++++++++++++++++++++++++++--------------------
 1 file changed, 38 insertions(+), 26 deletions(-)
xen/drivers/char/pl011.c +38 -26
index 67e6df5..16abaa5 100644
@@ -226,12 +226,42 @@ static struct uart_driver __read_mostly pl011_driver = {
     .vuart_info   = pl011_vuart,
 };
 
+static int __init pl011_uart_init(int irq, u64 addr, u64 size)
+{
+    struct pl011 *uart;
+
+    uart = &pl011_com;
+    uart->irq       = irq;
+    uart->clock_hz  = 0x16e3600;
+    uart->baud      = BAUD_AUTO;
+    uart->data_bits = 8;
+    uart->parity    = PARITY_NONE;
+    uart->stop_bits = 1;
+
+    uart->regs = ioremap_nocache(addr, size);
+    if ( !uart->regs )
+    {
+        printk("pl011: Unable to map the UART memory\n");
+        return -ENOMEM;
+    }
+
+    uart->vuart.base_addr = addr;
+    uart->vuart.size = size;
+    uart->vuart.data_off = DR;
+    uart->vuart.status_off = FR;
+    uart->vuart.status = 0;
+
+    /* Register with generic serial driver. */
+    serial_register_uart(SERHND_DTUART, &pl011_driver, uart);
+
+    return 0;
+}
+
 /* TODO: Parse UART config from the command line */
-static int __init pl011_uart_init(struct dt_device_node *dev,
-                                  const void *data)
+static int __init dt_pl011_uart_init(struct dt_device_node *dev,
+                                     const void *data)
 {
     const char *config = data;
-    struct pl011 *uart;
     int res;
     u64 addr, size;
 
@@ -240,14 +270,6 @@ static int __init pl011_uart_init(struct dt_device_node *dev,
         printk("WARNING: UART configuration is not supported\n");
     }
 
-    uart = &pl011_com;
-
-    uart->clock_hz  = 0x16e3600;
-    uart->baud      = BAUD_AUTO;
-    uart->data_bits = 8;
-    uart->parity    = PARITY_NONE;
-    uart->stop_bits = 1;
-
     res = dt_device_get_address(dev, 0, &addr, &size);
     if ( res )
     {
@@ -262,24 +284,14 @@ static int __init pl011_uart_init(struct dt_device_node *dev,
         printk("pl011: Unable to retrieve the IRQ\n");
         return -EINVAL;
     }
-    uart->irq = res;
 
-    uart->regs = ioremap_nocache(addr, size);
-    if ( !uart->regs )
+    res = pl011_uart_init(res, addr, size);
+    if ( res < 0 )
     {
-        printk("pl011: Unable to map the UART memory\n");
-        return -ENOMEM;
+        printk("pl011: Unable to initialize\n");
+        return res;
     }
 
-    uart->vuart.base_addr = addr;
-    uart->vuart.size = size;
-    uart->vuart.data_off = DR;
-    uart->vuart.status_off = FR;
-    uart->vuart.status = 0;
-
-    /* Register with generic serial driver. */
-    serial_register_uart(SERHND_DTUART, &pl011_driver, uart);
-
     dt_device_set_used_by(dev, DOMID_XEN);
 
     return 0;
@@ -293,7 +305,7 @@ static const struct dt_device_match pl011_dt_match[] __initconst =
 
 DT_DEVICE_START(pl011, "PL011 UART", DEVICE_SERIAL)
         .dt_match = pl011_dt_match,
-        .init = pl011_uart_init,
+        .init = dt_pl011_uart_init,
 DT_DEVICE_END
 
 /*
Signature · 1 line
2.1.0
#176 lore raw

PATCH v3 34/62 pl011: Refactor pl011 driver to dt and common initialization parts

Quoted 8 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Refactor pl011 driver to dt and common initialization parts. This will be useful later when acpi specific uart initialization function is introduced.

Quoted 109 lines
 xen/drivers/char/pl011.c | 64 ++++++++++++++++++++++++++++--------------------
 1 file changed, 38 insertions(+), 26 deletions(-)
xen/drivers/char/pl011.c +38 -26
index 67e6df5..16abaa5 100644
@@ -226,12 +226,42 @@ static struct uart_driver __read_mostly pl011_driver = {
     .vuart_info   = pl011_vuart,
 };
 
+static int __init pl011_uart_init(int irq, u64 addr, u64 size)
+{
+    struct pl011 *uart;
+
+    uart = &pl011_com;
+    uart->irq       = irq;
+    uart->clock_hz  = 0x16e3600;
+    uart->baud      = BAUD_AUTO;
+    uart->data_bits = 8;
+    uart->parity    = PARITY_NONE;
+    uart->stop_bits = 1;
+
+    uart->regs = ioremap_nocache(addr, size);
+    if ( !uart->regs )
+    {
+        printk("pl011: Unable to map the UART memory\n");
+        return -ENOMEM;
+    }
+
+    uart->vuart.base_addr = addr;
+    uart->vuart.size = size;
+    uart->vuart.data_off = DR;
+    uart->vuart.status_off = FR;
+    uart->vuart.status = 0;
+
+    /* Register with generic serial driver. */
+    serial_register_uart(SERHND_DTUART, &pl011_driver, uart);
+
+    return 0;
+}
+
 /* TODO: Parse UART config from the command line */
-static int __init pl011_uart_init(struct dt_device_node *dev,
-                                  const void *data)
+static int __init dt_pl011_uart_init(struct dt_device_node *dev,
+                                     const void *data)
 {
     const char *config = data;
-    struct pl011 *uart;
     int res;
     u64 addr, size;
 
@@ -240,14 +270,6 @@ static int __init pl011_uart_init(struct dt_device_node *dev,
         printk("WARNING: UART configuration is not supported\n");
     }
 
-    uart = &pl011_com;
-
-    uart->clock_hz  = 0x16e3600;
-    uart->baud      = BAUD_AUTO;
-    uart->data_bits = 8;
-    uart->parity    = PARITY_NONE;
-    uart->stop_bits = 1;
-
     res = dt_device_get_address(dev, 0, &addr, &size);
     if ( res )
     {
@@ -262,24 +284,14 @@ static int __init pl011_uart_init(struct dt_device_node *dev,
         printk("pl011: Unable to retrieve the IRQ\n");
         return -EINVAL;
     }
-    uart->irq = res;
 
-    uart->regs = ioremap_nocache(addr, size);
-    if ( !uart->regs )
+    res = pl011_uart_init(res, addr, size);
+    if ( res < 0 )
     {
-        printk("pl011: Unable to map the UART memory\n");
-        return -ENOMEM;
+        printk("pl011: Unable to initialize\n");
+        return res;
     }
 
-    uart->vuart.base_addr = addr;
-    uart->vuart.size = size;
-    uart->vuart.data_off = DR;
-    uart->vuart.status_off = FR;
-    uart->vuart.status = 0;
-
-    /* Register with generic serial driver. */
-    serial_register_uart(SERHND_DTUART, &pl011_driver, uart);
-
     dt_device_set_used_by(dev, DOMID_XEN);
 
     return 0;
@@ -293,7 +305,7 @@ static const struct dt_device_match pl011_dt_match[] __initconst =
 
 DT_DEVICE_START(pl011, "PL011 UART", DEVICE_SERIAL)
         .dt_match = pl011_dt_match,
-        .init = pl011_uart_init,
+        .init = dt_pl011_uart_init,
 DT_DEVICE_END
 
 /*
Signature · 1 line
2.1.0
Acked-by on v3 34/62
#177 lore raw

Re: [PATCH v3 34/62] pl011: Refactor pl011 driver to dt and common initialization parts

In reply to shannon.zhao at linaro.org
Quoted 8 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Shannon Zhao <[email protected]>

Refactor pl011 driver to dt and common initialization parts. This will be useful later when acpi specific uart initialization function is introduced.

Quoted 109 lines
 xen/drivers/char/pl011.c | 64 ++++++++++++++++++++++++++++--------------------
 1 file changed, 38 insertions(+), 26 deletions(-)
xen/drivers/char/pl011.c +38 -26
index 67e6df5..16abaa5 100644
@@ -226,12 +226,42 @@ static struct uart_driver __read_mostly pl011_driver = {
     .vuart_info   = pl011_vuart,
 };
 
+static int __init pl011_uart_init(int irq, u64 addr, u64 size)
+{
+    struct pl011 *uart;
+
+    uart = &pl011_com;
+    uart->irq       = irq;
+    uart->clock_hz  = 0x16e3600;
+    uart->baud      = BAUD_AUTO;
+    uart->data_bits = 8;
+    uart->parity    = PARITY_NONE;
+    uart->stop_bits = 1;
+
+    uart->regs = ioremap_nocache(addr, size);
+    if ( !uart->regs )
+    {
+        printk("pl011: Unable to map the UART memory\n");
+        return -ENOMEM;
+    }
+
+    uart->vuart.base_addr = addr;
+    uart->vuart.size = size;
+    uart->vuart.data_off = DR;
+    uart->vuart.status_off = FR;
+    uart->vuart.status = 0;
+
+    /* Register with generic serial driver. */
+    serial_register_uart(SERHND_DTUART, &pl011_driver, uart);
+
+    return 0;
+}
+
 /* TODO: Parse UART config from the command line */
-static int __init pl011_uart_init(struct dt_device_node *dev,
-                                  const void *data)
+static int __init dt_pl011_uart_init(struct dt_device_node *dev,
+                                     const void *data)
 {
     const char *config = data;
-    struct pl011 *uart;
     int res;
     u64 addr, size;
 
@@ -240,14 +270,6 @@ static int __init pl011_uart_init(struct dt_device_node *dev,
         printk("WARNING: UART configuration is not supported\n");
     }
 
-    uart = &pl011_com;
-
-    uart->clock_hz  = 0x16e3600;
-    uart->baud      = BAUD_AUTO;
-    uart->data_bits = 8;
-    uart->parity    = PARITY_NONE;
-    uart->stop_bits = 1;
-
     res = dt_device_get_address(dev, 0, &addr, &size);
     if ( res )
     {
@@ -262,24 +284,14 @@ static int __init pl011_uart_init(struct dt_device_node *dev,
         printk("pl011: Unable to retrieve the IRQ\n");
         return -EINVAL;
     }
-    uart->irq = res;
 
-    uart->regs = ioremap_nocache(addr, size);
-    if ( !uart->regs )
+    res = pl011_uart_init(res, addr, size);
+    if ( res < 0 )
     {
-        printk("pl011: Unable to map the UART memory\n");
-        return -ENOMEM;
+        printk("pl011: Unable to initialize\n");
+        return res;
     }
 
-    uart->vuart.base_addr = addr;
-    uart->vuart.size = size;
-    uart->vuart.data_off = DR;
-    uart->vuart.status_off = FR;
-    uart->vuart.status = 0;
-
-    /* Register with generic serial driver. */
-    serial_register_uart(SERHND_DTUART, &pl011_driver, uart);
-
     dt_device_set_used_by(dev, DOMID_XEN);
 
     return 0;
@@ -293,7 +305,7 @@ static const struct dt_device_match pl011_dt_match[] __initconst =
 
 DT_DEVICE_START(pl011, "PL011 UART", DEVICE_SERIAL)
         .dt_match = pl011_dt_match,
-        .init = pl011_uart_init,
+        .init = dt_pl011_uart_init,
 DT_DEVICE_END
 
 /*
Signature · 1 line
2.1.0
#178 lore raw

PATCH v3 35/62 serial: Rename SERHND_DTUART to SERHND_UART

In reply to shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Rename SERHND_DTUART to SERHND_UART in order to reuse it when booting with ACPI.

---
 xen/arch/arm/vuart.c               | 2 +-
 xen/drivers/char/cadence-uart.c    | 2 +-
 xen/drivers/char/exynos4210-uart.c | 2 +-
 xen/drivers/char/omap-uart.c       | 2 +-
 xen/drivers/char/pl011.c           | 2 +-
 xen/drivers/char/scif-uart.c       | 2 +-
 xen/drivers/char/serial.c          | 2 +-
 xen/include/xen/serial.h           | 2 +-
 8 files changed, 8 insertions(+), 8 deletions(-)
xen/arch/arm/vuart.c +1 -1
index b5c9288..6619b33 100644
@@ -59,7 +59,7 @@ int domain_vuart_init(struct domain *d)
 {
     ASSERT( is_hardware_domain(d) );
 
-    d->arch.vuart.info = serial_vuart_info(SERHND_DTUART);
+    d->arch.vuart.info = serial_vuart_info(SERHND_UART);
     if ( !d->arch.vuart.info )
         return 0;
 
xen/drivers/char/cadence-uart.c +1 -1
index 933672f..ed65004 100644
@@ -196,7 +196,7 @@ static int __init cuart_init(struct dt_device_node *dev, const void *data)
     uart->vuart.status = UART_SR_INTR_TEMPTY;
 
     /* Register with generic serial driver. */
-    serial_register_uart(SERHND_DTUART, &cuart_driver, uart);
+    serial_register_uart(SERHND_UART, &cuart_driver, uart);
 
     dt_device_set_used_by(dev, DOMID_XEN);
 
xen/drivers/char/exynos4210-uart.c +1 -1
index bac1c2b..43f5313 100644
@@ -345,7 +345,7 @@ static int __init exynos4210_uart_init(struct dt_device_node *dev,
     uart->vuart.status = UTRSTAT_TXE | UTRSTAT_TXFE;
 
     /* Register with generic serial driver. */
-    serial_register_uart(SERHND_DTUART, &exynos4210_uart_driver, uart);
+    serial_register_uart(SERHND_UART, &exynos4210_uart_driver, uart);
 
     dt_device_set_used_by(dev, DOMID_XEN);
 
xen/drivers/char/omap-uart.c +1 -1
index d8f64ea..98c3892 100644
@@ -343,7 +343,7 @@ static int __init omap_uart_init(struct dt_device_node *dev,
     uart->vuart.status = UART_LSR_THRE;
 
     /* Register with generic serial driver */
-    serial_register_uart(SERHND_DTUART, &omap_uart_driver, uart);
+    serial_register_uart(SERHND_UART, &omap_uart_driver, uart);
 
     dt_device_set_used_by(dev, DOMID_XEN);
 
xen/drivers/char/pl011.c +1 -1
index 16abaa5..1efb1cf 100644
@@ -252,7 +252,7 @@ static int __init pl011_uart_init(int irq, u64 addr, u64 size)
     uart->vuart.status = 0;
 
     /* Register with generic serial driver. */
-    serial_register_uart(SERHND_DTUART, &pl011_driver, uart);
+    serial_register_uart(SERHND_UART, &pl011_driver, uart);
 
     return 0;
 }
xen/drivers/char/scif-uart.c +1 -1
index 51a2233..739317c 100644
@@ -339,7 +339,7 @@ static int __init scif_uart_init(struct dt_device_node *dev,
     uart->vuart.status     = SCFSR_TDFE;
 
     /* Register with generic serial driver */
-    serial_register_uart(SERHND_DTUART, &scif_uart_driver, uart);
+    serial_register_uart(SERHND_UART, &scif_uart_driver, uart);
 
     dt_device_set_used_by(dev, DOMID_XEN);
 
xen/drivers/char/serial.c +1 -1
index c583a48..659e10d 100644
@@ -312,7 +312,7 @@ int __init serial_parse_handle(char *conf)
 
     if ( !strncmp(conf, "dtuart", 5) )
     {
-        handle = SERHND_DTUART;
+        handle = SERHND_UART;
         goto common;
     }
 
xen/include/xen/serial.h +1 -1
index 5e1a536..a6e7c22 100644
@@ -94,7 +94,7 @@ struct uart_driver {
 # define SERHND_COM1    (0<<0)
 # define SERHND_COM2    (1<<0)
 # define SERHND_DBGP    (2<<0)
-# define SERHND_DTUART  (0<<0) /* Steal SERHND_COM1 value */
+# define SERHND_UART    (0<<0) /* Steal SERHND_COM1 value */
 #define SERHND_HI       (1<<2) /* Mux/demux each transferred char by MSB. */
 #define SERHND_LO       (1<<3) /* Ditto, except that the MSB is cleared.  */
 #define SERHND_COOKED   (1<<4) /* Newline/carriage-return translation?    */
Signature · 1 line
2.1.0
#179 lore raw

PATCH v3 35/62 serial: Rename SERHND_DTUART to SERHND_UART

Quoted 4 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Rename SERHND_DTUART to SERHND_UART in order to reuse it when booting with ACPI.

But actually I fail to see where is it being used with ACPI.

Quoted 125 lines
---
 xen/arch/arm/vuart.c               | 2 +-
 xen/drivers/char/cadence-uart.c    | 2 +-
 xen/drivers/char/exynos4210-uart.c | 2 +-
 xen/drivers/char/omap-uart.c       | 2 +-
 xen/drivers/char/pl011.c           | 2 +-
 xen/drivers/char/scif-uart.c       | 2 +-
 xen/drivers/char/serial.c          | 2 +-
 xen/include/xen/serial.h           | 2 +-
 8 files changed, 8 insertions(+), 8 deletions(-)
xen/arch/arm/vuart.c +1 -1
index b5c9288..6619b33 100644
@@ -59,7 +59,7 @@ int domain_vuart_init(struct domain *d)
 {
     ASSERT( is_hardware_domain(d) );
 
-    d->arch.vuart.info = serial_vuart_info(SERHND_DTUART);
+    d->arch.vuart.info = serial_vuart_info(SERHND_UART);
     if ( !d->arch.vuart.info )
         return 0;
 
xen/drivers/char/cadence-uart.c +1 -1
index 933672f..ed65004 100644
@@ -196,7 +196,7 @@ static int __init cuart_init(struct dt_device_node *dev, const void *data)
     uart->vuart.status = UART_SR_INTR_TEMPTY;
 
     /* Register with generic serial driver. */
-    serial_register_uart(SERHND_DTUART, &cuart_driver, uart);
+    serial_register_uart(SERHND_UART, &cuart_driver, uart);
 
     dt_device_set_used_by(dev, DOMID_XEN);
 
xen/drivers/char/exynos4210-uart.c +1 -1
index bac1c2b..43f5313 100644
@@ -345,7 +345,7 @@ static int __init exynos4210_uart_init(struct dt_device_node *dev,
     uart->vuart.status = UTRSTAT_TXE | UTRSTAT_TXFE;
 
     /* Register with generic serial driver. */
-    serial_register_uart(SERHND_DTUART, &exynos4210_uart_driver, uart);
+    serial_register_uart(SERHND_UART, &exynos4210_uart_driver, uart);
 
     dt_device_set_used_by(dev, DOMID_XEN);
 
xen/drivers/char/omap-uart.c +1 -1
index d8f64ea..98c3892 100644
@@ -343,7 +343,7 @@ static int __init omap_uart_init(struct dt_device_node *dev,
     uart->vuart.status = UART_LSR_THRE;
 
     /* Register with generic serial driver */
-    serial_register_uart(SERHND_DTUART, &omap_uart_driver, uart);
+    serial_register_uart(SERHND_UART, &omap_uart_driver, uart);
 
     dt_device_set_used_by(dev, DOMID_XEN);
 
xen/drivers/char/pl011.c +1 -1
index 16abaa5..1efb1cf 100644
@@ -252,7 +252,7 @@ static int __init pl011_uart_init(int irq, u64 addr, u64 size)
     uart->vuart.status = 0;
 
     /* Register with generic serial driver. */
-    serial_register_uart(SERHND_DTUART, &pl011_driver, uart);
+    serial_register_uart(SERHND_UART, &pl011_driver, uart);
 
     return 0;
 }
xen/drivers/char/scif-uart.c +1 -1
index 51a2233..739317c 100644
@@ -339,7 +339,7 @@ static int __init scif_uart_init(struct dt_device_node *dev,
     uart->vuart.status     = SCFSR_TDFE;
 
     /* Register with generic serial driver */
-    serial_register_uart(SERHND_DTUART, &scif_uart_driver, uart);
+    serial_register_uart(SERHND_UART, &scif_uart_driver, uart);
 
     dt_device_set_used_by(dev, DOMID_XEN);
 
xen/drivers/char/serial.c +1 -1
index c583a48..659e10d 100644
@@ -312,7 +312,7 @@ int __init serial_parse_handle(char *conf)
 
     if ( !strncmp(conf, "dtuart", 5) )
     {
-        handle = SERHND_DTUART;
+        handle = SERHND_UART;
         goto common;
     }
 
xen/include/xen/serial.h +1 -1
index 5e1a536..a6e7c22 100644
@@ -94,7 +94,7 @@ struct uart_driver {
 # define SERHND_COM1    (0<<0)
 # define SERHND_COM2    (1<<0)
 # define SERHND_DBGP    (2<<0)
-# define SERHND_DTUART  (0<<0) /* Steal SERHND_COM1 value */
+# define SERHND_UART    (0<<0) /* Steal SERHND_COM1 value */
 #define SERHND_HI       (1<<2) /* Mux/demux each transferred char by MSB. */
 #define SERHND_LO       (1<<3) /* Ditto, except that the MSB is cleared.  */
 #define SERHND_COOKED   (1<<4) /* Newline/carriage-return translation?    */
Signature · 7 lines
2.1.0


_______________________________________________
Xen-devel mailing list
Xen-devel at lists.xen.org
http://lists.xen.org/xen-devel
#180 lore raw

Re: [PATCH v3 35/62] serial: Rename SERHND_DTUART to SERHND_UART

In reply to shannon.zhao at linaro.org
Quoted 4 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Shannon Zhao <[email protected]>

Rename SERHND_DTUART to SERHND_UART in order to reuse it when booting with ACPI.

But actually I fail to see where is it being used with ACPI.

Quoted 125 lines
---
 xen/arch/arm/vuart.c               | 2 +-
 xen/drivers/char/cadence-uart.c    | 2 +-
 xen/drivers/char/exynos4210-uart.c | 2 +-
 xen/drivers/char/omap-uart.c       | 2 +-
 xen/drivers/char/pl011.c           | 2 +-
 xen/drivers/char/scif-uart.c       | 2 +-
 xen/drivers/char/serial.c          | 2 +-
 xen/include/xen/serial.h           | 2 +-
 8 files changed, 8 insertions(+), 8 deletions(-)
xen/arch/arm/vuart.c +1 -1
index b5c9288..6619b33 100644
@@ -59,7 +59,7 @@ int domain_vuart_init(struct domain *d)
 {
     ASSERT( is_hardware_domain(d) );
 
-    d->arch.vuart.info = serial_vuart_info(SERHND_DTUART);
+    d->arch.vuart.info = serial_vuart_info(SERHND_UART);
     if ( !d->arch.vuart.info )
         return 0;
 
xen/drivers/char/cadence-uart.c +1 -1
index 933672f..ed65004 100644
@@ -196,7 +196,7 @@ static int __init cuart_init(struct dt_device_node *dev, const void *data)
     uart->vuart.status = UART_SR_INTR_TEMPTY;
 
     /* Register with generic serial driver. */
-    serial_register_uart(SERHND_DTUART, &cuart_driver, uart);
+    serial_register_uart(SERHND_UART, &cuart_driver, uart);
 
     dt_device_set_used_by(dev, DOMID_XEN);
 
xen/drivers/char/exynos4210-uart.c +1 -1
index bac1c2b..43f5313 100644
@@ -345,7 +345,7 @@ static int __init exynos4210_uart_init(struct dt_device_node *dev,
     uart->vuart.status = UTRSTAT_TXE | UTRSTAT_TXFE;
 
     /* Register with generic serial driver. */
-    serial_register_uart(SERHND_DTUART, &exynos4210_uart_driver, uart);
+    serial_register_uart(SERHND_UART, &exynos4210_uart_driver, uart);
 
     dt_device_set_used_by(dev, DOMID_XEN);
 
xen/drivers/char/omap-uart.c +1 -1
index d8f64ea..98c3892 100644
@@ -343,7 +343,7 @@ static int __init omap_uart_init(struct dt_device_node *dev,
     uart->vuart.status = UART_LSR_THRE;
 
     /* Register with generic serial driver */
-    serial_register_uart(SERHND_DTUART, &omap_uart_driver, uart);
+    serial_register_uart(SERHND_UART, &omap_uart_driver, uart);
 
     dt_device_set_used_by(dev, DOMID_XEN);
 
xen/drivers/char/pl011.c +1 -1
index 16abaa5..1efb1cf 100644
@@ -252,7 +252,7 @@ static int __init pl011_uart_init(int irq, u64 addr, u64 size)
     uart->vuart.status = 0;
 
     /* Register with generic serial driver. */
-    serial_register_uart(SERHND_DTUART, &pl011_driver, uart);
+    serial_register_uart(SERHND_UART, &pl011_driver, uart);
 
     return 0;
 }
xen/drivers/char/scif-uart.c +1 -1
index 51a2233..739317c 100644
@@ -339,7 +339,7 @@ static int __init scif_uart_init(struct dt_device_node *dev,
     uart->vuart.status     = SCFSR_TDFE;
 
     /* Register with generic serial driver */
-    serial_register_uart(SERHND_DTUART, &scif_uart_driver, uart);
+    serial_register_uart(SERHND_UART, &scif_uart_driver, uart);
 
     dt_device_set_used_by(dev, DOMID_XEN);
 
xen/drivers/char/serial.c +1 -1
index c583a48..659e10d 100644
@@ -312,7 +312,7 @@ int __init serial_parse_handle(char *conf)
 
     if ( !strncmp(conf, "dtuart", 5) )
     {
-        handle = SERHND_DTUART;
+        handle = SERHND_UART;
         goto common;
     }
 
xen/include/xen/serial.h +1 -1
index 5e1a536..a6e7c22 100644
@@ -94,7 +94,7 @@ struct uart_driver {
 # define SERHND_COM1    (0<<0)
 # define SERHND_COM2    (1<<0)
 # define SERHND_DBGP    (2<<0)
-# define SERHND_DTUART  (0<<0) /* Steal SERHND_COM1 value */
+# define SERHND_UART    (0<<0) /* Steal SERHND_COM1 value */
 #define SERHND_HI       (1<<2) /* Mux/demux each transferred char by MSB. */
 #define SERHND_LO       (1<<3) /* Ditto, except that the MSB is cleared.  */
 #define SERHND_COOKED   (1<<4) /* Newline/carriage-return translation?    */
Signature · 7 lines
2.1.0


_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
#181 lore raw

PATCH v3 36/62 arm/acpi: Initialize serial port from ACPI SPCR table

In reply to shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

Parse ACPI SPCR (Serial Port Console Redirection table) table and initialize the serial port pl011.

---
 xen/drivers/char/pl011.c  | 37 +++++++++++++++++++++++++++++++++++++
 xen/include/acpi/actbl2.h |  5 +++++
 2 files changed, 42 insertions(+)
xen/drivers/char/pl011.c +37 -0
index 1efb1cf..7106f1c 100644
@@ -27,6 +27,7 @@
 #include <asm/device.h>
 #include <xen/mm.h>
 #include <xen/vmap.h>
+#include <xen/acpi.h>
 #include <asm/pl011-uart.h>
 #include <asm/io.h>
 
@@ -308,6 +309,42 @@ DT_DEVICE_START(pl011, "PL011 UART", DEVICE_SERIAL)
         .init = dt_pl011_uart_init,
 DT_DEVICE_END
 
+#ifdef CONFIG_ACPI
+static int __init acpi_pl011_uart_init(const void *data)
+{
+    acpi_status status;
+    struct acpi_table_spcr *spcr=NULL;
+    int res;
+
+    status = acpi_get_table(ACPI_SIG_SPCR, 0,
+                            (struct acpi_table_header **)&spcr);
+
+    if ( ACPI_FAILURE(status) )
+    {
+        printk("pl011: Failed to get SPCR table\n");
+        return -EINVAL;
+    }
+
+    /* trigger/polarity information is not available in spcr */
+    irq_set_type(spcr->interrupt, ACPI_IRQ_TYPE_EDGE_BOTH);
+
+    res = pl011_uart_init(spcr->interrupt, spcr->serial_port.address,
+                          PAGE_SIZE);
+    if ( res < 0 )
+    {
+        printk("pl011: Unable to initialize\n");
+        return res;
+    }
+
+    return 0;
+}
+
+ACPI_DEVICE_START(apl011, "PL011 UART", DEVICE_SERIAL)
+        .class_type = ACPI_SPCR_TYPE_PL011,
+        .init = acpi_pl011_uart_init,
+ACPI_DEVICE_END
+#endif
+
 /*
  * Local variables:
  * mode: C
xen/include/acpi/actbl2.h +5 -0
index 87bc6b3..25be429 100644
@@ -815,6 +815,11 @@ struct acpi_table_spcr {
 
 #define ACPI_SPCR_DO_NOT_DISABLE    (1)
 
+/* UART Interface type */
+#define ACPI_SPCR_TYPE_16550 0
+#define ACPI_SPCR_TYPE_16550_SUB 1
+#define ACPI_SPCR_TYPE_PL011 3
+
 /*******************************************************************************
  *
  * SPMI - Server Platform Management Interface table
Signature · 1 line
2.1.0
#182 lore raw

PATCH v3 36/62 arm/acpi: Initialize serial port from ACPI SPCR table

Quoted 26 lines · shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

Parse ACPI SPCR (Serial Port Console Redirection table) table and initialize the serial port pl011.

---
 xen/drivers/char/pl011.c  | 37 +++++++++++++++++++++++++++++++++++++
 xen/include/acpi/actbl2.h |  5 +++++
 2 files changed, 42 insertions(+)
xen/drivers/char/pl011.c +1 -0
index 1efb1cf..7106f1c 100644
@@ -27,6 +27,7 @@
 #include <asm/device.h>
 #include <xen/mm.h>
 #include <xen/vmap.h>
+#include <xen/acpi.h>
 #include <asm/pl011-uart.h>
 #include <asm/io.h>
 

xen/drivers/char/pl011.c DT_DEVICE_START(pl011, "PL011 UART", DEVICE_SERIAL) · line 316

Quoted 8 lines
xen/drivers/char/pl011.c +5 -0
@@ -308,6 +309,42 @@ DT_DEVICE_START(pl011, "PL011 UART", DEVICE_SERIAL)
         .init = dt_pl011_uart_init,
 DT_DEVICE_END
 
+#ifdef CONFIG_ACPI
+static int __init acpi_pl011_uart_init(const void *data)
+{
+    acpi_status status;
+    struct acpi_table_spcr *spcr=NULL;

coding style

Quoted 39 lines
xen/drivers/char/pl011.c +31 -0
+    int res;
+
+    status = acpi_get_table(ACPI_SIG_SPCR, 0,
+                            (struct acpi_table_header **)&spcr);
+
+    if ( ACPI_FAILURE(status) )
+    {
+        printk("pl011: Failed to get SPCR table\n");
+        return -EINVAL;
+    }
+
+    /* trigger/polarity information is not available in spcr */
+    irq_set_type(spcr->interrupt, ACPI_IRQ_TYPE_EDGE_BOTH);
+
+    res = pl011_uart_init(spcr->interrupt, spcr->serial_port.address,
+                          PAGE_SIZE);
+    if ( res < 0 )
+    {
+        printk("pl011: Unable to initialize\n");
+        return res;
+    }
+
+    return 0;
+}
+
+ACPI_DEVICE_START(apl011, "PL011 UART", DEVICE_SERIAL)
+        .class_type = ACPI_SPCR_TYPE_PL011,
+        .init = acpi_pl011_uart_init,
+ACPI_DEVICE_END
+#endif
+
 /*
  * Local variables:
  * mode: C
xen/include/acpi/actbl2.h +0 -0
index 87bc6b3..25be429 100644

xen/include/acpi/actbl2.h struct acpi_table_spcr { · line 821

Quoted 7 lines
xen/include/acpi/actbl2.h +4 -0
@@ -815,6 +815,11 @@ struct acpi_table_spcr {
 
 #define ACPI_SPCR_DO_NOT_DISABLE    (1)
 
+/* UART Interface type */
+#define ACPI_SPCR_TYPE_16550 0
+#define ACPI_SPCR_TYPE_16550_SUB 1
+#define ACPI_SPCR_TYPE_PL011 3

Since you are at it, please also add the other fields as specified in the DBG2.

Quoted 6 lines
xen/include/acpi/actbl2.h +0 -0
 /*******************************************************************************
  *
  * SPMI - Server Platform Management Interface table
Signature · 1 line
2.1.0
#183 lore raw

Re: [PATCH v3 36/62] arm/acpi: Initialize serial port from ACPI SPCR table

In reply to shannon.zhao at linaro.org
Quoted 26 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Parth Dixit <[email protected]>

Parse ACPI SPCR (Serial Port Console Redirection table) table and initialize the serial port pl011.

---
 xen/drivers/char/pl011.c  | 37 +++++++++++++++++++++++++++++++++++++
 xen/include/acpi/actbl2.h |  5 +++++
 2 files changed, 42 insertions(+)
xen/drivers/char/pl011.c +1 -0
index 1efb1cf..7106f1c 100644
@@ -27,6 +27,7 @@
 #include <asm/device.h>
 #include <xen/mm.h>
 #include <xen/vmap.h>
+#include <xen/acpi.h>
 #include <asm/pl011-uart.h>
 #include <asm/io.h>
 

xen/drivers/char/pl011.c DT_DEVICE_START(pl011, "PL011 UART", DEVICE_SERIAL) · line 316

Quoted 8 lines
xen/drivers/char/pl011.c +5 -0
@@ -308,6 +309,42 @@ DT_DEVICE_START(pl011, "PL011 UART", DEVICE_SERIAL)
         .init = dt_pl011_uart_init,
 DT_DEVICE_END
 
+#ifdef CONFIG_ACPI
+static int __init acpi_pl011_uart_init(const void *data)
+{
+    acpi_status status;
+    struct acpi_table_spcr *spcr=NULL;

coding style

Quoted 39 lines
xen/drivers/char/pl011.c +31 -0
+    int res;
+
+    status = acpi_get_table(ACPI_SIG_SPCR, 0,
+                            (struct acpi_table_header **)&spcr);
+
+    if ( ACPI_FAILURE(status) )
+    {
+        printk("pl011: Failed to get SPCR table\n");
+        return -EINVAL;
+    }
+
+    /* trigger/polarity information is not available in spcr */
+    irq_set_type(spcr->interrupt, ACPI_IRQ_TYPE_EDGE_BOTH);
+
+    res = pl011_uart_init(spcr->interrupt, spcr->serial_port.address,
+                          PAGE_SIZE);
+    if ( res < 0 )
+    {
+        printk("pl011: Unable to initialize\n");
+        return res;
+    }
+
+    return 0;
+}
+
+ACPI_DEVICE_START(apl011, "PL011 UART", DEVICE_SERIAL)
+        .class_type = ACPI_SPCR_TYPE_PL011,
+        .init = acpi_pl011_uart_init,
+ACPI_DEVICE_END
+#endif
+
 /*
  * Local variables:
  * mode: C
xen/include/acpi/actbl2.h +0 -0
index 87bc6b3..25be429 100644

xen/include/acpi/actbl2.h struct acpi_table_spcr { · line 821

Quoted 7 lines
xen/include/acpi/actbl2.h +4 -0
@@ -815,6 +815,11 @@ struct acpi_table_spcr {
 
 #define ACPI_SPCR_DO_NOT_DISABLE    (1)
 
+/* UART Interface type */
+#define ACPI_SPCR_TYPE_16550 0
+#define ACPI_SPCR_TYPE_16550_SUB 1
+#define ACPI_SPCR_TYPE_PL011 3

Since you are at it, please also add the other fields as specified in the DBG2.

Quoted 6 lines
xen/include/acpi/actbl2.h +0 -0
 /*******************************************************************************
  *
  * SPMI - Server Platform Management Interface table
Signature · 1 line
2.1.0
#184 lore raw

PATCH v3 37/62 arm/acpi: Define a enum for reserved tables

In reply to shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

It needs to copy and change the contents of some ACPI and EFI tables for Dom0. Here define a enum for those tables.

---
 xen/include/asm-arm/acpi.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)
xen/include/asm-arm/acpi.h +12 -0
index 214fc4e..f159d51 100644
@@ -30,6 +30,18 @@
 
 extern bool_t acpi_disabled;
 
+/* Tables marked as reserved in efi table */
+typedef enum {
+    TBL_FADT,
+    TBL_MADT,
+    TBL_STAO,
+    TBL_XSDT,
+    TBL_RSDP,
+    TBL_EFIT,
+    TBL_MMAP,
+    TBL_MMAX,
+} EFI_MEM_RES;
+
 #ifdef CONFIG_ACPI
 bool_t __init acpi_psci_present(void);
 bool_t __init acpi_psci_hvc_present(void);
Signature · 1 line
2.1.0
#185 lore raw

PATCH v3 37/62 arm/acpi: Define a enum for reserved tables

Quoted 20 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

It needs to copy and change the contents of some ACPI and EFI tables for Dom0. Here define a enum for those tables.

---
 xen/include/asm-arm/acpi.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)
xen/include/asm-arm/acpi.h +1 -0
index 214fc4e..f159d51 100644
@@ -30,6 +30,18 @@
 
 extern bool_t acpi_disabled;
 
+/* Tables marked as reserved in efi table */

xen/include/asm-arm/acpi.h line 43

Quoted 10 lines
xen/include/asm-arm/acpi.h +10 -0
+typedef enum {
+    TBL_FADT,
+    TBL_MADT,
+    TBL_STAO,
+    TBL_XSDT,
+    TBL_RSDP,
+    TBL_EFIT,
+    TBL_MMAP,
+    TBL_MMAX,
+} EFI_MEM_RES;

Given that in later patches you are using the enum as integer, you should initialize each value explicitly.

Quoted 12 lines
xen/include/asm-arm/acpi.h +0 -0
 #ifdef CONFIG_ACPI
 bool_t __init acpi_psci_present(void);
 bool_t __init acpi_psci_hvc_present(void);
Signature · 7 lines
2.1.0


_______________________________________________
Xen-devel mailing list
Xen-devel at lists.xen.org
http://lists.xen.org/xen-devel
#186 lore raw

PATCH v3 37/62 arm/acpi: Define a enum for reserved tables

Quoted 20 lines · Stefano Stabellini
Quoted 19 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

It needs to copy and change the contents of some ACPI and EFI tables for Dom0. Here define a enum for those tables.

---
 xen/include/asm-arm/acpi.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)
xen/include/asm-arm/acpi.h +0 -0
index 214fc4e..f159d51 100644
@@ -30,6 +30,18 @@
 
 extern bool_t acpi_disabled;
 
Quoted 14 lines

xen/include/asm-arm/acpi.h line 43

Quoted 11 lines
xen/include/asm-arm/acpi.h +11 -0
+/* Tables marked as reserved in efi table */
+typedef enum {
+    TBL_FADT,
+    TBL_MADT,
+    TBL_STAO,
+    TBL_XSDT,
+    TBL_RSDP,
+    TBL_EFIT,
+    TBL_MMAP,
+    TBL_MMAX,
+} EFI_MEM_RES;

Given that in later patches you are using the enum as integer, you should initialize each value explicitly.

It turns out that actually enums are guaranteed to start from 0, so there is no need for an explicit initialization.

Quoted 13 lines
Quoted 12 lines
xen/include/asm-arm/acpi.h +0 -0
 #ifdef CONFIG_ACPI
 bool_t __init acpi_psci_present(void);
 bool_t __init acpi_psci_hvc_present(void);
Signature · 7 lines
2.1.0


_______________________________________________
Xen-devel mailing list
Xen-devel at lists.xen.org
http://lists.xen.org/xen-devel
#187 lore raw

Re: [PATCH v3 37/62] arm/acpi: Define a enum for reserved tables

In reply to Stefano Stabellini
Quoted 20 lines · Stefano Stabellini
Quoted 19 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Shannon Zhao <[email protected]>

It needs to copy and change the contents of some ACPI and EFI tables for Dom0. Here define a enum for those tables.

---
 xen/include/asm-arm/acpi.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)
xen/include/asm-arm/acpi.h +0 -0
index 214fc4e..f159d51 100644
@@ -30,6 +30,18 @@
 
 extern bool_t acpi_disabled;
 
Quoted 14 lines

xen/include/asm-arm/acpi.h line 43

Quoted 11 lines
xen/include/asm-arm/acpi.h +11 -0
+/* Tables marked as reserved in efi table */
+typedef enum {
+    TBL_FADT,
+    TBL_MADT,
+    TBL_STAO,
+    TBL_XSDT,
+    TBL_RSDP,
+    TBL_EFIT,
+    TBL_MMAP,
+    TBL_MMAX,
+} EFI_MEM_RES;

Given that in later patches you are using the enum as integer, you should initialize each value explicitly.

It turns out that actually enums are guaranteed to start from 0, so there is no need for an explicit initialization.

Quoted 13 lines
Quoted 12 lines
xen/include/asm-arm/acpi.h +0 -0
 #ifdef CONFIG_ACPI
 bool_t __init acpi_psci_present(void);
 bool_t __init acpi_psci_hvc_present(void);
Signature · 7 lines
2.1.0


_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
#188 lore raw

Re: [PATCH v3 37/62] arm/acpi: Define a enum for reserved tables

In reply to shannon.zhao at linaro.org
Quoted 20 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Shannon Zhao <[email protected]>

It needs to copy and change the contents of some ACPI and EFI tables for Dom0. Here define a enum for those tables.

---
 xen/include/asm-arm/acpi.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)
xen/include/asm-arm/acpi.h +1 -0
index 214fc4e..f159d51 100644
@@ -30,6 +30,18 @@
 
 extern bool_t acpi_disabled;
 
+/* Tables marked as reserved in efi table */

xen/include/asm-arm/acpi.h line 43

Quoted 10 lines
xen/include/asm-arm/acpi.h +10 -0
+typedef enum {
+    TBL_FADT,
+    TBL_MADT,
+    TBL_STAO,
+    TBL_XSDT,
+    TBL_RSDP,
+    TBL_EFIT,
+    TBL_MMAP,
+    TBL_MMAX,
+} EFI_MEM_RES;

Given that in later patches you are using the enum as integer, you should initialize each value explicitly.

Quoted 12 lines
xen/include/asm-arm/acpi.h +0 -0
 #ifdef CONFIG_ACPI
 bool_t __init acpi_psci_present(void);
 bool_t __init acpi_psci_hvc_present(void);
Signature · 7 lines
2.1.0


_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
#189 lore raw

PATCH v3 38/62 arm/acpi: Add placeholder for efi and acpi load address

In reply to shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

EFI table, memory description table and some of acpi tables will be placed after DOM0 memory space. Add placeholder for the starting address for loading in DOM0 and the size of new added tables. Also add a placeholder to store the new created tables.

---
 xen/include/asm-arm/domain.h | 5 +++++
 1 file changed, 5 insertions(+)
xen/include/asm-arm/domain.h +5 -0
index 1e61f30..91272e5 100644
@@ -125,6 +125,11 @@ struct arch_domain
     } vuart;
 
     unsigned int evtchn_irq;
+#ifdef CONFIG_ACPI
+    void *efi_acpi_table;
+    paddr_t efi_acpi_gpa;
+    paddr_t efi_acpi_len;
+#endif
 }  __cacheline_aligned;
 
 struct arch_vcpu
Signature · 1 line
2.1.0
#190 lore raw

PATCH v3 38/62 arm/acpi: Add placeholder for efi and acpi load address

Hi Shannon,

Quoted 18 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

EFI table, memory description table and some of acpi tables will be placed after DOM0 memory space. Add placeholder for the starting address for loading in DOM0 and the size of new added tables. Also add a placeholder to store the new created tables.

---
 xen/include/asm-arm/domain.h | 5 +++++
 1 file changed, 5 insertions(+)
xen/include/asm-arm/domain.h +0 -0
index 1e61f30..91272e5 100644

xen/include/asm-arm/domain.h struct arch_domain · line 132

Quoted 8 lines
xen/include/asm-arm/domain.h +5 -0
@@ -125,6 +125,11 @@ struct arch_domain
     } vuart;
 
     unsigned int evtchn_irq;
+#ifdef CONFIG_ACPI
+    void *efi_acpi_table;
+    paddr_t efi_acpi_gpa;
+    paddr_t efi_acpi_len;
+#endif

Why do you need this in the arch_domain? AFAICT those 3 variables should only be used while building DOM0, so a better place would be in struct kernel_info (see xen/arch/arm/kernel.h).

xen/include/asm-arm/domain.h struct arch_domain · line 135

Quoted 4 lines
xen/include/asm-arm/domain.h +0 -0
 }  __cacheline_aligned;
 
 struct arch_vcpu

Regards,

Signature · 1 line
Julien Grall
#191 lore raw

PATCH v3 38/62 arm/acpi: Add placeholder for efi and acpi load address

Quoted 23 lines · Julien Grall

Hi Shannon,

Quoted 20 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

EFI table, memory description table and some of acpi tables will be placed after DOM0 memory space. Add placeholder for the starting address for loading in DOM0 and the size of new added tables. Also add a placeholder to store the new created tables.

---
 xen/include/asm-arm/domain.h | 5 +++++
 1 file changed, 5 insertions(+)
xen/include/asm-arm/domain.h +0 -0
index 1e61f30..91272e5 100644
@@ -125,6 +125,11 @@ struct arch_domain
     } vuart;
 
Quoted 11 lines

xen/include/asm-arm/domain.h struct arch_domain · line 132

Quoted 6 lines
xen/include/asm-arm/domain.h +5 -0
     unsigned int evtchn_irq;
+#ifdef CONFIG_ACPI
+    void *efi_acpi_table;
+    paddr_t efi_acpi_gpa;
+    paddr_t efi_acpi_len;
+#endif

Why do you need this in the arch_domain? AFAICT those 3 variables should only be used while building DOM0, so a better place would be in struct kernel_info (see xen/arch/arm/kernel.h).

Since I use efi_acpi_table to store the allocated pages pointer which are used to store newly created ACPI and EFI tables.
See [PATCH v3 40/62]:
+ order = get_order_from_bytes(d->arch.efi_acpi_len);
+ d->arch.efi_acpi_table = alloc_xenheap_pages(order, 0);

And it free these pages when destroying this domain:
+#ifdef CONFIG_ACPI
+ free_xenheap_pages(d->arch.efi_acpi_table,
+ get_order_from_bytes(d->arch.efi_acpi_len));
+#endif

efi_acpi_gpa might not need.

Thanks,

Signature · 1 line
Shannon
#192 lore raw

PATCH v3 38/62 arm/acpi: Add placeholder for efi and acpi load address

Hi Shannon,

Quoted 45 lines · Shannon Zhao
Quoted 23 lines · Julien Grall

Hi Shannon,

Quoted 20 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

EFI table, memory description table and some of acpi tables will be placed after DOM0 memory space. Add placeholder for the starting address for loading in DOM0 and the size of new added tables. Also add a placeholder to store the new created tables.

---
 xen/include/asm-arm/domain.h | 5 +++++
 1 file changed, 5 insertions(+)
xen/include/asm-arm/domain.h +0 -0
index 1e61f30..91272e5 100644
@@ -125,6 +125,11 @@ struct arch_domain
     } vuart;
 
Quoted 11 lines

xen/include/asm-arm/domain.h struct arch_domain · line 132

Quoted 6 lines
xen/include/asm-arm/domain.h +5 -0
     unsigned int evtchn_irq;
+#ifdef CONFIG_ACPI
+    void *efi_acpi_table;
+    paddr_t efi_acpi_gpa;
+    paddr_t efi_acpi_len;
+#endif

Why do you need this in the arch_domain? AFAICT those 3 variables should only be used while building DOM0, so a better place would be in struct kernel_info (see xen/arch/arm/kernel.h).

Since I use efi_acpi_table to store the allocated pages pointer which are used to store newly created ACPI and EFI tables.
See [PATCH v3 40/62]:

(quoted diff) +2 -0
+    order = get_order_from_bytes(d->arch.efi_acpi_len);
+    d->arch.efi_acpi_table = alloc_xenheap_pages(order, 0);

And it free these pages when destroying this domain:

xen/include/asm-arm/domain.h struct arch_domain · line 132

Quoted 4 lines
xen/include/asm-arm/domain.h +4 -0
+#ifdef CONFIG_ACPI
+    free_xenheap_pages(d->arch.efi_acpi_table,
+                       get_order_from_bytes(d->arch.efi_acpi_len));
+#endif

But this is wrong. You are assuming that DOM0 memory is direct mapped which may not be true in the future.

You should have at least mentioned that in the commit message.

Regards,

Signature · 1 line
Julien Grall
#193 lore raw

PATCH v3 38/62 arm/acpi: Add placeholder for efi and acpi load address

Quoted 47 lines · Julien Grall

Hi Shannon,

Quoted 44 lines · Shannon Zhao
Quoted 23 lines · Julien Grall

Hi Shannon,

Quoted 20 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

EFI table, memory description table and some of acpi tables will be placed after DOM0 memory space. Add placeholder for the starting address for loading in DOM0 and the size of new added tables. Also add a placeholder to store the new created tables.

---
 xen/include/asm-arm/domain.h | 5 +++++
 1 file changed, 5 insertions(+)
xen/include/asm-arm/domain.h +0 -0
index 1e61f30..91272e5 100644
@@ -125,6 +125,11 @@ struct arch_domain
     } vuart;
 
Quoted 11 lines

xen/include/asm-arm/domain.h struct arch_domain · line 132

Quoted 6 lines
xen/include/asm-arm/domain.h +5 -0
     unsigned int evtchn_irq;
+#ifdef CONFIG_ACPI
+    void *efi_acpi_table;
+    paddr_t efi_acpi_gpa;
+    paddr_t efi_acpi_len;
+#endif

Why do you need this in the arch_domain? AFAICT those 3 variables should only be used while building DOM0, so a better place would be in struct kernel_info (see xen/arch/arm/kernel.h).

Since I use efi_acpi_table to store the allocated pages pointer which are used to store newly created ACPI and EFI tables.
See [PATCH v3 40/62]:

(quoted diff) +2 -0
+    order = get_order_from_bytes(d->arch.efi_acpi_len);
+    d->arch.efi_acpi_table = alloc_xenheap_pages(order, 0);
Quoted 9 lines

xen/include/asm-arm/domain.h struct arch_domain · line 132

Quoted 5 lines

And it free these pages when destroying this domain:

xen/include/asm-arm/domain.h +4 -0
+#ifdef CONFIG_ACPI
+    free_xenheap_pages(d->arch.efi_acpi_table,
+                       get_order_from_bytes(d->arch.efi_acpi_len));
+#endif

But this is wrong. You are assuming that DOM0 memory is direct mapped which may not be true in the future.

I think we have discussed this when we discussed the design doc.

"All above tables will be mapped to Dom0 non-RAM space. Since when booting through ACPI it doesn't need the grant table region(see below section 3), it could use this region to store the tables or use the same way to find one memory region to store them."

Firstly, as Jan suggested, these tables should not be in RAM space, so we drop the previous way that copying these tables to Dom0 RAM. Then I suggested map these tables to the space after the Dom0 RAM space, but this not right because Dom0 RAM region might be at the edge of physical RAM space and there might be device MMIO regions. Then you suggest it could map these tables to the region which is used for grant table(or the region found by the same way) while it's not used when it boots with ACPI. These regions are not used by Xen and will not be used by Dom0 either currently. But as you say, it will be wrong if Dom0 memory is not 1:1 mapped.

So how about below idea:
We still copy these tables to Dom0 RAM space but when we create EFI_MMAP_TABLE, we remove the space occupied by these tables from the EfiConventionalMemory descriptor.

Thanks,
--
Shannon

#194 lore raw

PATCH v3 38/62 arm/acpi: Add placeholder for efi and acpi load address

Quoted 5 lines · Shannon Zhao

"All above tables will be mapped to Dom0 non-RAM space. Since when booting through ACPI it doesn't need the grant table region(see below section 3), it could use this region to store the tables or use the same way to find one memory region to store them."

Quoted 10 lines

Firstly, as Jan suggested, these tables should not be in RAM space, so we drop the previous way that copying these tables to Dom0 RAM. Then I suggested map these tables to the space after the Dom0 RAM space, but this not right because Dom0 RAM region might be at the edge of physical RAM space and there might be device MMIO regions. Then you suggest it could map these tables to the region which is used for grant table(or the region found by the same way) while it's not used when it boots with ACPI. These regions are not used by Xen and will not be used by Dom0 either currently. But as you say, it will be wrong if Dom0 memory is not 1:1 mapped.

Will you remember in 6 months why you wrote the code like that?

My point on the previous mail is you don't describe what you did, neither in the code nor in the commit message.

Most of the place in the code are trying to avoid the assumption that DOM0 is using direct mapped. If not, we always have a comment/commit message explaining why we are doing like that and the implication (see the grant table example [1]).

Quoted 4 lines

So how about below idea:
We still copy these tables to Dom0 RAM space but when we create EFI_MMAP_TABLE, we remove the space occupied by these tables from the EfiConventionalMemory descriptor.

As you don't need the grant table region, why don't you re-use it fopr your tables? It may also be possible that we have some space just after for the EFI table.

Regards,

[1]
http://xenbits.xen.org/gitweb/?p=xen.git;a=commit;h=7e02c881606eb94f177becfa284494d89a3dba2e

Signature · 1 line
Julien Grall
#195 lore raw

PATCH v3 38/62 arm/acpi: Add placeholder for efi and acpi load address

Quoted 27 lines · Julien Grall
Quoted 5 lines · Shannon Zhao

"All above tables will be mapped to Dom0 non-RAM space. Since when booting through ACPI it doesn't need the grant table region(see below section 3), it could use this region to store the tables or use the same way to find one memory region to store them."

Quoted 10 lines

Firstly, as Jan suggested, these tables should not be in RAM space, so we drop the previous way that copying these tables to Dom0 RAM. Then I suggested map these tables to the space after the Dom0 RAM space, but this not right because Dom0 RAM region might be at the edge of physical RAM space and there might be device MMIO regions. Then you suggest it could map these tables to the region which is used for grant table(or the region found by the same way) while it's not used when it boots with ACPI. These regions are not used by Xen and will not be used by Dom0 either currently. But as you say, it will be wrong if Dom0 memory is not 1:1 mapped.

Will you remember in 6 months why you wrote the code like that?

My point on the previous mail is you don't describe what you did, neither in the code nor in the commit message.

Most of the place in the code are trying to avoid the assumption that DOM0 is using direct mapped. If not, we always have a comment/commit message explaining why we are doing like that and the implication (see the grant table example [1]).

Quoted 8 lines
Quoted 4 lines

So how about below idea:
We still copy these tables to Dom0 RAM space but when we create EFI_MMAP_TABLE, we remove the space occupied by these tables from the EfiConventionalMemory descriptor.

As you don't need the grant table region, why don't you re-use it fopr your tables? It may also be possible that we have some space just after for the EFI table.

I think that the current approach is good, please just extend the in-code comment in patch #40.

#196 lore raw

PATCH v3 38/62 arm/acpi: Add placeholder for efi and acpi load address

Hi Stefano,

Quoted 33 lines · Stefano Stabellini
Quoted 32 lines · Julien Grall
Quoted 5 lines · Shannon Zhao

"All above tables will be mapped to Dom0 non-RAM space. Since when booting through ACPI it doesn't need the grant table region(see below section 3), it could use this region to store the tables or use the same way to find one memory region to store them."

Quoted 10 lines

Firstly, as Jan suggested, these tables should not be in RAM space, so we drop the previous way that copying these tables to Dom0 RAM. Then I suggested map these tables to the space after the Dom0 RAM space, but this not right because Dom0 RAM region might be at the edge of physical RAM space and there might be device MMIO regions. Then you suggest it could map these tables to the region which is used for grant table(or the region found by the same way) while it's not used when it boots with ACPI. These regions are not used by Xen and will not be used by Dom0 either currently. But as you say, it will be wrong if Dom0 memory is not 1:1 mapped.

Will you remember in 6 months why you wrote the code like that?

My point on the previous mail is you don't describe what you did, neither in the code nor in the commit message.

Most of the place in the code are trying to avoid the assumption that DOM0 is using direct mapped. If not, we always have a comment/commit message explaining why we are doing like that and the implication (see the grant table example [1]).

Quoted 4 lines

So how about below idea:
We still copy these tables to Dom0 RAM space but when we create EFI_MMAP_TABLE, we remove the space occupied by these tables from the EfiConventionalMemory descriptor.

Quoted 6 lines
Quoted 3 lines

As you don't need the grant table region, why don't you re-use it fopr your tables? It may also be possible that we have some space just after for the EFI table.

I think that the current approach is good, please just extend the in-code comment in patch #40.

In fact my suggestion was wrong :/. We need real memory for EFI/ACPI placeholder.

Regards,

Signature · 1 line
Julien Grall
#197 lore raw

Re: [PATCH v3 38/62] arm/acpi: Add placeholder for efi and acpi load address

In reply to Julien Grall
Quoted 27 lines · Julien Grall
Quoted 5 lines · Shannon Zhao

"All above tables will be mapped to Dom0 non-RAM space. Since when booting through ACPI it doesn't need the grant table region(see below section 3), it could use this region to store the tables or use the same way to find one memory region to store them."

Quoted 10 lines

Firstly, as Jan suggested, these tables should not be in RAM space, so we drop the previous way that copying these tables to Dom0 RAM. Then I suggested map these tables to the space after the Dom0 RAM space, but this not right because Dom0 RAM region might be at the edge of physical RAM space and there might be device MMIO regions. Then you suggest it could map these tables to the region which is used for grant table(or the region found by the same way) while it's not used when it boots with ACPI. These regions are not used by Xen and will not be used by Dom0 either currently. But as you say, it will be wrong if Dom0 memory is not 1:1 mapped.

Will you remember in 6 months why you wrote the code like that?

My point on the previous mail is you don't describe what you did, neither in the code nor in the commit message.

Most of the place in the code are trying to avoid the assumption that DOM0 is using direct mapped. If not, we always have a comment/commit message explaining why we are doing like that and the implication (see the grant table example [1]).

Quoted 8 lines
Quoted 4 lines

So how about below idea:
We still copy these tables to Dom0 RAM space but when we create EFI_MMAP_TABLE, we remove the space occupied by these tables from the EfiConventionalMemory descriptor.

As you don't need the grant table region, why don't you re-use it fopr your tables? It may also be possible that we have some space just after for the EFI table.

I think that the current approach is good, please just extend the in-code comment in patch #40.

#198 lore raw

Re: [PATCH v3 38/62] arm/acpi: Add placeholder for efi and acpi load address

In reply to Shannon Zhao
Quoted 5 lines · Shannon Zhao

"All above tables will be mapped to Dom0 non-RAM space. Since when booting through ACPI it doesn't need the grant table region(see below section 3), it could use this region to store the tables or use the same way to find one memory region to store them."

Quoted 10 lines

Firstly, as Jan suggested, these tables should not be in RAM space, so we drop the previous way that copying these tables to Dom0 RAM. Then I suggested map these tables to the space after the Dom0 RAM space, but this not right because Dom0 RAM region might be at the edge of physical RAM space and there might be device MMIO regions. Then you suggest it could map these tables to the region which is used for grant table(or the region found by the same way) while it's not used when it boots with ACPI. These regions are not used by Xen and will not be used by Dom0 either currently. But as you say, it will be wrong if Dom0 memory is not 1:1 mapped.

Will you remember in 6 months why you wrote the code like that?

My point on the previous mail is you don't describe what you did, neither in the code nor in the commit message.

Most of the place in the code are trying to avoid the assumption that DOM0 is using direct mapped. If not, we always have a comment/commit message explaining why we are doing like that and the implication (see the grant table example [1]).

Quoted 4 lines

So how about below idea:
We still copy these tables to Dom0 RAM space but when we create EFI_MMAP_TABLE, we remove the space occupied by these tables from the EfiConventionalMemory descriptor.

As you don't need the grant table region, why don't you re-use it fopr your tables? It may also be possible that we have some space just after for the EFI table.

Regards,

[1]
http://xenbits.xen.org/gitweb/?p=xen.git;a=commit;h=7e02c881606eb94f177becfa284494d89a3dba2e

Signature · 1 line
Julien Grall
#199 lore raw

Re: [PATCH v3 38/62] arm/acpi: Add placeholder for efi and acpi load address

In reply to Julien Grall
Quoted 47 lines · Julien Grall

Hi Shannon,

Quoted 44 lines · Shannon Zhao
Quoted 23 lines · Julien Grall

Hi Shannon,

Quoted 20 lines · On 17/11/15 09:40, [email protected] wrote:

From: Shannon Zhao <[email protected]>

EFI table, memory description table and some of acpi tables will be placed after DOM0 memory space. Add placeholder for the starting address for loading in DOM0 and the size of new added tables. Also add a placeholder to store the new created tables.

---
 xen/include/asm-arm/domain.h | 5 +++++
 1 file changed, 5 insertions(+)
xen/include/asm-arm/domain.h +0 -0
index 1e61f30..91272e5 100644
@@ -125,6 +125,11 @@ struct arch_domain
     } vuart;
 
Quoted 11 lines

xen/include/asm-arm/domain.h struct arch_domain · line 132

Quoted 6 lines
xen/include/asm-arm/domain.h +5 -0
     unsigned int evtchn_irq;
+#ifdef CONFIG_ACPI
+    void *efi_acpi_table;
+    paddr_t efi_acpi_gpa;
+    paddr_t efi_acpi_len;
+#endif

Why do you need this in the arch_domain? AFAICT those 3 variables should only be used while building DOM0, so a better place would be in struct kernel_info (see xen/arch/arm/kernel.h).

Since I use efi_acpi_table to store the allocated pages pointer which are used to store newly created ACPI and EFI tables.
See [PATCH v3 40/62]:

(quoted diff) +2 -0
+    order = get_order_from_bytes(d->arch.efi_acpi_len);
+    d->arch.efi_acpi_table = alloc_xenheap_pages(order, 0);
Quoted 9 lines

xen/include/asm-arm/domain.h struct arch_domain · line 132

Quoted 5 lines

And it free these pages when destroying this domain:

xen/include/asm-arm/domain.h +4 -0
+#ifdef CONFIG_ACPI
+    free_xenheap_pages(d->arch.efi_acpi_table,
+                       get_order_from_bytes(d->arch.efi_acpi_len));
+#endif

But this is wrong. You are assuming that DOM0 memory is direct mapped which may not be true in the future.

I think we have discussed this when we discussed the design doc.

"All above tables will be mapped to Dom0 non-RAM space. Since when booting through ACPI it doesn't need the grant table region(see below section 3), it could use this region to store the tables or use the same way to find one memory region to store them."

Firstly, as Jan suggested, these tables should not be in RAM space, so we drop the previous way that copying these tables to Dom0 RAM. Then I suggested map these tables to the space after the Dom0 RAM space, but this not right because Dom0 RAM region might be at the edge of physical RAM space and there might be device MMIO regions. Then you suggest it could map these tables to the region which is used for grant table(or the region found by the same way) while it's not used when it boots with ACPI. These regions are not used by Xen and will not be used by Dom0 either currently. But as you say, it will be wrong if Dom0 memory is not 1:1 mapped.

So how about below idea:
We still copy these tables to Dom0 RAM space but when we create EFI_MMAP_TABLE, we remove the space occupied by these tables from the EfiConventionalMemory descriptor.

Thanks,
--
Shannon

#200 lore raw

Re: [PATCH v3 38/62] arm/acpi: Add placeholder for efi and acpi load address

In reply to Shannon Zhao

Hi Shannon,

Quoted 45 lines · Shannon Zhao
Quoted 23 lines · Julien Grall

Hi Shannon,

Quoted 20 lines · On 17/11/15 09:40, [email protected] wrote:

From: Shannon Zhao <[email protected]>

EFI table, memory description table and some of acpi tables will be placed after DOM0 memory space. Add placeholder for the starting address for loading in DOM0 and the size of new added tables. Also add a placeholder to store the new created tables.

---
 xen/include/asm-arm/domain.h | 5 +++++
 1 file changed, 5 insertions(+)
xen/include/asm-arm/domain.h +0 -0
index 1e61f30..91272e5 100644
@@ -125,6 +125,11 @@ struct arch_domain
     } vuart;
 
Quoted 11 lines

xen/include/asm-arm/domain.h struct arch_domain · line 132

Quoted 6 lines
xen/include/asm-arm/domain.h +5 -0
     unsigned int evtchn_irq;
+#ifdef CONFIG_ACPI
+    void *efi_acpi_table;
+    paddr_t efi_acpi_gpa;
+    paddr_t efi_acpi_len;
+#endif

Why do you need this in the arch_domain? AFAICT those 3 variables should only be used while building DOM0, so a better place would be in struct kernel_info (see xen/arch/arm/kernel.h).

Since I use efi_acpi_table to store the allocated pages pointer which are used to store newly created ACPI and EFI tables.
See [PATCH v3 40/62]:

(quoted diff) +2 -0
+    order = get_order_from_bytes(d->arch.efi_acpi_len);
+    d->arch.efi_acpi_table = alloc_xenheap_pages(order, 0);

And it free these pages when destroying this domain:

xen/include/asm-arm/domain.h struct arch_domain · line 132

Quoted 4 lines
xen/include/asm-arm/domain.h +4 -0
+#ifdef CONFIG_ACPI
+    free_xenheap_pages(d->arch.efi_acpi_table,
+                       get_order_from_bytes(d->arch.efi_acpi_len));
+#endif

But this is wrong. You are assuming that DOM0 memory is direct mapped which may not be true in the future.

You should have at least mentioned that in the commit message.

Regards,

Signature · 1 line
Julien Grall
#201 lore raw

PATCH v3 38/62 arm/acpi: Add placeholder for efi and acpi load address

In reply to Shannon Zhao
Quoted 48 lines · Shannon Zhao
Quoted 23 lines · Julien Grall

Hi Shannon,

Quoted 20 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

EFI table, memory description table and some of acpi tables will be placed after DOM0 memory space. Add placeholder for the starting address for loading in DOM0 and the size of new added tables. Also add a placeholder to store the new created tables.

---
 xen/include/asm-arm/domain.h | 5 +++++
 1 file changed, 5 insertions(+)
xen/include/asm-arm/domain.h +0 -0
index 1e61f30..91272e5 100644
@@ -125,6 +125,11 @@ struct arch_domain
     } vuart;
 
Quoted 11 lines

xen/include/asm-arm/domain.h struct arch_domain · line 132

Quoted 6 lines
xen/include/asm-arm/domain.h +5 -0
     unsigned int evtchn_irq;
+#ifdef CONFIG_ACPI
+    void *efi_acpi_table;
+    paddr_t efi_acpi_gpa;
+    paddr_t efi_acpi_len;
+#endif

Why do you need this in the arch_domain? AFAICT those 3 variables should only be used while building DOM0, so a better place would be in struct kernel_info (see xen/arch/arm/kernel.h).

Since I use efi_acpi_table to store the allocated pages pointer which are used to store newly created ACPI and EFI tables.
See [PATCH v3 40/62]:

(quoted diff) +2 -0
+    order = get_order_from_bytes(d->arch.efi_acpi_len);
+    d->arch.efi_acpi_table = alloc_xenheap_pages(order, 0);

And it free these pages when destroying this domain:

xen/include/asm-arm/domain.h +4 -0
+#ifdef CONFIG_ACPI
+    free_xenheap_pages(d->arch.efi_acpi_table,
+                       get_order_from_bytes(d->arch.efi_acpi_len));
+#endif
Quoted 1 line

efi_acpi_gpa might not need.

If you need to free the memory at domain destruction, it could make sense to store the pointer in struct arch_domain, even if it only happens for dom0. However you could come up with a single struct and add a pointer to it in arch_domain to limit the per-domain overhead.

#202 lore raw

Re: [PATCH v3 38/62] arm/acpi: Add placeholder for efi and acpi load address

In reply to Shannon Zhao
Quoted 48 lines · Shannon Zhao
Quoted 23 lines · Julien Grall

Hi Shannon,

Quoted 20 lines · On 17/11/15 09:40, [email protected] wrote:

From: Shannon Zhao <[email protected]>

EFI table, memory description table and some of acpi tables will be placed after DOM0 memory space. Add placeholder for the starting address for loading in DOM0 and the size of new added tables. Also add a placeholder to store the new created tables.

---
 xen/include/asm-arm/domain.h | 5 +++++
 1 file changed, 5 insertions(+)
xen/include/asm-arm/domain.h +0 -0
index 1e61f30..91272e5 100644
@@ -125,6 +125,11 @@ struct arch_domain
     } vuart;
 
Quoted 11 lines

xen/include/asm-arm/domain.h struct arch_domain · line 132

Quoted 6 lines
xen/include/asm-arm/domain.h +5 -0
     unsigned int evtchn_irq;
+#ifdef CONFIG_ACPI
+    void *efi_acpi_table;
+    paddr_t efi_acpi_gpa;
+    paddr_t efi_acpi_len;
+#endif

Why do you need this in the arch_domain? AFAICT those 3 variables should only be used while building DOM0, so a better place would be in struct kernel_info (see xen/arch/arm/kernel.h).

Since I use efi_acpi_table to store the allocated pages pointer which are used to store newly created ACPI and EFI tables.
See [PATCH v3 40/62]:

(quoted diff) +2 -0
+    order = get_order_from_bytes(d->arch.efi_acpi_len);
+    d->arch.efi_acpi_table = alloc_xenheap_pages(order, 0);

And it free these pages when destroying this domain:

xen/include/asm-arm/domain.h +4 -0
+#ifdef CONFIG_ACPI
+    free_xenheap_pages(d->arch.efi_acpi_table,
+                       get_order_from_bytes(d->arch.efi_acpi_len));
+#endif
Quoted 1 line

efi_acpi_gpa might not need.

If you need to free the memory at domain destruction, it could make sense to store the pointer in struct arch_domain, even if it only happens for dom0. However you could come up with a single struct and add a pointer to it in arch_domain to limit the per-domain overhead.

#203 lore raw

Re: [PATCH v3 38/62] arm/acpi: Add placeholder for efi and acpi load address

In reply to Julien Grall
Quoted 23 lines · Julien Grall

Hi Shannon,

Quoted 20 lines · On 17/11/15 09:40, [email protected] wrote:

From: Shannon Zhao <[email protected]>

EFI table, memory description table and some of acpi tables will be placed after DOM0 memory space. Add placeholder for the starting address for loading in DOM0 and the size of new added tables. Also add a placeholder to store the new created tables.

---
 xen/include/asm-arm/domain.h | 5 +++++
 1 file changed, 5 insertions(+)
xen/include/asm-arm/domain.h +0 -0
index 1e61f30..91272e5 100644
@@ -125,6 +125,11 @@ struct arch_domain
     } vuart;
 
Quoted 11 lines

xen/include/asm-arm/domain.h struct arch_domain · line 132

Quoted 6 lines
xen/include/asm-arm/domain.h +5 -0
     unsigned int evtchn_irq;
+#ifdef CONFIG_ACPI
+    void *efi_acpi_table;
+    paddr_t efi_acpi_gpa;
+    paddr_t efi_acpi_len;
+#endif

Why do you need this in the arch_domain? AFAICT those 3 variables should only be used while building DOM0, so a better place would be in struct kernel_info (see xen/arch/arm/kernel.h).

Since I use efi_acpi_table to store the allocated pages pointer which are used to store newly created ACPI and EFI tables.
See [PATCH v3 40/62]:
+ order = get_order_from_bytes(d->arch.efi_acpi_len);
+ d->arch.efi_acpi_table = alloc_xenheap_pages(order, 0);

And it free these pages when destroying this domain:
+#ifdef CONFIG_ACPI
+ free_xenheap_pages(d->arch.efi_acpi_table,
+ get_order_from_bytes(d->arch.efi_acpi_len));
+#endif

efi_acpi_gpa might not need.

Thanks,

Signature · 1 line
Shannon
#204 lore raw

Re: [PATCH v3 38/62] arm/acpi: Add placeholder for efi and acpi load address

In reply to shannon.zhao at linaro.org

Hi Shannon,

Quoted 18 lines · On 17/11/15 09:40, [email protected] wrote:

From: Shannon Zhao <[email protected]>

EFI table, memory description table and some of acpi tables will be placed after DOM0 memory space. Add placeholder for the starting address for loading in DOM0 and the size of new added tables. Also add a placeholder to store the new created tables.

---
 xen/include/asm-arm/domain.h | 5 +++++
 1 file changed, 5 insertions(+)
xen/include/asm-arm/domain.h +0 -0
index 1e61f30..91272e5 100644

xen/include/asm-arm/domain.h struct arch_domain · line 132

Quoted 8 lines
xen/include/asm-arm/domain.h +5 -0
@@ -125,6 +125,11 @@ struct arch_domain
     } vuart;
 
     unsigned int evtchn_irq;
+#ifdef CONFIG_ACPI
+    void *efi_acpi_table;
+    paddr_t efi_acpi_gpa;
+    paddr_t efi_acpi_len;
+#endif

Why do you need this in the arch_domain? AFAICT those 3 variables should only be used while building DOM0, so a better place would be in struct kernel_info (see xen/arch/arm/kernel.h).

xen/include/asm-arm/domain.h struct arch_domain · line 135

Quoted 4 lines
xen/include/asm-arm/domain.h +0 -0
 }  __cacheline_aligned;
 
 struct arch_vcpu

Regards,

Signature · 1 line
Julien Grall
#205 lore raw

PATCH v3 39/62 arm/acpi: Read acpi memory info from uefi

In reply to shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

ACPI memory is seperate from conventional memory and should be marked as reserved while passing to DOM0. Create a new meminfo structure to store all the acpi tables listed in uefi.

---
 xen/arch/arm/efi/efi-boot.h | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)
xen/arch/arm/efi/efi-boot.h +23 -0
index e427e5f..c58caca 100644
@@ -17,6 +17,9 @@ void __flush_dcache_area(const void *vaddr, unsigned long size);
 static struct file __initdata dtbfile;
 static void __initdata *fdt;
 static void __initdata *memmap;
+#ifdef CONFIG_ACPI
+static struct meminfo __initdata acpi_mem;
+#endif
 
 static int __init setup_chosen_node(void *fdt, int *addr_cells, int *size_cells)
 {
@@ -129,6 +132,9 @@ static EFI_STATUS __init efi_process_memory_map_bootinfo(EFI_MEMORY_DESCRIPTOR *
 {
     int Index;
     int i = 0;
+#ifdef CONFIG_ACPI
+    int j = 0;
+#endif
     EFI_MEMORY_DESCRIPTOR *desc_ptr = map;
 
     for ( Index = 0; Index < (mmap_size / desc_size); Index++ )
@@ -148,10 +154,27 @@ static EFI_STATUS __init efi_process_memory_map_bootinfo(EFI_MEMORY_DESCRIPTOR *
             bootinfo.mem.bank[i].size = desc_ptr->NumberOfPages * EFI_PAGE_SIZE;
             ++i;
         }
+#ifdef CONFIG_ACPI
+        else if ( desc_ptr->Type == EfiACPIReclaimMemory )
+        {
+            if ( j >= NR_MEM_BANKS )
+            {
+                PrintStr(L"Error: All " __stringify(NR_MEM_BANKS)
+                          " acpi meminfo mem banks exhausted.\r\n");
+                return EFI_LOAD_ERROR;
+            }
+            acpi_mem.bank[j].start = desc_ptr->PhysicalStart;
+            acpi_mem.bank[j].size  = desc_ptr->NumberOfPages * EFI_PAGE_SIZE;
+            ++j;
+        }
+#endif
         desc_ptr = NextMemoryDescriptor(desc_ptr, desc_size);
     }
 
     bootinfo.mem.nr_banks = i;
+#ifdef CONFIG_ACPI
+    acpi_mem.nr_banks = j;
+#endif
     return EFI_SUCCESS;
 }
 
Signature · 1 line
2.1.0
#206 lore raw

PATCH v3 39/62 arm/acpi: Read acpi memory info from uefi

Quoted 8 lines · shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

ACPI memory is seperate from conventional memory and should be marked as reserved while passing to DOM0. Create a new meminfo structure to store all the acpi tables listed in uefi.

Quoted 58 lines
 xen/arch/arm/efi/efi-boot.h | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)
xen/arch/arm/efi/efi-boot.h +23 -0
index e427e5f..c58caca 100644
@@ -17,6 +17,9 @@ void __flush_dcache_area(const void *vaddr, unsigned long size);
 static struct file __initdata dtbfile;
 static void __initdata *fdt;
 static void __initdata *memmap;
+#ifdef CONFIG_ACPI
+static struct meminfo __initdata acpi_mem;
+#endif
 
 static int __init setup_chosen_node(void *fdt, int *addr_cells, int *size_cells)
 {
@@ -129,6 +132,9 @@ static EFI_STATUS __init efi_process_memory_map_bootinfo(EFI_MEMORY_DESCRIPTOR *
 {
     int Index;
     int i = 0;
+#ifdef CONFIG_ACPI
+    int j = 0;
+#endif
     EFI_MEMORY_DESCRIPTOR *desc_ptr = map;
 
     for ( Index = 0; Index < (mmap_size / desc_size); Index++ )
@@ -148,10 +154,27 @@ static EFI_STATUS __init efi_process_memory_map_bootinfo(EFI_MEMORY_DESCRIPTOR *
             bootinfo.mem.bank[i].size = desc_ptr->NumberOfPages * EFI_PAGE_SIZE;
             ++i;
         }
+#ifdef CONFIG_ACPI
+        else if ( desc_ptr->Type == EfiACPIReclaimMemory )
+        {
+            if ( j >= NR_MEM_BANKS )
+            {
+                PrintStr(L"Error: All " __stringify(NR_MEM_BANKS)
+                          " acpi meminfo mem banks exhausted.\r\n");
+                return EFI_LOAD_ERROR;
+            }
+            acpi_mem.bank[j].start = desc_ptr->PhysicalStart;
+            acpi_mem.bank[j].size  = desc_ptr->NumberOfPages * EFI_PAGE_SIZE;
+            ++j;
+        }
+#endif
         desc_ptr = NextMemoryDescriptor(desc_ptr, desc_size);
     }
 
     bootinfo.mem.nr_banks = i;
+#ifdef CONFIG_ACPI
+    acpi_mem.nr_banks = j;
+#endif
     return EFI_SUCCESS;
 }
 
Signature · 1 line
2.1.0
Acked-by on v3 39/62
#207 lore raw

Re: [PATCH v3 39/62] arm/acpi: Read acpi memory info from uefi

In reply to shannon.zhao at linaro.org
Quoted 8 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Parth Dixit <[email protected]>

ACPI memory is seperate from conventional memory and should be marked as reserved while passing to DOM0. Create a new meminfo structure to store all the acpi tables listed in uefi.

Quoted 58 lines
 xen/arch/arm/efi/efi-boot.h | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)
xen/arch/arm/efi/efi-boot.h +23 -0
index e427e5f..c58caca 100644
@@ -17,6 +17,9 @@ void __flush_dcache_area(const void *vaddr, unsigned long size);
 static struct file __initdata dtbfile;
 static void __initdata *fdt;
 static void __initdata *memmap;
+#ifdef CONFIG_ACPI
+static struct meminfo __initdata acpi_mem;
+#endif
 
 static int __init setup_chosen_node(void *fdt, int *addr_cells, int *size_cells)
 {
@@ -129,6 +132,9 @@ static EFI_STATUS __init efi_process_memory_map_bootinfo(EFI_MEMORY_DESCRIPTOR *
 {
     int Index;
     int i = 0;
+#ifdef CONFIG_ACPI
+    int j = 0;
+#endif
     EFI_MEMORY_DESCRIPTOR *desc_ptr = map;
 
     for ( Index = 0; Index < (mmap_size / desc_size); Index++ )
@@ -148,10 +154,27 @@ static EFI_STATUS __init efi_process_memory_map_bootinfo(EFI_MEMORY_DESCRIPTOR *
             bootinfo.mem.bank[i].size = desc_ptr->NumberOfPages * EFI_PAGE_SIZE;
             ++i;
         }
+#ifdef CONFIG_ACPI
+        else if ( desc_ptr->Type == EfiACPIReclaimMemory )
+        {
+            if ( j >= NR_MEM_BANKS )
+            {
+                PrintStr(L"Error: All " __stringify(NR_MEM_BANKS)
+                          " acpi meminfo mem banks exhausted.\r\n");
+                return EFI_LOAD_ERROR;
+            }
+            acpi_mem.bank[j].start = desc_ptr->PhysicalStart;
+            acpi_mem.bank[j].size  = desc_ptr->NumberOfPages * EFI_PAGE_SIZE;
+            ++j;
+        }
+#endif
         desc_ptr = NextMemoryDescriptor(desc_ptr, desc_size);
     }
 
     bootinfo.mem.nr_banks = i;
+#ifdef CONFIG_ACPI
+    acpi_mem.nr_banks = j;
+#endif
     return EFI_SUCCESS;
 }
 
Signature · 1 line
2.1.0
#208 lore raw

PATCH v3 40/62 arm/acpi: Estimate memory required for acpi/efi tables

In reply to shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Estimate the memory required for loading acpi/efi tables in Dom0. Alloc the pages to store the new created EFI and ACPI tables and free these pages when destroying domain.

---
 xen/arch/arm/domain.c       |  4 +++
 xen/arch/arm/domain_build.c | 80 ++++++++++++++++++++++++++++++++++++++++++++-
 xen/common/efi/boot.c       | 21 ++++++++++++
 xen/include/asm-arm/setup.h |  2 ++
 4 files changed, 106 insertions(+), 1 deletion(-)
xen/arch/arm/domain.c +4 -0
index 880d0a6..10c58c4 100644
@@ -638,6 +638,10 @@ void arch_domain_destroy(struct domain *d)
     domain_vgic_free(d);
     domain_vuart_free(d);
     free_xenheap_page(d->shared_info);
+#ifdef CONFIG_ACPI
+    free_xenheap_pages(d->arch.efi_acpi_table,
+                       get_order_from_bytes(d->arch.efi_acpi_len));
+#endif
 }
 
 void arch_domain_shutdown(struct domain *d)
xen/arch/arm/domain_build.c +79 -1

98 lines not on this page · raw message

xen/common/efi/boot.c +21 -0
index 53c7452..78d8ae9 100644
@@ -13,6 +13,7 @@
 #include <xen/multiboot.h>
 #include <xen/pci_regs.h>
 #include <xen/pfn.h>
+#include <asm/acpi.h>
 #if EFI_PAGE_SIZE != PAGE_SIZE
 # error Cannot use xen/pfn.h here!
 #endif
@@ -1171,6 +1172,26 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
     for( ; ; ); /* not reached */
 }
 
+#ifdef CONFIG_ACPI
+/* Constant to indicate "Xen" in unicode u16 format */
+static const u16 XEN_EFI_FW_VENDOR[] ={0x0058,0x0065,0x006E,0x0000};
+
+int __init estimate_efi_size(int mem_nr_banks)
+{
+    int size;
+    int est_size = sizeof(EFI_SYSTEM_TABLE);
+    int ect_size = sizeof(EFI_CONFIGURATION_TABLE);
+    int emd_size = sizeof(EFI_MEMORY_DESCRIPTOR);
+    int fw_vendor_size = sizeof(XEN_EFI_FW_VENDOR);
+
+    size = PAGE_ALIGN(est_size + ect_size + fw_vendor_size)
+           + PAGE_ALIGN(emd_size *
+                        (mem_nr_banks + acpi_mem.nr_banks + TBL_MMAX));
+
+    return size;
+}
+#endif
+
 #ifndef CONFIG_ARM /* TODO - runtime service support */
 
 static bool_t __initdata efi_rs_enable = 1;
xen/include/asm-arm/setup.h +2 -0
index 30ac53b..b759813 100644
@@ -51,6 +51,8 @@ void arch_init_memory(void);
 
 void copy_from_paddr(void *dst, paddr_t paddr, unsigned long len);
 
+int estimate_efi_size(int mem_nr_banks);
+
 int construct_dom0(struct domain *d);
 
 void discard_initial_modules(void);
Signature · 1 line
2.1.0
#209 lore raw

PATCH v3 40/62 arm/acpi: Estimate memory required for acpi/efi tables

Quoted 5 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Estimate the memory required for loading acpi/efi tables in Dom0. Alloc the pages to store the new created EFI and ACPI tables and free these pages when destroying domain.

Could you please explain what you are page aligning exactly and why?

Quoted 52 lines
---
 xen/arch/arm/domain.c       |  4 +++
 xen/arch/arm/domain_build.c | 80 ++++++++++++++++++++++++++++++++++++++++++++-
 xen/common/efi/boot.c       | 21 ++++++++++++
 xen/include/asm-arm/setup.h |  2 ++
 4 files changed, 106 insertions(+), 1 deletion(-)
xen/arch/arm/domain.c +4 -0
index 880d0a6..10c58c4 100644
@@ -638,6 +638,10 @@ void arch_domain_destroy(struct domain *d)
     domain_vgic_free(d);
     domain_vuart_free(d);
     free_xenheap_page(d->shared_info);
+#ifdef CONFIG_ACPI
+    free_xenheap_pages(d->arch.efi_acpi_table,
+                       get_order_from_bytes(d->arch.efi_acpi_len));
+#endif
 }
 
 void arch_domain_shutdown(struct domain *d)
xen/arch/arm/domain_build.c +12 -0
index 0c3441a..b5ed44c 100644
@@ -12,6 +12,8 @@
 #include <xen/libfdt/libfdt.h>
 #include <xen/guest_access.h>
 #include <xen/iocap.h>
+#include <xen/acpi.h>
+#include <acpi/actables.h>
 #include <asm/device.h>
 #include <asm/setup.h>
 #include <asm/platform.h>
@@ -1354,6 +1356,78 @@ static int prepare_dtb(struct domain *d, struct kernel_info *kinfo)
     return -EINVAL;
 }
 
+#ifdef CONFIG_ACPI
+static int estimate_acpi_efi_size(struct domain *d, struct kernel_info *kinfo)
+{
+    u64 efi_size, acpi_size = 0, addr;
+    u32 madt_size;
+    struct acpi_table_rsdp *rsdp_tbl;
+    struct acpi_table_header *table = NULL;
+
+    efi_size = estimate_efi_size(kinfo->mem.nr_banks);
+

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1378

Quoted 10 lines
xen/arch/arm/domain_build.c +10 -0
+    acpi_size += PAGE_ALIGN(sizeof(struct acpi_table_fadt));
+    acpi_size += PAGE_ALIGN(sizeof(struct acpi_table_stao));
+
+    madt_size = sizeof(struct acpi_table_madt)
+                + sizeof(struct acpi_madt_generic_interrupt) * d->max_vcpus
+                + sizeof(struct acpi_madt_generic_distributor);
+    if ( d->arch.vgic.version == GIC_V3 )
+        madt_size += sizeof(struct acpi_madt_generic_redistributor)
+                     * d->arch.vgic.nr_regions;
+    acpi_size += PAGE_ALIGN(madt_size);

are the MADT and FADT tables guaranteed to be on separate pages or is it just an estimate?

Quoted 24 lines
xen/arch/arm/domain_build.c +24 -0
+    addr = acpi_os_get_root_pointer();
+    if ( !addr )
+    {
+        printk("Unable to get acpi root pointer\n");
+        return -EINVAL;
+    }
+    rsdp_tbl = acpi_os_map_memory(addr, sizeof(struct acpi_table_rsdp));
+    table = acpi_os_map_memory(rsdp_tbl->xsdt_physical_address,
+                               sizeof(struct acpi_table_header));
+    acpi_size += PAGE_ALIGN(table->length + sizeof(u64));
+    acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
+    acpi_os_unmap_memory(rsdp_tbl, sizeof(struct acpi_table_rsdp));
+
+    acpi_size += PAGE_ALIGN(sizeof(struct acpi_table_rsdp));
+    d->arch.efi_acpi_len = PAGE_ALIGN(efi_size) + PAGE_ALIGN(acpi_size);
+
+    return 0;
+}
+
+static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
+{
+    int rc = 0;
+    int order;
+

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1413

Quoted 10 lines
xen/arch/arm/domain_build.c +10 -0
+    rc = estimate_acpi_efi_size(d, kinfo);
+    if ( rc != 0 )
+        return rc;
+
+    order = get_order_from_bytes(d->arch.efi_acpi_len);
+    d->arch.efi_acpi_table = alloc_xenheap_pages(order, 0);
+    if ( d->arch.efi_acpi_table == NULL )
+    {
+        printk("unable to allocate memory!\n");
+        return -1;

ENOMEM

Quoted 54 lines
xen/arch/arm/domain_build.c +22 -1
+    }
+    memset(d->arch.efi_acpi_table, 0, d->arch.efi_acpi_len);
+
+    /* For ACPI, Dom0 doesn't use kinfo->gnttab_start to get the grant table
+     * region. So we use it as the ACPI table mapped address. */
+    d->arch.efi_acpi_gpa = kinfo->gnttab_start;
+
+    return 0;
+}
+#else
+static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
+{
+    /* Only booting with ACPI will hit here */
+    BUG_ON(1);
+    return -EINVAL;
+}
+#endif
 static void dtb_load(struct kernel_info *kinfo)
 {
     void * __user dtb_virt = (void * __user)(register_t)kinfo->dtb_paddr;
@@ -1540,7 +1614,11 @@ int construct_dom0(struct domain *d)
     allocate_memory(d, &kinfo);
     find_gnttab_region(d, &kinfo);
 
-    rc = prepare_dtb(d, &kinfo);
+    if ( acpi_disabled )
+        rc = prepare_dtb(d, &kinfo);
+    else
+        rc = prepare_acpi(d, &kinfo);
+
     if ( rc < 0 )
         return rc;
 
xen/common/efi/boot.c +6 -0
index 53c7452..78d8ae9 100644
@@ -13,6 +13,7 @@
 #include <xen/multiboot.h>
 #include <xen/pci_regs.h>
 #include <xen/pfn.h>
+#include <asm/acpi.h>
 #if EFI_PAGE_SIZE != PAGE_SIZE
 # error Cannot use xen/pfn.h here!
 #endif
@@ -1171,6 +1172,26 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
     for( ; ; ); /* not reached */
 }
 
+#ifdef CONFIG_ACPI
+/* Constant to indicate "Xen" in unicode u16 format */
+static const u16 XEN_EFI_FW_VENDOR[] ={0x0058,0x0065,0x006E,0x0000};
+
+int __init estimate_efi_size(int mem_nr_banks)

xen/common/efi/boot.c efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) · line 1189

Quoted 10 lines
xen/common/efi/boot.c +10 -0
+{
+    int size;
+    int est_size = sizeof(EFI_SYSTEM_TABLE);
+    int ect_size = sizeof(EFI_CONFIGURATION_TABLE);
+    int emd_size = sizeof(EFI_MEMORY_DESCRIPTOR);
+    int fw_vendor_size = sizeof(XEN_EFI_FW_VENDOR);
+
+    size = PAGE_ALIGN(est_size + ect_size + fw_vendor_size)
+           + PAGE_ALIGN(emd_size *
+                        (mem_nr_banks + acpi_mem.nr_banks + TBL_MMAX));

Why are they on two separate pages? Is it mandated by the EFI spec? Why are you adding TBL_MMAX to the multiplicand here?

I don't like that we are passing mem_nr_banks as argument but we are accessing acpi_mem.nr_banks from the global variable. I would prefer if they were both passed as arguments.

Quoted 23 lines
xen/common/efi/boot.c +4 -0
+    return size;
+}
+#endif
+
 #ifndef CONFIG_ARM /* TODO - runtime service support */
 
 static bool_t __initdata efi_rs_enable = 1;
xen/include/asm-arm/setup.h +2 -0
index 30ac53b..b759813 100644
@@ -51,6 +51,8 @@ void arch_init_memory(void);
 
 void copy_from_paddr(void *dst, paddr_t paddr, unsigned long len);
 
+int estimate_efi_size(int mem_nr_banks);
+
 int construct_dom0(struct domain *d);
 
 void discard_initial_modules(void);
Signature · 1 line
2.1.0
#210 lore raw

PATCH v3 40/62 arm/acpi: Estimate memory required for acpi/efi tables

Quoted 9 lines · Stefano Stabellini
Quoted 5 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Estimate the memory required for loading acpi/efi tables in Dom0. Alloc the pages to store the new created EFI and ACPI tables and free these pages when destroying domain.

Could you please explain what you are page aligning exactly and why?

At least it should be 64bit aligned of the table start address. If not, guest will throw out an alignment fault.

ACPI: Using GIC for interrupt routing
Unhandled fault: alignment fault (0x96000021) at 0xffffff800006c19c

Internal error: : 96000021 [#1] PREEMPT SMP
Modules linked in:
CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.3.0+ #551
Hardware name: (null) (DT)
task: ffffffc008870000 ti: ffffffc00884c000 task.ti: ffffffc00884c000
PC is at acpi_get_phys_id+0x264/0x290
LR is at acpi_get_phys_id+0x178/0x290
Quoted 205 lines
Quoted 53 lines
---
 xen/arch/arm/domain.c       |  4 +++
 xen/arch/arm/domain_build.c | 80 ++++++++++++++++++++++++++++++++++++++++++++-
 xen/common/efi/boot.c       | 21 ++++++++++++
 xen/include/asm-arm/setup.h |  2 ++
 4 files changed, 106 insertions(+), 1 deletion(-)
xen/arch/arm/domain.c +4 -0
index 880d0a6..10c58c4 100644
@@ -638,6 +638,10 @@ void arch_domain_destroy(struct domain *d)
     domain_vgic_free(d);
     domain_vuart_free(d);
     free_xenheap_page(d->shared_info);
+#ifdef CONFIG_ACPI
+    free_xenheap_pages(d->arch.efi_acpi_table,
+                       get_order_from_bytes(d->arch.efi_acpi_len));
+#endif
 }
 
 void arch_domain_shutdown(struct domain *d)
xen/arch/arm/domain_build.c +12 -0
index 0c3441a..b5ed44c 100644
@@ -12,6 +12,8 @@
 #include <xen/libfdt/libfdt.h>
 #include <xen/guest_access.h>
 #include <xen/iocap.h>
+#include <xen/acpi.h>
+#include <acpi/actables.h>
 #include <asm/device.h>
 #include <asm/setup.h>
 #include <asm/platform.h>
@@ -1354,6 +1356,78 @@ static int prepare_dtb(struct domain *d, struct kernel_info *kinfo)
     return -EINVAL;
 }
 
+#ifdef CONFIG_ACPI
+static int estimate_acpi_efi_size(struct domain *d, struct kernel_info *kinfo)
+{
+    u64 efi_size, acpi_size = 0, addr;
+    u32 madt_size;
+    struct acpi_table_rsdp *rsdp_tbl;
+    struct acpi_table_header *table = NULL;
+
+    efi_size = estimate_efi_size(kinfo->mem.nr_banks);
+

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1378

Quoted 10 lines
xen/arch/arm/domain_build.c +10 -0
+    acpi_size += PAGE_ALIGN(sizeof(struct acpi_table_fadt));
+    acpi_size += PAGE_ALIGN(sizeof(struct acpi_table_stao));
+
+    madt_size = sizeof(struct acpi_table_madt)
+                + sizeof(struct acpi_madt_generic_interrupt) * d->max_vcpus
+                + sizeof(struct acpi_madt_generic_distributor);
+    if ( d->arch.vgic.version == GIC_V3 )
+        madt_size += sizeof(struct acpi_madt_generic_redistributor)
+                     * d->arch.vgic.nr_regions;
+    acpi_size += PAGE_ALIGN(madt_size);

are the MADT and FADT tables guaranteed to be on separate pages or is it just an estimate?

Quoted 24 lines
xen/arch/arm/domain_build.c +24 -0
+    addr = acpi_os_get_root_pointer();
+    if ( !addr )
+    {
+        printk("Unable to get acpi root pointer\n");
+        return -EINVAL;
+    }
+    rsdp_tbl = acpi_os_map_memory(addr, sizeof(struct acpi_table_rsdp));
+    table = acpi_os_map_memory(rsdp_tbl->xsdt_physical_address,
+                               sizeof(struct acpi_table_header));
+    acpi_size += PAGE_ALIGN(table->length + sizeof(u64));
+    acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
+    acpi_os_unmap_memory(rsdp_tbl, sizeof(struct acpi_table_rsdp));
+
+    acpi_size += PAGE_ALIGN(sizeof(struct acpi_table_rsdp));
+    d->arch.efi_acpi_len = PAGE_ALIGN(efi_size) + PAGE_ALIGN(acpi_size);
+
+    return 0;
+}
+
+static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
+{
+    int rc = 0;
+    int order;
+

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1413

Quoted 10 lines
xen/arch/arm/domain_build.c +10 -0
+    rc = estimate_acpi_efi_size(d, kinfo);
+    if ( rc != 0 )
+        return rc;
+
+    order = get_order_from_bytes(d->arch.efi_acpi_len);
+    d->arch.efi_acpi_table = alloc_xenheap_pages(order, 0);
+    if ( d->arch.efi_acpi_table == NULL )
+    {
+        printk("unable to allocate memory!\n");
+        return -1;

ENOMEM

Quoted 54 lines
xen/arch/arm/domain_build.c +22 -1
+    }
+    memset(d->arch.efi_acpi_table, 0, d->arch.efi_acpi_len);
+
+    /* For ACPI, Dom0 doesn't use kinfo->gnttab_start to get the grant table
+     * region. So we use it as the ACPI table mapped address. */
+    d->arch.efi_acpi_gpa = kinfo->gnttab_start;
+
+    return 0;
+}
+#else
+static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
+{
+    /* Only booting with ACPI will hit here */
+    BUG_ON(1);
+    return -EINVAL;
+}
+#endif
 static void dtb_load(struct kernel_info *kinfo)
 {
     void * __user dtb_virt = (void * __user)(register_t)kinfo->dtb_paddr;
@@ -1540,7 +1614,11 @@ int construct_dom0(struct domain *d)
     allocate_memory(d, &kinfo);
     find_gnttab_region(d, &kinfo);
 
-    rc = prepare_dtb(d, &kinfo);
+    if ( acpi_disabled )
+        rc = prepare_dtb(d, &kinfo);
+    else
+        rc = prepare_acpi(d, &kinfo);
+
     if ( rc < 0 )
         return rc;
 
xen/common/efi/boot.c +6 -0
index 53c7452..78d8ae9 100644
@@ -13,6 +13,7 @@
 #include <xen/multiboot.h>
 #include <xen/pci_regs.h>
 #include <xen/pfn.h>
+#include <asm/acpi.h>
 #if EFI_PAGE_SIZE != PAGE_SIZE
 # error Cannot use xen/pfn.h here!
 #endif
@@ -1171,6 +1172,26 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
     for( ; ; ); /* not reached */
 }
 
+#ifdef CONFIG_ACPI
+/* Constant to indicate "Xen" in unicode u16 format */
+static const u16 XEN_EFI_FW_VENDOR[] ={0x0058,0x0065,0x006E,0x0000};
+
+int __init estimate_efi_size(int mem_nr_banks)

xen/common/efi/boot.c efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) · line 1189

Quoted 10 lines
xen/common/efi/boot.c +10 -0
+{
+    int size;
+    int est_size = sizeof(EFI_SYSTEM_TABLE);
+    int ect_size = sizeof(EFI_CONFIGURATION_TABLE);
+    int emd_size = sizeof(EFI_MEMORY_DESCRIPTOR);
+    int fw_vendor_size = sizeof(XEN_EFI_FW_VENDOR);
+
+    size = PAGE_ALIGN(est_size + ect_size + fw_vendor_size)
+           + PAGE_ALIGN(emd_size *
+                        (mem_nr_banks + acpi_mem.nr_banks + TBL_MMAX));

Why are they on two separate pages? Is it mandated by the EFI spec? Why are you adding TBL_MMAX to the multiplicand here?

I don't like that we are passing mem_nr_banks as argument but we are accessing acpi_mem.nr_banks from the global variable. I would prefer if they were both passed as arguments.

Quoted 23 lines
xen/common/efi/boot.c +4 -0
+    return size;
+}
+#endif
+
 #ifndef CONFIG_ARM /* TODO - runtime service support */
 
 static bool_t __initdata efi_rs_enable = 1;
xen/include/asm-arm/setup.h +2 -0
index 30ac53b..b759813 100644
@@ -51,6 +51,8 @@ void arch_init_memory(void);
 
 void copy_from_paddr(void *dst, paddr_t paddr, unsigned long len);
 
+int estimate_efi_size(int mem_nr_banks);
+
 int construct_dom0(struct domain *d);
 
 void discard_initial_modules(void);
Signature · 1 line
2.1.0

.

Signature · 1 line
Shannon
#211 lore raw

PATCH v3 40/62 arm/acpi: Estimate memory required for acpi/efi tables

Quoted 16 lines · Shannon Zhao
Quoted 9 lines · Stefano Stabellini
Quoted 5 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Estimate the memory required for loading acpi/efi tables in Dom0. Alloc the pages to store the new created EFI and ACPI tables and free these pages when destroying domain.

Could you please explain what you are page aligning exactly and why?

At least it should be 64bit aligned of the table start address. If not, guest will throw out an alignment fault.

ACPI: Using GIC for interrupt routing
Unhandled fault: alignment fault (0x96000021) at 0xffffff800006c19c

Quoted 7 lines
Internal error: : 96000021 [#1] PREEMPT SMP
Modules linked in:
CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.3.0+ #551
Hardware name: (null) (DT)
task: ffffffc008870000 ti: ffffffc00884c000 task.ti: ffffffc00884c000
PC is at acpi_get_phys_id+0x264/0x290
LR is at acpi_get_phys_id+0x178/0x290

OK, but between page alignment and 64-bit alignment there is a very big difference.

Quoted 209 lines
Quoted 205 lines
Quoted 53 lines
---
 xen/arch/arm/domain.c       |  4 +++
 xen/arch/arm/domain_build.c | 80 ++++++++++++++++++++++++++++++++++++++++++++-
 xen/common/efi/boot.c       | 21 ++++++++++++
 xen/include/asm-arm/setup.h |  2 ++
 4 files changed, 106 insertions(+), 1 deletion(-)
xen/arch/arm/domain.c +4 -0
index 880d0a6..10c58c4 100644
@@ -638,6 +638,10 @@ void arch_domain_destroy(struct domain *d)
     domain_vgic_free(d);
     domain_vuart_free(d);
     free_xenheap_page(d->shared_info);
+#ifdef CONFIG_ACPI
+    free_xenheap_pages(d->arch.efi_acpi_table,
+                       get_order_from_bytes(d->arch.efi_acpi_len));
+#endif
 }
 
 void arch_domain_shutdown(struct domain *d)
xen/arch/arm/domain_build.c +12 -0
index 0c3441a..b5ed44c 100644
@@ -12,6 +12,8 @@
 #include <xen/libfdt/libfdt.h>
 #include <xen/guest_access.h>
 #include <xen/iocap.h>
+#include <xen/acpi.h>
+#include <acpi/actables.h>
 #include <asm/device.h>
 #include <asm/setup.h>
 #include <asm/platform.h>
@@ -1354,6 +1356,78 @@ static int prepare_dtb(struct domain *d, struct kernel_info *kinfo)
     return -EINVAL;
 }
 
+#ifdef CONFIG_ACPI
+static int estimate_acpi_efi_size(struct domain *d, struct kernel_info *kinfo)
+{
+    u64 efi_size, acpi_size = 0, addr;
+    u32 madt_size;
+    struct acpi_table_rsdp *rsdp_tbl;
+    struct acpi_table_header *table = NULL;
+
+    efi_size = estimate_efi_size(kinfo->mem.nr_banks);
+

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1378

Quoted 10 lines
xen/arch/arm/domain_build.c +10 -0
+    acpi_size += PAGE_ALIGN(sizeof(struct acpi_table_fadt));
+    acpi_size += PAGE_ALIGN(sizeof(struct acpi_table_stao));
+
+    madt_size = sizeof(struct acpi_table_madt)
+                + sizeof(struct acpi_madt_generic_interrupt) * d->max_vcpus
+                + sizeof(struct acpi_madt_generic_distributor);
+    if ( d->arch.vgic.version == GIC_V3 )
+        madt_size += sizeof(struct acpi_madt_generic_redistributor)
+                     * d->arch.vgic.nr_regions;
+    acpi_size += PAGE_ALIGN(madt_size);

are the MADT and FADT tables guaranteed to be on separate pages or is it just an estimate?

Quoted 24 lines
xen/arch/arm/domain_build.c +24 -0
+    addr = acpi_os_get_root_pointer();
+    if ( !addr )
+    {
+        printk("Unable to get acpi root pointer\n");
+        return -EINVAL;
+    }
+    rsdp_tbl = acpi_os_map_memory(addr, sizeof(struct acpi_table_rsdp));
+    table = acpi_os_map_memory(rsdp_tbl->xsdt_physical_address,
+                               sizeof(struct acpi_table_header));
+    acpi_size += PAGE_ALIGN(table->length + sizeof(u64));
+    acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
+    acpi_os_unmap_memory(rsdp_tbl, sizeof(struct acpi_table_rsdp));
+
+    acpi_size += PAGE_ALIGN(sizeof(struct acpi_table_rsdp));
+    d->arch.efi_acpi_len = PAGE_ALIGN(efi_size) + PAGE_ALIGN(acpi_size);
+
+    return 0;
+}
+
+static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
+{
+    int rc = 0;
+    int order;
+

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1413

Quoted 10 lines
xen/arch/arm/domain_build.c +10 -0
+    rc = estimate_acpi_efi_size(d, kinfo);
+    if ( rc != 0 )
+        return rc;
+
+    order = get_order_from_bytes(d->arch.efi_acpi_len);
+    d->arch.efi_acpi_table = alloc_xenheap_pages(order, 0);
+    if ( d->arch.efi_acpi_table == NULL )
+    {
+        printk("unable to allocate memory!\n");
+        return -1;

ENOMEM

Quoted 54 lines
xen/arch/arm/domain_build.c +22 -1
+    }
+    memset(d->arch.efi_acpi_table, 0, d->arch.efi_acpi_len);
+
+    /* For ACPI, Dom0 doesn't use kinfo->gnttab_start to get the grant table
+     * region. So we use it as the ACPI table mapped address. */
+    d->arch.efi_acpi_gpa = kinfo->gnttab_start;
+
+    return 0;
+}
+#else
+static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
+{
+    /* Only booting with ACPI will hit here */
+    BUG_ON(1);
+    return -EINVAL;
+}
+#endif
 static void dtb_load(struct kernel_info *kinfo)
 {
     void * __user dtb_virt = (void * __user)(register_t)kinfo->dtb_paddr;
@@ -1540,7 +1614,11 @@ int construct_dom0(struct domain *d)
     allocate_memory(d, &kinfo);
     find_gnttab_region(d, &kinfo);
 
-    rc = prepare_dtb(d, &kinfo);
+    if ( acpi_disabled )
+        rc = prepare_dtb(d, &kinfo);
+    else
+        rc = prepare_acpi(d, &kinfo);
+
     if ( rc < 0 )
         return rc;
 
xen/common/efi/boot.c +6 -0
index 53c7452..78d8ae9 100644
@@ -13,6 +13,7 @@
 #include <xen/multiboot.h>
 #include <xen/pci_regs.h>
 #include <xen/pfn.h>
+#include <asm/acpi.h>
 #if EFI_PAGE_SIZE != PAGE_SIZE
 # error Cannot use xen/pfn.h here!
 #endif
@@ -1171,6 +1172,26 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
     for( ; ; ); /* not reached */
 }
 
+#ifdef CONFIG_ACPI
+/* Constant to indicate "Xen" in unicode u16 format */
+static const u16 XEN_EFI_FW_VENDOR[] ={0x0058,0x0065,0x006E,0x0000};
+
+int __init estimate_efi_size(int mem_nr_banks)

xen/common/efi/boot.c efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) · line 1189

Quoted 10 lines
xen/common/efi/boot.c +10 -0
+{
+    int size;
+    int est_size = sizeof(EFI_SYSTEM_TABLE);
+    int ect_size = sizeof(EFI_CONFIGURATION_TABLE);
+    int emd_size = sizeof(EFI_MEMORY_DESCRIPTOR);
+    int fw_vendor_size = sizeof(XEN_EFI_FW_VENDOR);
+
+    size = PAGE_ALIGN(est_size + ect_size + fw_vendor_size)
+           + PAGE_ALIGN(emd_size *
+                        (mem_nr_banks + acpi_mem.nr_banks + TBL_MMAX));

Why are they on two separate pages? Is it mandated by the EFI spec? Why are you adding TBL_MMAX to the multiplicand here?

I don't like that we are passing mem_nr_banks as argument but we are accessing acpi_mem.nr_banks from the global variable. I would prefer if they were both passed as arguments.

Quoted 23 lines
xen/common/efi/boot.c +4 -0
+    return size;
+}
+#endif
+
 #ifndef CONFIG_ARM /* TODO - runtime service support */
 
 static bool_t __initdata efi_rs_enable = 1;
xen/include/asm-arm/setup.h +2 -0
index 30ac53b..b759813 100644
@@ -51,6 +51,8 @@ void arch_init_memory(void);
 
 void copy_from_paddr(void *dst, paddr_t paddr, unsigned long len);
 
+int estimate_efi_size(int mem_nr_banks);
+
 int construct_dom0(struct domain *d);
 
 void discard_initial_modules(void);
Signature · 1 line
2.1.0

.

Signature · 1 line
Shannon
#212 lore raw

Re: [PATCH v3 40/62] arm/acpi: Estimate memory required for acpi/efi tables

In reply to Shannon Zhao
Quoted 16 lines · Shannon Zhao
Quoted 9 lines · Stefano Stabellini
Quoted 5 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Shannon Zhao <[email protected]>

Estimate the memory required for loading acpi/efi tables in Dom0. Alloc the pages to store the new created EFI and ACPI tables and free these pages when destroying domain.

Could you please explain what you are page aligning exactly and why?

At least it should be 64bit aligned of the table start address. If not, guest will throw out an alignment fault.

ACPI: Using GIC for interrupt routing
Unhandled fault: alignment fault (0x96000021) at 0xffffff800006c19c

Quoted 7 lines
Internal error: : 96000021 [#1] PREEMPT SMP
Modules linked in:
CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.3.0+ #551
Hardware name: (null) (DT)
task: ffffffc008870000 ti: ffffffc00884c000 task.ti: ffffffc00884c000
PC is at acpi_get_phys_id+0x264/0x290
LR is at acpi_get_phys_id+0x178/0x290

OK, but between page alignment and 64-bit alignment there is a very big difference.

Quoted 209 lines
Quoted 205 lines
Quoted 53 lines
---
 xen/arch/arm/domain.c       |  4 +++
 xen/arch/arm/domain_build.c | 80 ++++++++++++++++++++++++++++++++++++++++++++-
 xen/common/efi/boot.c       | 21 ++++++++++++
 xen/include/asm-arm/setup.h |  2 ++
 4 files changed, 106 insertions(+), 1 deletion(-)
xen/arch/arm/domain.c +4 -0
index 880d0a6..10c58c4 100644
@@ -638,6 +638,10 @@ void arch_domain_destroy(struct domain *d)
     domain_vgic_free(d);
     domain_vuart_free(d);
     free_xenheap_page(d->shared_info);
+#ifdef CONFIG_ACPI
+    free_xenheap_pages(d->arch.efi_acpi_table,
+                       get_order_from_bytes(d->arch.efi_acpi_len));
+#endif
 }
 
 void arch_domain_shutdown(struct domain *d)
xen/arch/arm/domain_build.c +12 -0
index 0c3441a..b5ed44c 100644
@@ -12,6 +12,8 @@
 #include <xen/libfdt/libfdt.h>
 #include <xen/guest_access.h>
 #include <xen/iocap.h>
+#include <xen/acpi.h>
+#include <acpi/actables.h>
 #include <asm/device.h>
 #include <asm/setup.h>
 #include <asm/platform.h>
@@ -1354,6 +1356,78 @@ static int prepare_dtb(struct domain *d, struct kernel_info *kinfo)
     return -EINVAL;
 }
 
+#ifdef CONFIG_ACPI
+static int estimate_acpi_efi_size(struct domain *d, struct kernel_info *kinfo)
+{
+    u64 efi_size, acpi_size = 0, addr;
+    u32 madt_size;
+    struct acpi_table_rsdp *rsdp_tbl;
+    struct acpi_table_header *table = NULL;
+
+    efi_size = estimate_efi_size(kinfo->mem.nr_banks);
+

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1378

Quoted 10 lines
xen/arch/arm/domain_build.c +10 -0
+    acpi_size += PAGE_ALIGN(sizeof(struct acpi_table_fadt));
+    acpi_size += PAGE_ALIGN(sizeof(struct acpi_table_stao));
+
+    madt_size = sizeof(struct acpi_table_madt)
+                + sizeof(struct acpi_madt_generic_interrupt) * d->max_vcpus
+                + sizeof(struct acpi_madt_generic_distributor);
+    if ( d->arch.vgic.version == GIC_V3 )
+        madt_size += sizeof(struct acpi_madt_generic_redistributor)
+                     * d->arch.vgic.nr_regions;
+    acpi_size += PAGE_ALIGN(madt_size);

are the MADT and FADT tables guaranteed to be on separate pages or is it just an estimate?

Quoted 24 lines
xen/arch/arm/domain_build.c +24 -0
+    addr = acpi_os_get_root_pointer();
+    if ( !addr )
+    {
+        printk("Unable to get acpi root pointer\n");
+        return -EINVAL;
+    }
+    rsdp_tbl = acpi_os_map_memory(addr, sizeof(struct acpi_table_rsdp));
+    table = acpi_os_map_memory(rsdp_tbl->xsdt_physical_address,
+                               sizeof(struct acpi_table_header));
+    acpi_size += PAGE_ALIGN(table->length + sizeof(u64));
+    acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
+    acpi_os_unmap_memory(rsdp_tbl, sizeof(struct acpi_table_rsdp));
+
+    acpi_size += PAGE_ALIGN(sizeof(struct acpi_table_rsdp));
+    d->arch.efi_acpi_len = PAGE_ALIGN(efi_size) + PAGE_ALIGN(acpi_size);
+
+    return 0;
+}
+
+static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
+{
+    int rc = 0;
+    int order;
+

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1413

Quoted 10 lines
xen/arch/arm/domain_build.c +10 -0
+    rc = estimate_acpi_efi_size(d, kinfo);
+    if ( rc != 0 )
+        return rc;
+
+    order = get_order_from_bytes(d->arch.efi_acpi_len);
+    d->arch.efi_acpi_table = alloc_xenheap_pages(order, 0);
+    if ( d->arch.efi_acpi_table == NULL )
+    {
+        printk("unable to allocate memory!\n");
+        return -1;

ENOMEM

Quoted 54 lines
xen/arch/arm/domain_build.c +22 -1
+    }
+    memset(d->arch.efi_acpi_table, 0, d->arch.efi_acpi_len);
+
+    /* For ACPI, Dom0 doesn't use kinfo->gnttab_start to get the grant table
+     * region. So we use it as the ACPI table mapped address. */
+    d->arch.efi_acpi_gpa = kinfo->gnttab_start;
+
+    return 0;
+}
+#else
+static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
+{
+    /* Only booting with ACPI will hit here */
+    BUG_ON(1);
+    return -EINVAL;
+}
+#endif
 static void dtb_load(struct kernel_info *kinfo)
 {
     void * __user dtb_virt = (void * __user)(register_t)kinfo->dtb_paddr;
@@ -1540,7 +1614,11 @@ int construct_dom0(struct domain *d)
     allocate_memory(d, &kinfo);
     find_gnttab_region(d, &kinfo);
 
-    rc = prepare_dtb(d, &kinfo);
+    if ( acpi_disabled )
+        rc = prepare_dtb(d, &kinfo);
+    else
+        rc = prepare_acpi(d, &kinfo);
+
     if ( rc < 0 )
         return rc;
 
xen/common/efi/boot.c +6 -0
index 53c7452..78d8ae9 100644
@@ -13,6 +13,7 @@
 #include <xen/multiboot.h>
 #include <xen/pci_regs.h>
 #include <xen/pfn.h>
+#include <asm/acpi.h>
 #if EFI_PAGE_SIZE != PAGE_SIZE
 # error Cannot use xen/pfn.h here!
 #endif
@@ -1171,6 +1172,26 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
     for( ; ; ); /* not reached */
 }
 
+#ifdef CONFIG_ACPI
+/* Constant to indicate "Xen" in unicode u16 format */
+static const u16 XEN_EFI_FW_VENDOR[] ={0x0058,0x0065,0x006E,0x0000};
+
+int __init estimate_efi_size(int mem_nr_banks)

xen/common/efi/boot.c efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) · line 1189

Quoted 10 lines
xen/common/efi/boot.c +10 -0
+{
+    int size;
+    int est_size = sizeof(EFI_SYSTEM_TABLE);
+    int ect_size = sizeof(EFI_CONFIGURATION_TABLE);
+    int emd_size = sizeof(EFI_MEMORY_DESCRIPTOR);
+    int fw_vendor_size = sizeof(XEN_EFI_FW_VENDOR);
+
+    size = PAGE_ALIGN(est_size + ect_size + fw_vendor_size)
+           + PAGE_ALIGN(emd_size *
+                        (mem_nr_banks + acpi_mem.nr_banks + TBL_MMAX));

Why are they on two separate pages? Is it mandated by the EFI spec? Why are you adding TBL_MMAX to the multiplicand here?

I don't like that we are passing mem_nr_banks as argument but we are accessing acpi_mem.nr_banks from the global variable. I would prefer if they were both passed as arguments.

Quoted 23 lines
xen/common/efi/boot.c +4 -0
+    return size;
+}
+#endif
+
 #ifndef CONFIG_ARM /* TODO - runtime service support */
 
 static bool_t __initdata efi_rs_enable = 1;
xen/include/asm-arm/setup.h +2 -0
index 30ac53b..b759813 100644
@@ -51,6 +51,8 @@ void arch_init_memory(void);
 
 void copy_from_paddr(void *dst, paddr_t paddr, unsigned long len);
 
+int estimate_efi_size(int mem_nr_banks);
+
 int construct_dom0(struct domain *d);
 
 void discard_initial_modules(void);
Signature · 1 line
2.1.0

.

Signature · 1 line
Shannon
#213 lore raw

Re: [PATCH v3 40/62] arm/acpi: Estimate memory required for acpi/efi tables

In reply to Stefano Stabellini
Quoted 9 lines · Stefano Stabellini
Quoted 5 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Shannon Zhao <[email protected]>

Estimate the memory required for loading acpi/efi tables in Dom0. Alloc the pages to store the new created EFI and ACPI tables and free these pages when destroying domain.

Could you please explain what you are page aligning exactly and why?

At least it should be 64bit aligned of the table start address. If not, guest will throw out an alignment fault.

ACPI: Using GIC for interrupt routing
Unhandled fault: alignment fault (0x96000021) at 0xffffff800006c19c

Internal error: : 96000021 [#1] PREEMPT SMP
Modules linked in:
CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.3.0+ #551
Hardware name: (null) (DT)
task: ffffffc008870000 ti: ffffffc00884c000 task.ti: ffffffc00884c000
PC is at acpi_get_phys_id+0x264/0x290
LR is at acpi_get_phys_id+0x178/0x290
Quoted 205 lines
Quoted 53 lines
---
 xen/arch/arm/domain.c       |  4 +++
 xen/arch/arm/domain_build.c | 80 ++++++++++++++++++++++++++++++++++++++++++++-
 xen/common/efi/boot.c       | 21 ++++++++++++
 xen/include/asm-arm/setup.h |  2 ++
 4 files changed, 106 insertions(+), 1 deletion(-)
xen/arch/arm/domain.c +4 -0
index 880d0a6..10c58c4 100644
@@ -638,6 +638,10 @@ void arch_domain_destroy(struct domain *d)
     domain_vgic_free(d);
     domain_vuart_free(d);
     free_xenheap_page(d->shared_info);
+#ifdef CONFIG_ACPI
+    free_xenheap_pages(d->arch.efi_acpi_table,
+                       get_order_from_bytes(d->arch.efi_acpi_len));
+#endif
 }
 
 void arch_domain_shutdown(struct domain *d)
xen/arch/arm/domain_build.c +12 -0
index 0c3441a..b5ed44c 100644
@@ -12,6 +12,8 @@
 #include <xen/libfdt/libfdt.h>
 #include <xen/guest_access.h>
 #include <xen/iocap.h>
+#include <xen/acpi.h>
+#include <acpi/actables.h>
 #include <asm/device.h>
 #include <asm/setup.h>
 #include <asm/platform.h>
@@ -1354,6 +1356,78 @@ static int prepare_dtb(struct domain *d, struct kernel_info *kinfo)
     return -EINVAL;
 }
 
+#ifdef CONFIG_ACPI
+static int estimate_acpi_efi_size(struct domain *d, struct kernel_info *kinfo)
+{
+    u64 efi_size, acpi_size = 0, addr;
+    u32 madt_size;
+    struct acpi_table_rsdp *rsdp_tbl;
+    struct acpi_table_header *table = NULL;
+
+    efi_size = estimate_efi_size(kinfo->mem.nr_banks);
+

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1378

Quoted 10 lines
xen/arch/arm/domain_build.c +10 -0
+    acpi_size += PAGE_ALIGN(sizeof(struct acpi_table_fadt));
+    acpi_size += PAGE_ALIGN(sizeof(struct acpi_table_stao));
+
+    madt_size = sizeof(struct acpi_table_madt)
+                + sizeof(struct acpi_madt_generic_interrupt) * d->max_vcpus
+                + sizeof(struct acpi_madt_generic_distributor);
+    if ( d->arch.vgic.version == GIC_V3 )
+        madt_size += sizeof(struct acpi_madt_generic_redistributor)
+                     * d->arch.vgic.nr_regions;
+    acpi_size += PAGE_ALIGN(madt_size);

are the MADT and FADT tables guaranteed to be on separate pages or is it just an estimate?

Quoted 24 lines
xen/arch/arm/domain_build.c +24 -0
+    addr = acpi_os_get_root_pointer();
+    if ( !addr )
+    {
+        printk("Unable to get acpi root pointer\n");
+        return -EINVAL;
+    }
+    rsdp_tbl = acpi_os_map_memory(addr, sizeof(struct acpi_table_rsdp));
+    table = acpi_os_map_memory(rsdp_tbl->xsdt_physical_address,
+                               sizeof(struct acpi_table_header));
+    acpi_size += PAGE_ALIGN(table->length + sizeof(u64));
+    acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
+    acpi_os_unmap_memory(rsdp_tbl, sizeof(struct acpi_table_rsdp));
+
+    acpi_size += PAGE_ALIGN(sizeof(struct acpi_table_rsdp));
+    d->arch.efi_acpi_len = PAGE_ALIGN(efi_size) + PAGE_ALIGN(acpi_size);
+
+    return 0;
+}
+
+static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
+{
+    int rc = 0;
+    int order;
+

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1413

Quoted 10 lines
xen/arch/arm/domain_build.c +10 -0
+    rc = estimate_acpi_efi_size(d, kinfo);
+    if ( rc != 0 )
+        return rc;
+
+    order = get_order_from_bytes(d->arch.efi_acpi_len);
+    d->arch.efi_acpi_table = alloc_xenheap_pages(order, 0);
+    if ( d->arch.efi_acpi_table == NULL )
+    {
+        printk("unable to allocate memory!\n");
+        return -1;

ENOMEM

Quoted 54 lines
xen/arch/arm/domain_build.c +22 -1
+    }
+    memset(d->arch.efi_acpi_table, 0, d->arch.efi_acpi_len);
+
+    /* For ACPI, Dom0 doesn't use kinfo->gnttab_start to get the grant table
+     * region. So we use it as the ACPI table mapped address. */
+    d->arch.efi_acpi_gpa = kinfo->gnttab_start;
+
+    return 0;
+}
+#else
+static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
+{
+    /* Only booting with ACPI will hit here */
+    BUG_ON(1);
+    return -EINVAL;
+}
+#endif
 static void dtb_load(struct kernel_info *kinfo)
 {
     void * __user dtb_virt = (void * __user)(register_t)kinfo->dtb_paddr;
@@ -1540,7 +1614,11 @@ int construct_dom0(struct domain *d)
     allocate_memory(d, &kinfo);
     find_gnttab_region(d, &kinfo);
 
-    rc = prepare_dtb(d, &kinfo);
+    if ( acpi_disabled )
+        rc = prepare_dtb(d, &kinfo);
+    else
+        rc = prepare_acpi(d, &kinfo);
+
     if ( rc < 0 )
         return rc;
 
xen/common/efi/boot.c +6 -0
index 53c7452..78d8ae9 100644
@@ -13,6 +13,7 @@
 #include <xen/multiboot.h>
 #include <xen/pci_regs.h>
 #include <xen/pfn.h>
+#include <asm/acpi.h>
 #if EFI_PAGE_SIZE != PAGE_SIZE
 # error Cannot use xen/pfn.h here!
 #endif
@@ -1171,6 +1172,26 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
     for( ; ; ); /* not reached */
 }
 
+#ifdef CONFIG_ACPI
+/* Constant to indicate "Xen" in unicode u16 format */
+static const u16 XEN_EFI_FW_VENDOR[] ={0x0058,0x0065,0x006E,0x0000};
+
+int __init estimate_efi_size(int mem_nr_banks)

xen/common/efi/boot.c efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) · line 1189

Quoted 10 lines
xen/common/efi/boot.c +10 -0
+{
+    int size;
+    int est_size = sizeof(EFI_SYSTEM_TABLE);
+    int ect_size = sizeof(EFI_CONFIGURATION_TABLE);
+    int emd_size = sizeof(EFI_MEMORY_DESCRIPTOR);
+    int fw_vendor_size = sizeof(XEN_EFI_FW_VENDOR);
+
+    size = PAGE_ALIGN(est_size + ect_size + fw_vendor_size)
+           + PAGE_ALIGN(emd_size *
+                        (mem_nr_banks + acpi_mem.nr_banks + TBL_MMAX));

Why are they on two separate pages? Is it mandated by the EFI spec? Why are you adding TBL_MMAX to the multiplicand here?

I don't like that we are passing mem_nr_banks as argument but we are accessing acpi_mem.nr_banks from the global variable. I would prefer if they were both passed as arguments.

Quoted 23 lines
xen/common/efi/boot.c +4 -0
+    return size;
+}
+#endif
+
 #ifndef CONFIG_ARM /* TODO - runtime service support */
 
 static bool_t __initdata efi_rs_enable = 1;
xen/include/asm-arm/setup.h +2 -0
index 30ac53b..b759813 100644
@@ -51,6 +51,8 @@ void arch_init_memory(void);
 
 void copy_from_paddr(void *dst, paddr_t paddr, unsigned long len);
 
+int estimate_efi_size(int mem_nr_banks);
+
 int construct_dom0(struct domain *d);
 
 void discard_initial_modules(void);
Signature · 1 line
2.1.0

.

Signature · 1 line
Shannon
#214 lore raw

Re: [PATCH v3 40/62] arm/acpi: Estimate memory required for acpi/efi tables

In reply to shannon.zhao at linaro.org
Quoted 5 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Shannon Zhao <[email protected]>

Estimate the memory required for loading acpi/efi tables in Dom0. Alloc the pages to store the new created EFI and ACPI tables and free these pages when destroying domain.

Could you please explain what you are page aligning exactly and why?

Quoted 52 lines
---
 xen/arch/arm/domain.c       |  4 +++
 xen/arch/arm/domain_build.c | 80 ++++++++++++++++++++++++++++++++++++++++++++-
 xen/common/efi/boot.c       | 21 ++++++++++++
 xen/include/asm-arm/setup.h |  2 ++
 4 files changed, 106 insertions(+), 1 deletion(-)
xen/arch/arm/domain.c +4 -0
index 880d0a6..10c58c4 100644
@@ -638,6 +638,10 @@ void arch_domain_destroy(struct domain *d)
     domain_vgic_free(d);
     domain_vuart_free(d);
     free_xenheap_page(d->shared_info);
+#ifdef CONFIG_ACPI
+    free_xenheap_pages(d->arch.efi_acpi_table,
+                       get_order_from_bytes(d->arch.efi_acpi_len));
+#endif
 }
 
 void arch_domain_shutdown(struct domain *d)
xen/arch/arm/domain_build.c +12 -0
index 0c3441a..b5ed44c 100644
@@ -12,6 +12,8 @@
 #include <xen/libfdt/libfdt.h>
 #include <xen/guest_access.h>
 #include <xen/iocap.h>
+#include <xen/acpi.h>
+#include <acpi/actables.h>
 #include <asm/device.h>
 #include <asm/setup.h>
 #include <asm/platform.h>
@@ -1354,6 +1356,78 @@ static int prepare_dtb(struct domain *d, struct kernel_info *kinfo)
     return -EINVAL;
 }
 
+#ifdef CONFIG_ACPI
+static int estimate_acpi_efi_size(struct domain *d, struct kernel_info *kinfo)
+{
+    u64 efi_size, acpi_size = 0, addr;
+    u32 madt_size;
+    struct acpi_table_rsdp *rsdp_tbl;
+    struct acpi_table_header *table = NULL;
+
+    efi_size = estimate_efi_size(kinfo->mem.nr_banks);
+

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1378

Quoted 10 lines
xen/arch/arm/domain_build.c +10 -0
+    acpi_size += PAGE_ALIGN(sizeof(struct acpi_table_fadt));
+    acpi_size += PAGE_ALIGN(sizeof(struct acpi_table_stao));
+
+    madt_size = sizeof(struct acpi_table_madt)
+                + sizeof(struct acpi_madt_generic_interrupt) * d->max_vcpus
+                + sizeof(struct acpi_madt_generic_distributor);
+    if ( d->arch.vgic.version == GIC_V3 )
+        madt_size += sizeof(struct acpi_madt_generic_redistributor)
+                     * d->arch.vgic.nr_regions;
+    acpi_size += PAGE_ALIGN(madt_size);

are the MADT and FADT tables guaranteed to be on separate pages or is it just an estimate?

Quoted 24 lines
xen/arch/arm/domain_build.c +24 -0
+    addr = acpi_os_get_root_pointer();
+    if ( !addr )
+    {
+        printk("Unable to get acpi root pointer\n");
+        return -EINVAL;
+    }
+    rsdp_tbl = acpi_os_map_memory(addr, sizeof(struct acpi_table_rsdp));
+    table = acpi_os_map_memory(rsdp_tbl->xsdt_physical_address,
+                               sizeof(struct acpi_table_header));
+    acpi_size += PAGE_ALIGN(table->length + sizeof(u64));
+    acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
+    acpi_os_unmap_memory(rsdp_tbl, sizeof(struct acpi_table_rsdp));
+
+    acpi_size += PAGE_ALIGN(sizeof(struct acpi_table_rsdp));
+    d->arch.efi_acpi_len = PAGE_ALIGN(efi_size) + PAGE_ALIGN(acpi_size);
+
+    return 0;
+}
+
+static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
+{
+    int rc = 0;
+    int order;
+

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1413

Quoted 10 lines
xen/arch/arm/domain_build.c +10 -0
+    rc = estimate_acpi_efi_size(d, kinfo);
+    if ( rc != 0 )
+        return rc;
+
+    order = get_order_from_bytes(d->arch.efi_acpi_len);
+    d->arch.efi_acpi_table = alloc_xenheap_pages(order, 0);
+    if ( d->arch.efi_acpi_table == NULL )
+    {
+        printk("unable to allocate memory!\n");
+        return -1;

ENOMEM

Quoted 54 lines
xen/arch/arm/domain_build.c +22 -1
+    }
+    memset(d->arch.efi_acpi_table, 0, d->arch.efi_acpi_len);
+
+    /* For ACPI, Dom0 doesn't use kinfo->gnttab_start to get the grant table
+     * region. So we use it as the ACPI table mapped address. */
+    d->arch.efi_acpi_gpa = kinfo->gnttab_start;
+
+    return 0;
+}
+#else
+static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
+{
+    /* Only booting with ACPI will hit here */
+    BUG_ON(1);
+    return -EINVAL;
+}
+#endif
 static void dtb_load(struct kernel_info *kinfo)
 {
     void * __user dtb_virt = (void * __user)(register_t)kinfo->dtb_paddr;
@@ -1540,7 +1614,11 @@ int construct_dom0(struct domain *d)
     allocate_memory(d, &kinfo);
     find_gnttab_region(d, &kinfo);
 
-    rc = prepare_dtb(d, &kinfo);
+    if ( acpi_disabled )
+        rc = prepare_dtb(d, &kinfo);
+    else
+        rc = prepare_acpi(d, &kinfo);
+
     if ( rc < 0 )
         return rc;
 
xen/common/efi/boot.c +6 -0
index 53c7452..78d8ae9 100644
@@ -13,6 +13,7 @@
 #include <xen/multiboot.h>
 #include <xen/pci_regs.h>
 #include <xen/pfn.h>
+#include <asm/acpi.h>
 #if EFI_PAGE_SIZE != PAGE_SIZE
 # error Cannot use xen/pfn.h here!
 #endif
@@ -1171,6 +1172,26 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
     for( ; ; ); /* not reached */
 }
 
+#ifdef CONFIG_ACPI
+/* Constant to indicate "Xen" in unicode u16 format */
+static const u16 XEN_EFI_FW_VENDOR[] ={0x0058,0x0065,0x006E,0x0000};
+
+int __init estimate_efi_size(int mem_nr_banks)

xen/common/efi/boot.c efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) · line 1189

Quoted 10 lines
xen/common/efi/boot.c +10 -0
+{
+    int size;
+    int est_size = sizeof(EFI_SYSTEM_TABLE);
+    int ect_size = sizeof(EFI_CONFIGURATION_TABLE);
+    int emd_size = sizeof(EFI_MEMORY_DESCRIPTOR);
+    int fw_vendor_size = sizeof(XEN_EFI_FW_VENDOR);
+
+    size = PAGE_ALIGN(est_size + ect_size + fw_vendor_size)
+           + PAGE_ALIGN(emd_size *
+                        (mem_nr_banks + acpi_mem.nr_banks + TBL_MMAX));

Why are they on two separate pages? Is it mandated by the EFI spec? Why are you adding TBL_MMAX to the multiplicand here?

I don't like that we are passing mem_nr_banks as argument but we are accessing acpi_mem.nr_banks from the global variable. I would prefer if they were both passed as arguments.

Quoted 23 lines
xen/common/efi/boot.c +4 -0
+    return size;
+}
+#endif
+
 #ifndef CONFIG_ARM /* TODO - runtime service support */
 
 static bool_t __initdata efi_rs_enable = 1;
xen/include/asm-arm/setup.h +2 -0
index 30ac53b..b759813 100644
@@ -51,6 +51,8 @@ void arch_init_memory(void);
 
 void copy_from_paddr(void *dst, paddr_t paddr, unsigned long len);
 
+int estimate_efi_size(int mem_nr_banks);
+
 int construct_dom0(struct domain *d);
 
 void discard_initial_modules(void);
Signature · 1 line
2.1.0
#215 lore raw

PATCH v3 40/62 arm/acpi: Estimate memory required for acpi/efi tables

In reply to shannon.zhao at linaro.org

Hi Shannon,

Quoted 26 lines · shannon.zhao at linaro.org
xen/common/efi/boot.c +11 -0
index 53c7452..78d8ae9 100644
@@ -13,6 +13,7 @@
 #include <xen/multiboot.h>
 #include <xen/pci_regs.h>
 #include <xen/pfn.h>
+#include <asm/acpi.h>
 #if EFI_PAGE_SIZE != PAGE_SIZE
 # error Cannot use xen/pfn.h here!
 #endif
@@ -1171,6 +1172,26 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
     for( ; ; ); /* not reached */
 }
 
+#ifdef CONFIG_ACPI
+/* Constant to indicate "Xen" in unicode u16 format */
+static const u16 XEN_EFI_FW_VENDOR[] ={0x0058,0x0065,0x006E,0x0000};
+
+int __init estimate_efi_size(int mem_nr_banks)
+{
+    int size;
+    int est_size = sizeof(EFI_SYSTEM_TABLE);
+    int ect_size = sizeof(EFI_CONFIGURATION_TABLE);
+    int emd_size = sizeof(EFI_MEMORY_DESCRIPTOR);

xen/common/efi/boot.c efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) · line 1194

Quoted 10 lines
xen/common/efi/boot.c +10 -0
+    int fw_vendor_size = sizeof(XEN_EFI_FW_VENDOR);
+
+    size = PAGE_ALIGN(est_size + ect_size + fw_vendor_size)
+           + PAGE_ALIGN(emd_size *
+                        (mem_nr_banks + acpi_mem.nr_banks + TBL_MMAX));
+
+    return size;
+}
+#endif
+

efi/boot.c only contains code related to the stub EFI. This is not the case of this code.

Moreover, this code won't compile on x86 because acpi_mem is only defined for ARM.

Regards,

Signature · 1 line
Julien Grall
#216 lore raw

PATCH v3 40/62 arm/acpi: Estimate memory required for acpi/efi tables

Quoted 34 lines · Julien Grall

Hi Shannon,

Quoted 31 lines · shannon.zhao at linaro.org
xen/common/efi/boot.c +16 -0
index 53c7452..78d8ae9 100644
@@ -13,6 +13,7 @@
 #include <xen/multiboot.h>
 #include <xen/pci_regs.h>
 #include <xen/pfn.h>
+#include <asm/acpi.h>
 #if EFI_PAGE_SIZE != PAGE_SIZE
 # error Cannot use xen/pfn.h here!
 #endif
@@ -1171,6 +1172,26 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
     for( ; ; ); /* not reached */
 }
 
+#ifdef CONFIG_ACPI
+/* Constant to indicate "Xen" in unicode u16 format */
+static const u16 XEN_EFI_FW_VENDOR[] ={0x0058,0x0065,0x006E,0x0000};
+
+int __init estimate_efi_size(int mem_nr_banks)
+{
+    int size;
+    int est_size = sizeof(EFI_SYSTEM_TABLE);
+    int ect_size = sizeof(EFI_CONFIGURATION_TABLE);
+    int emd_size = sizeof(EFI_MEMORY_DESCRIPTOR);
+    int fw_vendor_size = sizeof(XEN_EFI_FW_VENDOR);
+
+    size = PAGE_ALIGN(est_size + ect_size + fw_vendor_size)
+           + PAGE_ALIGN(emd_size *
+                        (mem_nr_banks + acpi_mem.nr_banks + TBL_MMAX));
Quoted 9 lines

xen/common/efi/boot.c efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) · line 1194

Quoted 5 lines
xen/common/efi/boot.c +5 -0
+
+    return size;
+}
+#endif
+

efi/boot.c only contains code related to the stub EFI. This is not the case of this code.

I add these codes at this file because I want to reuse the definitions of EFI structures like EFI_SYSTEM_TABLE. Parth re-define those structures at previous patch set and one comment suggested to reuse the existing ones. If I add these codes in xen/arch/arm/domain_build.c, it will have some conflicts. E.g:

In file included from /home/open-source/xen/xen/include/asm/efibind.h:2:0,

                 from domain_build.c:29:
/home/open-source/xen/xen/include/asm/arm64/efibind.h:86:20: error:
conflicting types for 'UINT64'
 typedef uint64_t   UINT64;
                    ^
In file included from /home/open-source/xen/xen/include/acpi/acpi.h:57:0,
                 from /home/open-source/xen/xen/include/xen/acpi.h:33,
                 from domain_build.c:15:

/home/open-source/xen/xen/include/acpi/actypes.h:130:35: note: previous declaration of 'UINT64' was here
typedef COMPILER_DEPENDENT_UINT64 UINT64;

Quoted 5 lines

Moreover, this code won't compile on x86 because acpi_mem is only defined for ARM.

Regards,

Thanks,

Signature · 1 line
Shannon
#217 lore raw

PATCH v3 40/62 arm/acpi: Estimate memory required for acpi/efi tables

Quoted 60 lines · Shannon Zhao
Quoted 34 lines · Julien Grall

Hi Shannon,

Quoted 31 lines · shannon.zhao at linaro.org
xen/common/efi/boot.c +16 -0
index 53c7452..78d8ae9 100644
@@ -13,6 +13,7 @@
 #include <xen/multiboot.h>
 #include <xen/pci_regs.h>
 #include <xen/pfn.h>
+#include <asm/acpi.h>
 #if EFI_PAGE_SIZE != PAGE_SIZE
 # error Cannot use xen/pfn.h here!
 #endif
@@ -1171,6 +1172,26 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
     for( ; ; ); /* not reached */
 }
 
+#ifdef CONFIG_ACPI
+/* Constant to indicate "Xen" in unicode u16 format */
+static const u16 XEN_EFI_FW_VENDOR[] ={0x0058,0x0065,0x006E,0x0000};
+
+int __init estimate_efi_size(int mem_nr_banks)
+{
+    int size;
+    int est_size = sizeof(EFI_SYSTEM_TABLE);
+    int ect_size = sizeof(EFI_CONFIGURATION_TABLE);
+    int emd_size = sizeof(EFI_MEMORY_DESCRIPTOR);
+    int fw_vendor_size = sizeof(XEN_EFI_FW_VENDOR);
+
+    size = PAGE_ALIGN(est_size + ect_size + fw_vendor_size)
+           + PAGE_ALIGN(emd_size *
+                        (mem_nr_banks + acpi_mem.nr_banks + TBL_MMAX));
Quoted 9 lines

xen/common/efi/boot.c efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) · line 1194

Quoted 5 lines
xen/common/efi/boot.c +5 -0
+
+    return size;
+}
+#endif
+

efi/boot.c only contains code related to the stub EFI. This is not the case of this code.

I add these codes at this file because I want to reuse the definitions of EFI structures like EFI_SYSTEM_TABLE. Parth re-define those structures at previous patch set and one comment suggested to reuse the existing ones. If I add these codes in xen/arch/arm/domain_build.c, it will have some conflicts. E.g:

In file included from /home/open-source/xen/xen/include/asm/efibind.h:2:0,

                 from domain_build.c:29:
/home/open-source/xen/xen/include/asm/arm64/efibind.h:86:20: error:
conflicting types for 'UINT64'
 typedef uint64_t   UINT64;
                    ^
In file included from /home/open-source/xen/xen/include/acpi/acpi.h:57:0,
                 from /home/open-source/xen/xen/include/xen/acpi.h:33,
                 from domain_build.c:15:
Quoted 3 lines

/home/open-source/xen/xen/include/acpi/actypes.h:130:35: note: previous declaration of 'UINT64' was here
typedef COMPILER_DEPENDENT_UINT64 UINT64;

I think that having this code in efi/boot.c might be OK, but let's see what Jan thinks.

Quoted 10 lines
Quoted 5 lines

Moreover, this code won't compile on x86 because acpi_mem is only defined for ARM.

Regards,

Thanks,

Signature · 1 line
Shannon
#218 lore raw

Re: [PATCH v3 40/62] arm/acpi: Estimate memory required for acpi/efi tables

In reply to Shannon Zhao
Quoted 60 lines · Shannon Zhao
Quoted 34 lines · Julien Grall

Hi Shannon,

Quoted 31 lines · On 17/11/15 09:40, [email protected] wrote:
xen/common/efi/boot.c +16 -0
index 53c7452..78d8ae9 100644
@@ -13,6 +13,7 @@
 #include <xen/multiboot.h>
 #include <xen/pci_regs.h>
 #include <xen/pfn.h>
+#include <asm/acpi.h>
 #if EFI_PAGE_SIZE != PAGE_SIZE
 # error Cannot use xen/pfn.h here!
 #endif
@@ -1171,6 +1172,26 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
     for( ; ; ); /* not reached */
 }
 
+#ifdef CONFIG_ACPI
+/* Constant to indicate "Xen" in unicode u16 format */
+static const u16 XEN_EFI_FW_VENDOR[] ={0x0058,0x0065,0x006E,0x0000};
+
+int __init estimate_efi_size(int mem_nr_banks)
+{
+    int size;
+    int est_size = sizeof(EFI_SYSTEM_TABLE);
+    int ect_size = sizeof(EFI_CONFIGURATION_TABLE);
+    int emd_size = sizeof(EFI_MEMORY_DESCRIPTOR);
+    int fw_vendor_size = sizeof(XEN_EFI_FW_VENDOR);
+
+    size = PAGE_ALIGN(est_size + ect_size + fw_vendor_size)
+           + PAGE_ALIGN(emd_size *
+                        (mem_nr_banks + acpi_mem.nr_banks + TBL_MMAX));
Quoted 9 lines

xen/common/efi/boot.c efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) · line 1194

Quoted 5 lines
xen/common/efi/boot.c +5 -0
+
+    return size;
+}
+#endif
+

efi/boot.c only contains code related to the stub EFI. This is not the case of this code.

I add these codes at this file because I want to reuse the definitions of EFI structures like EFI_SYSTEM_TABLE. Parth re-define those structures at previous patch set and one comment suggested to reuse the existing ones. If I add these codes in xen/arch/arm/domain_build.c, it will have some conflicts. E.g:

In file included from /home/open-source/xen/xen/include/asm/efibind.h:2:0,

                 from domain_build.c:29:
/home/open-source/xen/xen/include/asm/arm64/efibind.h:86:20: error:
conflicting types for 'UINT64'
 typedef uint64_t   UINT64;
                    ^
In file included from /home/open-source/xen/xen/include/acpi/acpi.h:57:0,
                 from /home/open-source/xen/xen/include/xen/acpi.h:33,
                 from domain_build.c:15:
Quoted 3 lines

/home/open-source/xen/xen/include/acpi/actypes.h:130:35: note: previous declaration of 'UINT64' was here
typedef COMPILER_DEPENDENT_UINT64 UINT64;

I think that having this code in efi/boot.c might be OK, but let's see what Jan thinks.

Quoted 10 lines
Quoted 5 lines

Moreover, this code won't compile on x86 because acpi_mem is only defined for ARM.

Regards,

Thanks,

Signature · 1 line
Shannon
#219 lore raw

Re: [PATCH v3 40/62] arm/acpi: Estimate memory required for acpi/efi tables

In reply to Julien Grall
Quoted 34 lines · Julien Grall

Hi Shannon,

Quoted 31 lines · On 17/11/15 09:40, [email protected] wrote:
xen/common/efi/boot.c +16 -0
index 53c7452..78d8ae9 100644
@@ -13,6 +13,7 @@
 #include <xen/multiboot.h>
 #include <xen/pci_regs.h>
 #include <xen/pfn.h>
+#include <asm/acpi.h>
 #if EFI_PAGE_SIZE != PAGE_SIZE
 # error Cannot use xen/pfn.h here!
 #endif
@@ -1171,6 +1172,26 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
     for( ; ; ); /* not reached */
 }
 
+#ifdef CONFIG_ACPI
+/* Constant to indicate "Xen" in unicode u16 format */
+static const u16 XEN_EFI_FW_VENDOR[] ={0x0058,0x0065,0x006E,0x0000};
+
+int __init estimate_efi_size(int mem_nr_banks)
+{
+    int size;
+    int est_size = sizeof(EFI_SYSTEM_TABLE);
+    int ect_size = sizeof(EFI_CONFIGURATION_TABLE);
+    int emd_size = sizeof(EFI_MEMORY_DESCRIPTOR);
+    int fw_vendor_size = sizeof(XEN_EFI_FW_VENDOR);
+
+    size = PAGE_ALIGN(est_size + ect_size + fw_vendor_size)
+           + PAGE_ALIGN(emd_size *
+                        (mem_nr_banks + acpi_mem.nr_banks + TBL_MMAX));
Quoted 9 lines

xen/common/efi/boot.c efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) · line 1194

Quoted 5 lines
xen/common/efi/boot.c +5 -0
+
+    return size;
+}
+#endif
+

efi/boot.c only contains code related to the stub EFI. This is not the case of this code.

I add these codes at this file because I want to reuse the definitions of EFI structures like EFI_SYSTEM_TABLE. Parth re-define those structures at previous patch set and one comment suggested to reuse the existing ones. If I add these codes in xen/arch/arm/domain_build.c, it will have some conflicts. E.g:

In file included from /home/open-source/xen/xen/include/asm/efibind.h:2:0,

                 from domain_build.c:29:
/home/open-source/xen/xen/include/asm/arm64/efibind.h:86:20: error:
conflicting types for 'UINT64'
 typedef uint64_t   UINT64;
                    ^
In file included from /home/open-source/xen/xen/include/acpi/acpi.h:57:0,
                 from /home/open-source/xen/xen/include/xen/acpi.h:33,
                 from domain_build.c:15:

/home/open-source/xen/xen/include/acpi/actypes.h:130:35: note: previous declaration of 'UINT64' was here
typedef COMPILER_DEPENDENT_UINT64 UINT64;

Quoted 5 lines

Moreover, this code won't compile on x86 because acpi_mem is only defined for ARM.

Regards,

Thanks,

Signature · 1 line
Shannon
#220 lore raw

PATCH v3 41/62 arm/acpi: Add a helper function to get the acpi table offset

In reply to shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

---
 xen/arch/arm/acpi/lib.c    | 13 +++++++++++++
 xen/include/asm-arm/acpi.h |  6 ++++++
 2 files changed, 19 insertions(+)
xen/arch/arm/acpi/lib.c +13 -0
index 47f4c6a..d6044ef 100644
@@ -70,3 +70,16 @@ unsigned int acpi_get_irq_type(u32 flags)
         return ACPI_IRQ_TYPE_NONE;
     }
 }
+
+unsigned int acpi_get_table_offset(struct membank tbl_add[], EFI_MEM_RES index)
+{
+    int i;
+    unsigned int offset = 0;
+
+    for ( i = 0; i < index; i++ )
+    {
+        offset += PAGE_ALIGN(tbl_add[i].size);
+    }
+
+    return offset;
+}
xen/include/asm-arm/acpi.h +6 -0
index f159d51..628f3c8 100644
@@ -24,6 +24,7 @@
 #define _ASM_ARM_ACPI_H
 
 #include <xen/init.h>
+#include <asm/setup.h>
 
 #define COMPILER_DEPENDENT_INT64   long long
 #define COMPILER_DEPENDENT_UINT64  unsigned long long
@@ -47,11 +48,16 @@ bool_t __init acpi_psci_present(void);
 bool_t __init acpi_psci_hvc_present(void);
 void __init acpi_smp_init_cpus(void);
 unsigned int acpi_get_irq_type(u32 flags);
+unsigned int acpi_get_table_offset(struct membank tbl_add[], EFI_MEM_RES index);
 #else
 static inline bool_t acpi_psci_present(void) { return false; }
 static inline bool_t acpi_psci_hvc_present(void) {return false; }
 static inline void acpi_smp_init_cpus(void) { }
 static inline unsigned int acpi_get_irq_type(u32 flags) { return 0; }
+unsigned int acpi_get_table_offset(struct membank tbl_add[], EFI_MEM_RES index)
+{
+    return 0;
+}
 #endif /* CONFIG_ACPI */
 
 /* Basic configuration for ACPI */
Signature · 1 line
2.1.0
#221 lore raw

PATCH v3 41/62 arm/acpi: Add a helper function to get the acpi table offset

Quoted 3 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

It should probably be merged with patch #37.

Please add more details on how the offset is calculated, whether it is bytes, and why all the tables have been page aligned.

Quoted 12 lines
 xen/arch/arm/acpi/lib.c    | 13 +++++++++++++
 xen/include/asm-arm/acpi.h |  6 ++++++
 2 files changed, 19 insertions(+)
xen/arch/arm/acpi/lib.c +0 -0
index 47f4c6a..d6044ef 100644
@@ -70,3 +70,16 @@ unsigned int acpi_get_irq_type(u32 flags)
         return ACPI_IRQ_TYPE_NONE;
     }
 }

xen/arch/arm/acpi/lib.c unsigned int acpi_get_irq_type(u32 flags) · line 82

Quoted 10 lines
xen/arch/arm/acpi/lib.c +10 -0
+
+unsigned int acpi_get_table_offset(struct membank tbl_add[], EFI_MEM_RES index)
+{
+    int i;
+    unsigned int offset = 0;
+
+    for ( i = 0; i < index; i++ )
+    {
+        offset += PAGE_ALIGN(tbl_add[i].size);
+    }

Aside from the fact that I don't know if PAGE_ALIGNING each entry here is correct, the patch looks straightforward.

Quoted 34 lines
xen/arch/arm/acpi/lib.c +2 -0
+    return offset;
+}
xen/include/asm-arm/acpi.h +6 -0
index f159d51..628f3c8 100644
@@ -24,6 +24,7 @@
 #define _ASM_ARM_ACPI_H
 
 #include <xen/init.h>
+#include <asm/setup.h>
 
 #define COMPILER_DEPENDENT_INT64   long long
 #define COMPILER_DEPENDENT_UINT64  unsigned long long
@@ -47,11 +48,16 @@ bool_t __init acpi_psci_present(void);
 bool_t __init acpi_psci_hvc_present(void);
 void __init acpi_smp_init_cpus(void);
 unsigned int acpi_get_irq_type(u32 flags);
+unsigned int acpi_get_table_offset(struct membank tbl_add[], EFI_MEM_RES index);
 #else
 static inline bool_t acpi_psci_present(void) { return false; }
 static inline bool_t acpi_psci_hvc_present(void) {return false; }
 static inline void acpi_smp_init_cpus(void) { }
 static inline unsigned int acpi_get_irq_type(u32 flags) { return 0; }
+unsigned int acpi_get_table_offset(struct membank tbl_add[], EFI_MEM_RES index)
+{
+    return 0;
+}
 #endif /* CONFIG_ACPI */
 
 /* Basic configuration for ACPI */
Signature · 1 line
2.1.0
#222 lore raw

Re: [PATCH v3 41/62] arm/acpi: Add a helper function to get the acpi table offset

In reply to shannon.zhao at linaro.org
Quoted 3 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Shannon Zhao <[email protected]>

It should probably be merged with patch #37.

Please add more details on how the offset is calculated, whether it is bytes, and why all the tables have been page aligned.

Quoted 12 lines
 xen/arch/arm/acpi/lib.c    | 13 +++++++++++++
 xen/include/asm-arm/acpi.h |  6 ++++++
 2 files changed, 19 insertions(+)
xen/arch/arm/acpi/lib.c +0 -0
index 47f4c6a..d6044ef 100644
@@ -70,3 +70,16 @@ unsigned int acpi_get_irq_type(u32 flags)
         return ACPI_IRQ_TYPE_NONE;
     }
 }

xen/arch/arm/acpi/lib.c unsigned int acpi_get_irq_type(u32 flags) · line 82

Quoted 10 lines
xen/arch/arm/acpi/lib.c +10 -0
+
+unsigned int acpi_get_table_offset(struct membank tbl_add[], EFI_MEM_RES index)
+{
+    int i;
+    unsigned int offset = 0;
+
+    for ( i = 0; i < index; i++ )
+    {
+        offset += PAGE_ALIGN(tbl_add[i].size);
+    }

Aside from the fact that I don't know if PAGE_ALIGNING each entry here is correct, the patch looks straightforward.

Quoted 34 lines
xen/arch/arm/acpi/lib.c +2 -0
+    return offset;
+}
xen/include/asm-arm/acpi.h +6 -0
index f159d51..628f3c8 100644
@@ -24,6 +24,7 @@
 #define _ASM_ARM_ACPI_H
 
 #include <xen/init.h>
+#include <asm/setup.h>
 
 #define COMPILER_DEPENDENT_INT64   long long
 #define COMPILER_DEPENDENT_UINT64  unsigned long long
@@ -47,11 +48,16 @@ bool_t __init acpi_psci_present(void);
 bool_t __init acpi_psci_hvc_present(void);
 void __init acpi_smp_init_cpus(void);
 unsigned int acpi_get_irq_type(u32 flags);
+unsigned int acpi_get_table_offset(struct membank tbl_add[], EFI_MEM_RES index);
 #else
 static inline bool_t acpi_psci_present(void) { return false; }
 static inline bool_t acpi_psci_hvc_present(void) {return false; }
 static inline void acpi_smp_init_cpus(void) { }
 static inline unsigned int acpi_get_irq_type(u32 flags) { return 0; }
+unsigned int acpi_get_table_offset(struct membank tbl_add[], EFI_MEM_RES index)
+{
+    return 0;
+}
 #endif /* CONFIG_ACPI */
 
 /* Basic configuration for ACPI */
Signature · 1 line
2.1.0
#223 lore raw

PATCH v3 42/62 arm/acpi: Prepare FADT table for Dom0

In reply to shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Copy and modify FADT table before passing it to Dom0. Set PSCI_COMPLIANT and PSCI_USE_HVC.

---
 xen/arch/arm/domain_build.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)
xen/arch/arm/domain_build.c +45 -0
index b5ed44c..5d03dc0 100644
@@ -1357,6 +1357,46 @@ static int prepare_dtb(struct domain *d, struct kernel_info *kinfo)
 }
 
 #ifdef CONFIG_ACPI
+#define XEN_HYPERVISOR_ID 0x000058656E564D4D  /* "XenVMM" */
+
+static int acpi_create_fadt(struct domain *d, struct membank tbl_add[])
+{
+    struct acpi_table_header *table = NULL;
+    struct acpi_table_fadt *fadt = NULL;
+    u64 table_size;
+    acpi_status status;
+    u8 *base_ptr;
+    u8 checksum;
+
+    status = acpi_get_table(ACPI_SIG_FADT, 0, &table);
+
+    if ( ACPI_FAILURE(status) )
+    {
+        const char *msg = acpi_format_exception(status);
+
+        printk("Failed to get FADT table, %s\n", msg);
+        return -EINVAL;
+    }
+
+    table_size = table->length;
+    base_ptr = d->arch.efi_acpi_table
+               + acpi_get_table_offset(tbl_add, TBL_FADT);
+    ACPI_MEMCPY(base_ptr, table, table_size);
+    fadt = (struct acpi_table_fadt *)base_ptr;
+
+    /* Set PSCI_COMPLIANT and PSCI_USE_HVC */
+    fadt->arm_boot_flags |= (ACPI_FADT_PSCI_COMPLIANT | ACPI_FADT_PSCI_USE_HVC);
+    fadt->hypervisor_id = XEN_HYPERVISOR_ID;
+    checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, fadt), table_size);
+    fadt->header.checksum -= checksum;
+
+    tbl_add[TBL_FADT].start = d->arch.efi_acpi_gpa
+                              + acpi_get_table_offset(tbl_add, TBL_FADT);
+    tbl_add[TBL_FADT].size = table_size;
+
+    return 0;
+}
+
 static int estimate_acpi_efi_size(struct domain *d, struct kernel_info *kinfo)
 {
     u64 efi_size, acpi_size = 0, addr;
@@ -1400,6 +1440,7 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
 {
     int rc = 0;
     int order;
+    struct membank tbl_add[TBL_MMAX] = {};
 
     rc = estimate_acpi_efi_size(d, kinfo);
     if ( rc != 0 )
@@ -1418,6 +1459,10 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
      * region. So we use it as the ACPI table mapped address. */
     d->arch.efi_acpi_gpa = kinfo->gnttab_start;
 
+    rc = acpi_create_fadt(d, tbl_add);
+    if ( rc != 0 )
+        return rc;
+
     return 0;
 }
 #else
Signature · 1 line
2.1.0
#224 lore raw

PATCH v3 42/62 arm/acpi: Prepare FADT table for Dom0

Quoted 15 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Copy and modify FADT table before passing it to Dom0. Set PSCI_COMPLIANT and PSCI_USE_HVC.

 xen/arch/arm/domain_build.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)
xen/arch/arm/domain_build.c +0 -0
index b5ed44c..5d03dc0 100644

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1360

Quoted 4 lines
xen/arch/arm/domain_build.c +1 -0
@@ -1357,6 +1357,46 @@ static int prepare_dtb(struct domain *d, struct kernel_info *kinfo)
 }
 
 #ifdef CONFIG_ACPI
+#define XEN_HYPERVISOR_ID 0x000058656E564D4D  /* "XenVMM" */

This needs to be documented somewhere. A new doc under docs/ might be enough.

Quoted 69 lines
xen/arch/arm/domain_build.c +43 -0
+static int acpi_create_fadt(struct domain *d, struct membank tbl_add[])
+{
+    struct acpi_table_header *table = NULL;
+    struct acpi_table_fadt *fadt = NULL;
+    u64 table_size;
+    acpi_status status;
+    u8 *base_ptr;
+    u8 checksum;
+
+    status = acpi_get_table(ACPI_SIG_FADT, 0, &table);
+
+    if ( ACPI_FAILURE(status) )
+    {
+        const char *msg = acpi_format_exception(status);
+
+        printk("Failed to get FADT table, %s\n", msg);
+        return -EINVAL;
+    }
+
+    table_size = table->length;
+    base_ptr = d->arch.efi_acpi_table
+               + acpi_get_table_offset(tbl_add, TBL_FADT);
+    ACPI_MEMCPY(base_ptr, table, table_size);
+    fadt = (struct acpi_table_fadt *)base_ptr;
+
+    /* Set PSCI_COMPLIANT and PSCI_USE_HVC */
+    fadt->arm_boot_flags |= (ACPI_FADT_PSCI_COMPLIANT | ACPI_FADT_PSCI_USE_HVC);
+    fadt->hypervisor_id = XEN_HYPERVISOR_ID;
+    checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, fadt), table_size);
+    fadt->header.checksum -= checksum;
+
+    tbl_add[TBL_FADT].start = d->arch.efi_acpi_gpa
+                              + acpi_get_table_offset(tbl_add, TBL_FADT);
+    tbl_add[TBL_FADT].size = table_size;
+
+    return 0;
+}
+
 static int estimate_acpi_efi_size(struct domain *d, struct kernel_info *kinfo)
 {
     u64 efi_size, acpi_size = 0, addr;
@@ -1400,6 +1440,7 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
 {
     int rc = 0;
     int order;
+    struct membank tbl_add[TBL_MMAX] = {};
 
     rc = estimate_acpi_efi_size(d, kinfo);
     if ( rc != 0 )
@@ -1418,6 +1459,10 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
      * region. So we use it as the ACPI table mapped address. */
     d->arch.efi_acpi_gpa = kinfo->gnttab_start;
 
+    rc = acpi_create_fadt(d, tbl_add);
+    if ( rc != 0 )
+        return rc;
+
     return 0;
 }
 #else
Signature · 7 lines
2.1.0


_______________________________________________
Xen-devel mailing list
Xen-devel at lists.xen.org
http://lists.xen.org/xen-devel
#225 lore raw

PATCH v3 42/62 arm/acpi: Prepare FADT table for Dom0

Quoted 13 lines · Stefano Stabellini
Quoted 12 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Copy and modify FADT table before passing it to Dom0. Set PSCI_COMPLIANT
and PSCI_USE_HVC.

?xen/arch/arm/domain_build.c | 45
+++++++++++++++++++++++++++++++++++++++++++++
?1 file changed, 45 insertions(+)

Quoted 13 lines
Quoted 10 lines
xen/arch/arm/domain_build.c +0 -0
index b5ed44c..5d03dc0 100644
@@ -1357,6 +1357,46 @@ static int prepare_dtb(struct domain *d, struct
 kernel_info *kinfo)
 ?}

?
?#ifdef CONFIG_ACPI
+#define XEN_HYPERVISOR_ID 0x000058656E564D4D??/* "XenVMM" */

This needs to be documented somewhere. A new doc under docs/ might be enough.

Should (also?) probably be in xen/include/public/arch-arm.h in the same "#if defined(__XEN__) || defined(__XEN_TOOLS__)" as the other guest non-ABI stuff[0] which is needed by both Xen and the toolstack.

We don't actually have ACPI guest support today, so the toolstack has no current interest, but I think that is still a logical place for it do be defined.

Ian.

[0] That is, stuff which is part of the current implementation but which is exposed to guests through other means, e.g. DT or ACPI and not through the use of the arch-arm.h public header.

#226 lore raw

Re: [PATCH v3 42/62] arm/acpi: Prepare FADT table for Dom0

In reply to Stefano Stabellini
Quoted 13 lines · Stefano Stabellini
Quoted 12 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Shannon Zhao <[email protected]>

Copy and modify FADT table before passing it to Dom0. Set PSCI_COMPLIANT
and PSCI_USE_HVC.

 xen/arch/arm/domain_build.c | 45
+++++++++++++++++++++++++++++++++++++++++++++

 1 file changed, 45 insertions(+)
Quoted 13 lines
Quoted 10 lines
xen/arch/arm/domain_build.c +0 -0
index b5ed44c..5d03dc0 100644
@@ -1357,6 +1357,46 @@ static int prepare_dtb(struct domain *d, struct
 kernel_info *kinfo)
  }


 #ifdef CONFIG_ACPI
+#define XEN_HYPERVISOR_ID 0x000058656E564D4D  /* "XenVMM" */

This needs to be documented somewhere. A new doc under docs/ might be enough.

Should (also?) probably be in xen/include/public/arch-arm.h in the same "#if defined(__XEN__) || defined(__XEN_TOOLS__)" as the other guest non-ABI stuff[0] which is needed by both Xen and the toolstack.

We don't actually have ACPI guest support today, so the toolstack has no current interest, but I think that is still a logical place for it do be defined.

Ian.

[0] That is, stuff which is part of the current implementation but which is exposed to guests through other means, e.g. DT or ACPI and not through the use of the arch-arm.h public header.

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

#227 lore raw

Re: [PATCH v3 42/62] arm/acpi: Prepare FADT table for Dom0

In reply to shannon.zhao at linaro.org
Quoted 15 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Shannon Zhao <[email protected]>

Copy and modify FADT table before passing it to Dom0. Set PSCI_COMPLIANT and PSCI_USE_HVC.

 xen/arch/arm/domain_build.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)
xen/arch/arm/domain_build.c +0 -0
index b5ed44c..5d03dc0 100644

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1360

Quoted 4 lines
xen/arch/arm/domain_build.c +1 -0
@@ -1357,6 +1357,46 @@ static int prepare_dtb(struct domain *d, struct kernel_info *kinfo)
 }
 
 #ifdef CONFIG_ACPI
+#define XEN_HYPERVISOR_ID 0x000058656E564D4D  /* "XenVMM" */

This needs to be documented somewhere. A new doc under docs/ might be enough.

Quoted 69 lines
xen/arch/arm/domain_build.c +43 -0
+static int acpi_create_fadt(struct domain *d, struct membank tbl_add[])
+{
+    struct acpi_table_header *table = NULL;
+    struct acpi_table_fadt *fadt = NULL;
+    u64 table_size;
+    acpi_status status;
+    u8 *base_ptr;
+    u8 checksum;
+
+    status = acpi_get_table(ACPI_SIG_FADT, 0, &table);
+
+    if ( ACPI_FAILURE(status) )
+    {
+        const char *msg = acpi_format_exception(status);
+
+        printk("Failed to get FADT table, %s\n", msg);
+        return -EINVAL;
+    }
+
+    table_size = table->length;
+    base_ptr = d->arch.efi_acpi_table
+               + acpi_get_table_offset(tbl_add, TBL_FADT);
+    ACPI_MEMCPY(base_ptr, table, table_size);
+    fadt = (struct acpi_table_fadt *)base_ptr;
+
+    /* Set PSCI_COMPLIANT and PSCI_USE_HVC */
+    fadt->arm_boot_flags |= (ACPI_FADT_PSCI_COMPLIANT | ACPI_FADT_PSCI_USE_HVC);
+    fadt->hypervisor_id = XEN_HYPERVISOR_ID;
+    checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, fadt), table_size);
+    fadt->header.checksum -= checksum;
+
+    tbl_add[TBL_FADT].start = d->arch.efi_acpi_gpa
+                              + acpi_get_table_offset(tbl_add, TBL_FADT);
+    tbl_add[TBL_FADT].size = table_size;
+
+    return 0;
+}
+
 static int estimate_acpi_efi_size(struct domain *d, struct kernel_info *kinfo)
 {
     u64 efi_size, acpi_size = 0, addr;
@@ -1400,6 +1440,7 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
 {
     int rc = 0;
     int order;
+    struct membank tbl_add[TBL_MMAX] = {};
 
     rc = estimate_acpi_efi_size(d, kinfo);
     if ( rc != 0 )
@@ -1418,6 +1459,10 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
      * region. So we use it as the ACPI table mapped address. */
     d->arch.efi_acpi_gpa = kinfo->gnttab_start;
 
+    rc = acpi_create_fadt(d, tbl_add);
+    if ( rc != 0 )
+        return rc;
+
     return 0;
 }
 #else
Signature · 7 lines
2.1.0


_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
#228 lore raw

PATCH v3 43/62 arm/acpi: Prepare MADT table for Dom0

In reply to shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Copy and modify MADT table before passing it to Dom0. Copy dom0_max_vcpus of GICCs and GICD as well.

---
 xen/arch/arm/domain_build.c | 98 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 98 insertions(+)
xen/arch/arm/domain_build.c +98 -0
index 5d03dc0..4591955 100644
@@ -1359,6 +1359,100 @@ static int prepare_dtb(struct domain *d, struct kernel_info *kinfo)
 #ifdef CONFIG_ACPI
 #define XEN_HYPERVISOR_ID 0x000058656E564D4D  /* "XenVMM" */
 
+static int acpi_create_madt(struct domain *d, struct membank tbl_add[])
+{
+    struct acpi_table_header *table = NULL;
+    struct acpi_table_madt *madt = NULL;
+    struct acpi_madt_generic_distributor gicd;
+    u64 table_size = sizeof(struct acpi_table_madt);
+    acpi_status status;
+    int i;
+    u8 *base_ptr;
+    u8 checksum;
+
+    status = acpi_get_table(ACPI_SIG_MADT, 0, &table);
+
+    if ( ACPI_FAILURE(status) )
+    {
+        const char *msg = acpi_format_exception(status);
+
+        printk("Failed to get MADT table, %s\n", msg);
+        return -EINVAL;
+    }
+
+    base_ptr = d->arch.efi_acpi_table
+               + acpi_get_table_offset(tbl_add, TBL_MADT);
+    ACPI_MEMCPY(base_ptr, table, table_size);
+
+    /* Add Generic Distributor */
+    memset(&gicd, 0, sizeof(gicd));
+    gicd.header.type = ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR;
+    gicd.header.length = sizeof(gicd);
+    gicd.base_address = d->arch.vgic.dbase;
+    if ( d->arch.vgic.version == GIC_V2 )
+        gicd.version = ACPI_MADT_GIC_VERSION_V2;
+    else if ( d->arch.vgic.version == GIC_V3 )
+        gicd.version = ACPI_MADT_GIC_VERSION_V3;
+    else
+        gicd.version = ACPI_MADT_GIC_VERSION_NONE;
+    ACPI_MEMCPY(base_ptr + table_size, &gicd, sizeof(gicd));
+    table_size += sizeof(gicd);
+
+    if ( d->arch.vgic.version == GIC_V3 ) {
+        /* Add Generic Redistributor */
+        for ( i = 0; i < d->arch.vgic.nr_regions; i++ ) {
+            struct acpi_madt_generic_redistributor gicr;
+
+            memset(&gicr, 0, sizeof(gicr));
+            gicr.header.type = ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR;
+            gicr.header.length = sizeof(gicr);
+            gicr.base_address = d->arch.vgic.rdist_regions[i].base;
+            gicr.length = d->arch.vgic.rdist_regions[i].size;
+            ACPI_MEMCPY(base_ptr + table_size, &gicr, sizeof(gicr));
+            table_size += sizeof(gicr);
+        }
+    } else {
+        /* Add Generic Interrupt */
+        for ( i = 0; i < d->max_vcpus; i++ )
+        {
+            struct acpi_madt_generic_interrupt gicc;
+            u64 mpidr = 0;
+            u32 id = i, j = 0;
+
+            memset(&gicc, 0, sizeof(gicc));
+            gicc.header.type = ACPI_MADT_TYPE_GENERIC_INTERRUPT;
+            gicc.header.length = sizeof(gicc);
+            gicc.cpu_interface_number = i;
+            gicc.uid = i;
+            gicc.flags = ACPI_MADT_ENABLED;
+            gicc.base_address = d->arch.vgic.cbase;
+
+            do {
+                mpidr |= (id % 4) << (8 * j);
+                j++;
+                if ( j ==3 )
+                    j++;
+                id = id / 4;
+            } while(id > 0);
+            gicc.arm_mpidr = mpidr;
+
+            ACPI_MEMCPY(base_ptr + table_size, &gicc, sizeof(gicc));
+            table_size += sizeof(gicc);
+        }
+    }
+
+    madt = (struct acpi_table_madt *)base_ptr;
+    madt->header.length = table_size;
+    checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, madt), table_size);
+    madt->header.checksum -= checksum;
+
+    tbl_add[TBL_MADT].start = d->arch.efi_acpi_gpa
+                              + acpi_get_table_offset(tbl_add, TBL_MADT);
+    tbl_add[TBL_MADT].size = table_size;
+
+    return 0;
+}
+
 static int acpi_create_fadt(struct domain *d, struct membank tbl_add[])
 {
     struct acpi_table_header *table = NULL;
@@ -1463,6 +1557,10 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
     if ( rc != 0 )
         return rc;
 
+    rc = acpi_create_madt(d, tbl_add);
+    if ( rc != 0 )
+        return rc;
+
     return 0;
 }
 #else
Signature · 1 line
2.1.0
#229 lore raw

PATCH v3 43/62 arm/acpi: Prepare MADT table for Dom0

Quoted 51 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Copy and modify MADT table before passing it to Dom0. Copy dom0_max_vcpus of GICCs and GICD as well.

---
 xen/arch/arm/domain_build.c | 98 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 98 insertions(+)
xen/arch/arm/domain_build.c +33 -0
index 5d03dc0..4591955 100644
@@ -1359,6 +1359,100 @@ static int prepare_dtb(struct domain *d, struct kernel_info *kinfo)
 #ifdef CONFIG_ACPI
 #define XEN_HYPERVISOR_ID 0x000058656E564D4D  /* "XenVMM" */
 
+static int acpi_create_madt(struct domain *d, struct membank tbl_add[])
+{
+    struct acpi_table_header *table = NULL;
+    struct acpi_table_madt *madt = NULL;
+    struct acpi_madt_generic_distributor gicd;
+    u64 table_size = sizeof(struct acpi_table_madt);
+    acpi_status status;
+    int i;
+    u8 *base_ptr;
+    u8 checksum;
+
+    status = acpi_get_table(ACPI_SIG_MADT, 0, &table);
+
+    if ( ACPI_FAILURE(status) )
+    {
+        const char *msg = acpi_format_exception(status);
+
+        printk("Failed to get MADT table, %s\n", msg);
+        return -EINVAL;
+    }
+
+    base_ptr = d->arch.efi_acpi_table
+               + acpi_get_table_offset(tbl_add, TBL_MADT);
+    ACPI_MEMCPY(base_ptr, table, table_size);
+
+    /* Add Generic Distributor */
+    memset(&gicd, 0, sizeof(gicd));
+    gicd.header.type = ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR;
+    gicd.header.length = sizeof(gicd);
+    gicd.base_address = d->arch.vgic.dbase;
+    if ( d->arch.vgic.version == GIC_V2 )
+        gicd.version = ACPI_MADT_GIC_VERSION_V2;
+    else if ( d->arch.vgic.version == GIC_V3 )

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1404

Quoted 10 lines
xen/arch/arm/domain_build.c +10 -0
+        gicd.version = ACPI_MADT_GIC_VERSION_V3;
+    else
+        gicd.version = ACPI_MADT_GIC_VERSION_NONE;
+    ACPI_MEMCPY(base_ptr + table_size, &gicd, sizeof(gicd));
+
+    table_size += sizeof(gicd);
+
+    if ( d->arch.vgic.version == GIC_V3 ) {
+        /* Add Generic Redistributor */
+        for ( i = 0; i < d->arch.vgic.nr_regions; i++ ) {

Coding style

Quoted 23 lines
xen/arch/arm/domain_build.c +23 -0
+            struct acpi_madt_generic_redistributor gicr;
+
+            memset(&gicr, 0, sizeof(gicr));
+            gicr.header.type = ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR;
+            gicr.header.length = sizeof(gicr);
+            gicr.base_address = d->arch.vgic.rdist_regions[i].base;
+            gicr.length = d->arch.vgic.rdist_regions[i].size;
+            ACPI_MEMCPY(base_ptr + table_size, &gicr, sizeof(gicr));
+            table_size += sizeof(gicr);
+        }
+    } else {
+        /* Add Generic Interrupt */
+        for ( i = 0; i < d->max_vcpus; i++ )
+        {
+            struct acpi_madt_generic_interrupt gicc;
+            u64 mpidr = 0;
+            u32 id = i, j = 0;
+
+            memset(&gicc, 0, sizeof(gicc));
+            gicc.header.type = ACPI_MADT_TYPE_GENERIC_INTERRUPT;
+            gicc.header.length = sizeof(gicc);
+            gicc.cpu_interface_number = i;
+            gicc.uid = i;

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1436

Quoted 10 lines
xen/arch/arm/domain_build.c +10 -0
+            gicc.flags = ACPI_MADT_ENABLED;
+            gicc.base_address = d->arch.vgic.cbase;
+
+            do {
+                mpidr |= (id % 4) << (8 * j);
+                j++;
+                if ( j ==3 )
+                    j++;
+                id = id / 4;
+            } while(id > 0);

You should be able to use vcpuid_to_vaffinity to calculate the vmpidr.

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1437

Quoted 1 line
xen/arch/arm/domain_build.c +1 -0
+            gicc.arm_mpidr = mpidr;

We should probably copy the native value of "Processor Power Efficiency Class" ?

Quoted 34 lines
xen/arch/arm/domain_build.c +21 -0
+            ACPI_MEMCPY(base_ptr + table_size, &gicc, sizeof(gicc));
+            table_size += sizeof(gicc);
+        }
+    }
+
+    madt = (struct acpi_table_madt *)base_ptr;
+    madt->header.length = table_size;
+    checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, madt), table_size);
+    madt->header.checksum -= checksum;
+
+    tbl_add[TBL_MADT].start = d->arch.efi_acpi_gpa
+                              + acpi_get_table_offset(tbl_add, TBL_MADT);
+    tbl_add[TBL_MADT].size = table_size;
+
+    return 0;
+}
+
 static int acpi_create_fadt(struct domain *d, struct membank tbl_add[])
 {
     struct acpi_table_header *table = NULL;
@@ -1463,6 +1557,10 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
     if ( rc != 0 )
         return rc;
 
+    rc = acpi_create_madt(d, tbl_add);
+    if ( rc != 0 )
+        return rc;
+
     return 0;
 }
 #else
Signature · 1 line
2.1.0
#230 lore raw

Re: [PATCH v3 43/62] arm/acpi: Prepare MADT table for Dom0

In reply to shannon.zhao at linaro.org
Quoted 51 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Shannon Zhao <[email protected]>

Copy and modify MADT table before passing it to Dom0. Copy dom0_max_vcpus of GICCs and GICD as well.

---
 xen/arch/arm/domain_build.c | 98 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 98 insertions(+)
xen/arch/arm/domain_build.c +33 -0
index 5d03dc0..4591955 100644
@@ -1359,6 +1359,100 @@ static int prepare_dtb(struct domain *d, struct kernel_info *kinfo)
 #ifdef CONFIG_ACPI
 #define XEN_HYPERVISOR_ID 0x000058656E564D4D  /* "XenVMM" */
 
+static int acpi_create_madt(struct domain *d, struct membank tbl_add[])
+{
+    struct acpi_table_header *table = NULL;
+    struct acpi_table_madt *madt = NULL;
+    struct acpi_madt_generic_distributor gicd;
+    u64 table_size = sizeof(struct acpi_table_madt);
+    acpi_status status;
+    int i;
+    u8 *base_ptr;
+    u8 checksum;
+
+    status = acpi_get_table(ACPI_SIG_MADT, 0, &table);
+
+    if ( ACPI_FAILURE(status) )
+    {
+        const char *msg = acpi_format_exception(status);
+
+        printk("Failed to get MADT table, %s\n", msg);
+        return -EINVAL;
+    }
+
+    base_ptr = d->arch.efi_acpi_table
+               + acpi_get_table_offset(tbl_add, TBL_MADT);
+    ACPI_MEMCPY(base_ptr, table, table_size);
+
+    /* Add Generic Distributor */
+    memset(&gicd, 0, sizeof(gicd));
+    gicd.header.type = ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR;
+    gicd.header.length = sizeof(gicd);
+    gicd.base_address = d->arch.vgic.dbase;
+    if ( d->arch.vgic.version == GIC_V2 )
+        gicd.version = ACPI_MADT_GIC_VERSION_V2;
+    else if ( d->arch.vgic.version == GIC_V3 )

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1404

Quoted 10 lines
xen/arch/arm/domain_build.c +10 -0
+        gicd.version = ACPI_MADT_GIC_VERSION_V3;
+    else
+        gicd.version = ACPI_MADT_GIC_VERSION_NONE;
+    ACPI_MEMCPY(base_ptr + table_size, &gicd, sizeof(gicd));
+
+    table_size += sizeof(gicd);
+
+    if ( d->arch.vgic.version == GIC_V3 ) {
+        /* Add Generic Redistributor */
+        for ( i = 0; i < d->arch.vgic.nr_regions; i++ ) {

Coding style

Quoted 23 lines
xen/arch/arm/domain_build.c +23 -0
+            struct acpi_madt_generic_redistributor gicr;
+
+            memset(&gicr, 0, sizeof(gicr));
+            gicr.header.type = ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR;
+            gicr.header.length = sizeof(gicr);
+            gicr.base_address = d->arch.vgic.rdist_regions[i].base;
+            gicr.length = d->arch.vgic.rdist_regions[i].size;
+            ACPI_MEMCPY(base_ptr + table_size, &gicr, sizeof(gicr));
+            table_size += sizeof(gicr);
+        }
+    } else {
+        /* Add Generic Interrupt */
+        for ( i = 0; i < d->max_vcpus; i++ )
+        {
+            struct acpi_madt_generic_interrupt gicc;
+            u64 mpidr = 0;
+            u32 id = i, j = 0;
+
+            memset(&gicc, 0, sizeof(gicc));
+            gicc.header.type = ACPI_MADT_TYPE_GENERIC_INTERRUPT;
+            gicc.header.length = sizeof(gicc);
+            gicc.cpu_interface_number = i;
+            gicc.uid = i;

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1436

Quoted 10 lines
xen/arch/arm/domain_build.c +10 -0
+            gicc.flags = ACPI_MADT_ENABLED;
+            gicc.base_address = d->arch.vgic.cbase;
+
+            do {
+                mpidr |= (id % 4) << (8 * j);
+                j++;
+                if ( j ==3 )
+                    j++;
+                id = id / 4;
+            } while(id > 0);

You should be able to use vcpuid_to_vaffinity to calculate the vmpidr.

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1437

Quoted 1 line
xen/arch/arm/domain_build.c +1 -0
+            gicc.arm_mpidr = mpidr;

We should probably copy the native value of "Processor Power Efficiency Class" ?

Quoted 34 lines
xen/arch/arm/domain_build.c +21 -0
+            ACPI_MEMCPY(base_ptr + table_size, &gicc, sizeof(gicc));
+            table_size += sizeof(gicc);
+        }
+    }
+
+    madt = (struct acpi_table_madt *)base_ptr;
+    madt->header.length = table_size;
+    checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, madt), table_size);
+    madt->header.checksum -= checksum;
+
+    tbl_add[TBL_MADT].start = d->arch.efi_acpi_gpa
+                              + acpi_get_table_offset(tbl_add, TBL_MADT);
+    tbl_add[TBL_MADT].size = table_size;
+
+    return 0;
+}
+
 static int acpi_create_fadt(struct domain *d, struct membank tbl_add[])
 {
     struct acpi_table_header *table = NULL;
@@ -1463,6 +1557,10 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
     if ( rc != 0 )
         return rc;
 
+    rc = acpi_create_madt(d, tbl_add);
+    if ( rc != 0 )
+        return rc;
+
     return 0;
 }
 #else
Signature · 1 line
2.1.0
#231 lore raw

PATCH v3 44/62 ACPICA: ACPI 6.0: Add support for STAO table

In reply to shannon.zhao at linaro.org

From: Bob Moore <[email protected]>

ACPICA commit 532bf402a503061afd9d80a23e1d3c8fd99b052c

_STA override table.

---
 xen/include/acpi/actbl3.h | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
xen/include/acpi/actbl3.h +16 -0
index fc96963..cb9e1c0 100644
@@ -68,6 +68,7 @@
 #define ACPI_SIG_PCCT           "PCCT"	/* Platform Communications Channel Table */
 #define ACPI_SIG_PMTT           "PMTT"	/* Platform Memory Topology Table */
 #define ACPI_SIG_RASF           "RASF"	/* RAS Feature table */
+#define ACPI_SIG_STAO           "STAO" /* Status Override table */
 
 #define ACPI_SIG_S3PT           "S3PT"	/* S3 Performance (sub)Table */
 #define ACPI_SIG_PCCS           "PCC"	/* PCC Shared Memory Region */
@@ -618,6 +619,21 @@ enum acpi_rasf_status {
 #define ACPI_RASF_ERROR                 (1<<2)
 #define ACPI_RASF_STATUS                (0x1F<<3)
 
+/*******************************************************************************
+ *
+ * STAO - Status Override Table (_STA override) - ACPI 6.0
+ *        Version 1
+ *
+ * Conforms to "ACPI Specification for Status Override Table"
+ * 6 January 2015
+ *
+ ******************************************************************************/
+
+struct acpi_table_stao {
+	struct acpi_table_header header;	/* Common ACPI table header */
+	u8 ignore_uart;
+};
+
 /* Reset to default packing */
 
 #pragma pack()
Signature · 1 line
2.1.0
#232 lore raw

PATCH v3 44/62 ACPICA: ACPI 6.0: Add support for STAO table

Quoted 4 lines · shannon.zhao at linaro.org

From: Bob Moore <[email protected]>

ACPICA commit 532bf402a503061afd9d80a23e1d3c8fd99b052c

Quoted 8 lines

_STA override table.

Quoted 40 lines
 xen/include/acpi/actbl3.h | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
xen/include/acpi/actbl3.h +16 -0
index fc96963..cb9e1c0 100644
@@ -68,6 +68,7 @@
 #define ACPI_SIG_PCCT           "PCCT"	/* Platform Communications Channel Table */
 #define ACPI_SIG_PMTT           "PMTT"	/* Platform Memory Topology Table */
 #define ACPI_SIG_RASF           "RASF"	/* RAS Feature table */
+#define ACPI_SIG_STAO           "STAO" /* Status Override table */
 
 #define ACPI_SIG_S3PT           "S3PT"	/* S3 Performance (sub)Table */
 #define ACPI_SIG_PCCS           "PCC"	/* PCC Shared Memory Region */
@@ -618,6 +619,21 @@ enum acpi_rasf_status {
 #define ACPI_RASF_ERROR                 (1<<2)
 #define ACPI_RASF_STATUS                (0x1F<<3)
 
+/*******************************************************************************
+ *
+ * STAO - Status Override Table (_STA override) - ACPI 6.0
+ *        Version 1
+ *
+ * Conforms to "ACPI Specification for Status Override Table"
+ * 6 January 2015
+ *
+ ******************************************************************************/
+
+struct acpi_table_stao {
+	struct acpi_table_header header;	/* Common ACPI table header */
+	u8 ignore_uart;
+};
+
 /* Reset to default packing */
 
 #pragma pack()
Signature · 1 line
2.1.0
Acked-by on v3 44/62
#233 lore raw

Re: [PATCH v3 44/62] ACPICA: ACPI 6.0: Add support for STAO table

In reply to shannon.zhao at linaro.org
Quoted 4 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Bob Moore <[email protected]>

ACPICA commit 532bf402a503061afd9d80a23e1d3c8fd99b052c

Quoted 8 lines

_STA override table.

Quoted 40 lines
 xen/include/acpi/actbl3.h | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
xen/include/acpi/actbl3.h +16 -0
index fc96963..cb9e1c0 100644
@@ -68,6 +68,7 @@
 #define ACPI_SIG_PCCT           "PCCT"	/* Platform Communications Channel Table */
 #define ACPI_SIG_PMTT           "PMTT"	/* Platform Memory Topology Table */
 #define ACPI_SIG_RASF           "RASF"	/* RAS Feature table */
+#define ACPI_SIG_STAO           "STAO" /* Status Override table */
 
 #define ACPI_SIG_S3PT           "S3PT"	/* S3 Performance (sub)Table */
 #define ACPI_SIG_PCCS           "PCC"	/* PCC Shared Memory Region */
@@ -618,6 +619,21 @@ enum acpi_rasf_status {
 #define ACPI_RASF_ERROR                 (1<<2)
 #define ACPI_RASF_STATUS                (0x1F<<3)
 
+/*******************************************************************************
+ *
+ * STAO - Status Override Table (_STA override) - ACPI 6.0
+ *        Version 1
+ *
+ * Conforms to "ACPI Specification for Status Override Table"
+ * 6 January 2015
+ *
+ ******************************************************************************/
+
+struct acpi_table_stao {
+	struct acpi_table_header header;	/* Common ACPI table header */
+	u8 ignore_uart;
+};
+
 /* Reset to default packing */
 
 #pragma pack()
Signature · 1 line
2.1.0
#234 lore raw

PATCH v3 45/62 arm/acpi: Prepare STAO table for Dom0

In reply to shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Create STAO table for Dom0. This table is used to tell Dom0 whether it should ignore UART defined in SPCR table or the ACPI namespace names.

Look at below url for details:
http://wiki.xenproject.org/mediawiki/images/0/02/Status-override-table.pdf

---
 xen/arch/arm/domain_build.c | 43 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)
xen/arch/arm/domain_build.c +43 -0
index 4591955..fb3f150 100644
@@ -1359,6 +1359,45 @@ static int prepare_dtb(struct domain *d, struct kernel_info *kinfo)
 #ifdef CONFIG_ACPI
 #define XEN_HYPERVISOR_ID 0x000058656E564D4D  /* "XenVMM" */
 
+static int acpi_create_stao(struct domain *d, struct membank tbl_add[])
+{
+    struct acpi_table_header *table = NULL;
+    struct acpi_table_stao *stao = NULL;
+    u64 table_size = sizeof(struct acpi_table_stao);
+    acpi_status status;
+    u8 *base_ptr;
+    u8 checksum;
+
+    status = acpi_get_table(ACPI_SIG_MADT, 0, &table);
+
+    if ( ACPI_FAILURE(status) )
+    {
+        const char *msg = acpi_format_exception(status);
+
+        printk("Failed to get MADT table, %s\n", msg);
+        return -EINVAL;
+    }
+
+    base_ptr = d->arch.efi_acpi_table
+               + acpi_get_table_offset(tbl_add, TBL_STAO);
+    /* Copy header of one table, here use MADT */
+    ACPI_MEMCPY(base_ptr, table, sizeof(struct acpi_table_header));
+    stao = (struct acpi_table_stao *)base_ptr;
+
+    ACPI_MEMCPY(stao->header.signature, ACPI_SIG_STAO, 4);
+    stao->header.revision = 1;
+    stao->header.length = table_size;
+    stao->ignore_uart = 1;
+    checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, stao), table_size);
+    stao->header.checksum = stao->header.checksum - checksum;
+
+    tbl_add[TBL_STAO].start = d->arch.efi_acpi_gpa
+                              + acpi_get_table_offset(tbl_add, TBL_STAO);
+    tbl_add[TBL_STAO].size = table_size;
+
+    return 0;
+}
+
 static int acpi_create_madt(struct domain *d, struct membank tbl_add[])
 {
     struct acpi_table_header *table = NULL;
@@ -1561,6 +1600,10 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
     if ( rc != 0 )
         return rc;
 
+    rc = acpi_create_stao(d, tbl_add);
+    if ( rc != 0 )
+        return rc;
+
     return 0;
 }
 #else
Signature · 1 line
2.1.0
#235 lore raw

PATCH v3 45/62 arm/acpi: Prepare STAO table for Dom0

Quoted 22 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Create STAO table for Dom0. This table is used to tell Dom0 whether it should ignore UART defined in SPCR table or the ACPI namespace names.

Look at below url for details:
http://wiki.xenproject.org/mediawiki/images/0/02/Status-override-table.pdf

---
 xen/arch/arm/domain_build.c | 43 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)
xen/arch/arm/domain_build.c +0 -0
index 4591955..fb3f150 100644
@@ -1359,6 +1359,45 @@ static int prepare_dtb(struct domain *d, struct kernel_info *kinfo)
 #ifdef CONFIG_ACPI
 #define XEN_HYPERVISOR_ID 0x000058656E564D4D  /* "XenVMM" */
 

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1371

Quoted 10 lines
xen/arch/arm/domain_build.c +10 -0
+static int acpi_create_stao(struct domain *d, struct membank tbl_add[])
+{
+    struct acpi_table_header *table = NULL;
+    struct acpi_table_stao *stao = NULL;
+    u64 table_size = sizeof(struct acpi_table_stao);
+    acpi_status status;
+    u8 *base_ptr;
+    u8 checksum;
+
+    status = acpi_get_table(ACPI_SIG_MADT, 0, &table);

This needs a comment: why are we trying to get the MADT table while this function is to create the STAO table?

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1383

Quoted 11 lines
xen/arch/arm/domain_build.c +11 -0
+    if ( ACPI_FAILURE(status) )
+    {
+        const char *msg = acpi_format_exception(status);
+
+        printk("Failed to get MADT table, %s\n", msg);
+        return -EINVAL;
+    }
+
+    base_ptr = d->arch.efi_acpi_table
+               + acpi_get_table_offset(tbl_add, TBL_STAO);
+    /* Copy header of one table, here use MADT */

Please move the comment above. This is just to copy the OEM fields, I guess?

Quoted 40 lines
xen/arch/arm/domain_build.c +21 -0
+    ACPI_MEMCPY(base_ptr, table, sizeof(struct acpi_table_header));
+    stao = (struct acpi_table_stao *)base_ptr;
+
+    ACPI_MEMCPY(stao->header.signature, ACPI_SIG_STAO, 4);
+    stao->header.revision = 1;
+    stao->header.length = table_size;
+    stao->ignore_uart = 1;
+    checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, stao), table_size);
+    stao->header.checksum = stao->header.checksum - checksum;
+
+    tbl_add[TBL_STAO].start = d->arch.efi_acpi_gpa
+                              + acpi_get_table_offset(tbl_add, TBL_STAO);
+    tbl_add[TBL_STAO].size = table_size;
+
+    return 0;
+}
+
 static int acpi_create_madt(struct domain *d, struct membank tbl_add[])
 {
     struct acpi_table_header *table = NULL;
@@ -1561,6 +1600,10 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
     if ( rc != 0 )
         return rc;
 
+    rc = acpi_create_stao(d, tbl_add);
+    if ( rc != 0 )
+        return rc;
+
     return 0;
 }
 #else
Signature · 7 lines
2.1.0


_______________________________________________
Xen-devel mailing list
Xen-devel at lists.xen.org
http://lists.xen.org/xen-devel
#236 lore raw

Re: [PATCH v3 45/62] arm/acpi: Prepare STAO table for Dom0

In reply to shannon.zhao at linaro.org
Quoted 22 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Shannon Zhao <[email protected]>

Create STAO table for Dom0. This table is used to tell Dom0 whether it should ignore UART defined in SPCR table or the ACPI namespace names.

Look at below url for details:
http://wiki.xenproject.org/mediawiki/images/0/02/Status-override-table.pdf

---
 xen/arch/arm/domain_build.c | 43 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)
xen/arch/arm/domain_build.c +0 -0
index 4591955..fb3f150 100644
@@ -1359,6 +1359,45 @@ static int prepare_dtb(struct domain *d, struct kernel_info *kinfo)
 #ifdef CONFIG_ACPI
 #define XEN_HYPERVISOR_ID 0x000058656E564D4D  /* "XenVMM" */
 

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1371

Quoted 10 lines
xen/arch/arm/domain_build.c +10 -0
+static int acpi_create_stao(struct domain *d, struct membank tbl_add[])
+{
+    struct acpi_table_header *table = NULL;
+    struct acpi_table_stao *stao = NULL;
+    u64 table_size = sizeof(struct acpi_table_stao);
+    acpi_status status;
+    u8 *base_ptr;
+    u8 checksum;
+
+    status = acpi_get_table(ACPI_SIG_MADT, 0, &table);

This needs a comment: why are we trying to get the MADT table while this function is to create the STAO table?

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1383

Quoted 11 lines
xen/arch/arm/domain_build.c +11 -0
+    if ( ACPI_FAILURE(status) )
+    {
+        const char *msg = acpi_format_exception(status);
+
+        printk("Failed to get MADT table, %s\n", msg);
+        return -EINVAL;
+    }
+
+    base_ptr = d->arch.efi_acpi_table
+               + acpi_get_table_offset(tbl_add, TBL_STAO);
+    /* Copy header of one table, here use MADT */

Please move the comment above. This is just to copy the OEM fields, I guess?

Quoted 40 lines
xen/arch/arm/domain_build.c +21 -0
+    ACPI_MEMCPY(base_ptr, table, sizeof(struct acpi_table_header));
+    stao = (struct acpi_table_stao *)base_ptr;
+
+    ACPI_MEMCPY(stao->header.signature, ACPI_SIG_STAO, 4);
+    stao->header.revision = 1;
+    stao->header.length = table_size;
+    stao->ignore_uart = 1;
+    checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, stao), table_size);
+    stao->header.checksum = stao->header.checksum - checksum;
+
+    tbl_add[TBL_STAO].start = d->arch.efi_acpi_gpa
+                              + acpi_get_table_offset(tbl_add, TBL_STAO);
+    tbl_add[TBL_STAO].size = table_size;
+
+    return 0;
+}
+
 static int acpi_create_madt(struct domain *d, struct membank tbl_add[])
 {
     struct acpi_table_header *table = NULL;
@@ -1561,6 +1600,10 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
     if ( rc != 0 )
         return rc;
 
+    rc = acpi_create_stao(d, tbl_add);
+    if ( rc != 0 )
+        return rc;
+
     return 0;
 }
 #else
Signature · 7 lines
2.1.0


_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
#237 lore raw

PATCH v3 46/62 arm/acpi: Prepare XSDT table for Dom0

In reply to shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Copy and modify XSDT table before passing it to Dom0. Repalce the entry value of the copied table. Add a new entry for STAO table as well. And keep entry value of other reused tables unchanged.

---
 xen/arch/arm/domain_build.c | 71 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 71 insertions(+)
xen/arch/arm/domain_build.c +71 -0
index fb3f150..894328f 100644
@@ -1359,6 +1359,73 @@ static int prepare_dtb(struct domain *d, struct kernel_info *kinfo)
 #ifdef CONFIG_ACPI
 #define XEN_HYPERVISOR_ID 0x000058656E564D4D  /* "XenVMM" */
 
+static void acpi_xsdt_modify_entry(u64 entry[], unsigned long entry_count,
+                                   char *signature, u64 addr)
+{
+    int i;
+    struct acpi_table_header *table;
+    u64 size = sizeof(struct acpi_table_header);
+
+    for( i = 0; i < entry_count; i++ )
+    {
+        table = acpi_os_map_memory(entry[i], size);
+	if ( ACPI_COMPARE_NAME(table->signature, signature) )
+        {
+            entry[i] = addr;
+            acpi_os_unmap_memory(table, size);
+            break;
+        }
+        acpi_os_unmap_memory(table, size);
+    }
+}
+
+static int acpi_create_xsdt(struct domain *d, struct membank tbl_add[])
+{
+    struct acpi_table_header *table = NULL;
+    struct acpi_table_rsdp *rsdp_tbl;
+    struct acpi_table_xsdt *xsdt = NULL;
+    u64 table_size, addr;
+    unsigned long entry_count;
+    u8 *base_ptr;
+    u8 checksum;
+
+    addr = acpi_os_get_root_pointer();
+    if ( !addr )
+    {
+        printk("Unable to get acpi root pointer\n");
+        return -EINVAL;
+    }
+    rsdp_tbl = acpi_os_map_memory(addr, sizeof(struct acpi_table_rsdp));
+    table = acpi_os_map_memory(rsdp_tbl->xsdt_physical_address,
+                               sizeof(struct acpi_table_header));
+
+    table_size = table->length + sizeof(u64); /* Add place for STAO table */
+    entry_count = (table->length - sizeof(struct acpi_table_header))
+                  / sizeof(u64);
+    base_ptr = d->arch.efi_acpi_table
+               + acpi_get_table_offset(tbl_add, TBL_XSDT);
+    ACPI_MEMCPY(base_ptr, table, table->length);
+    acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
+    acpi_os_unmap_memory(rsdp_tbl, sizeof(struct acpi_table_rsdp));
+
+    xsdt = (struct acpi_table_xsdt *)base_ptr;
+    acpi_xsdt_modify_entry(xsdt->table_offset_entry, entry_count,
+                           ACPI_SIG_FADT, tbl_add[TBL_FADT].start);
+    acpi_xsdt_modify_entry(xsdt->table_offset_entry, entry_count,
+                           ACPI_SIG_MADT, tbl_add[TBL_MADT].start);
+    xsdt->table_offset_entry[entry_count] = tbl_add[TBL_STAO].start;
+
+    xsdt->header.length = table_size;
+    checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, xsdt), table_size);
+    xsdt->header.checksum -= checksum;
+
+    tbl_add[TBL_XSDT].start = d->arch.efi_acpi_gpa
+                              + acpi_get_table_offset(tbl_add, TBL_XSDT);
+    tbl_add[TBL_XSDT].size = table_size;
+
+    return 0;
+}
+
 static int acpi_create_stao(struct domain *d, struct membank tbl_add[])
 {
     struct acpi_table_header *table = NULL;
@@ -1604,6 +1671,10 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
     if ( rc != 0 )
         return rc;
 
+    rc = acpi_create_xsdt(d, tbl_add);
+    if ( rc != 0 )
+        return rc;
+
     return 0;
 }
 #else
Signature · 1 line
2.1.0
#238 lore raw

PATCH v3 46/62 arm/acpi: Prepare XSDT table for Dom0

Quoted 20 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Copy and modify XSDT table before passing it to Dom0. Repalce the entry value of the copied table. Add a new entry for STAO table as well. And keep entry value of other reused tables unchanged.

---
 xen/arch/arm/domain_build.c | 71 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 71 insertions(+)
xen/arch/arm/domain_build.c +1 -0
index fb3f150..894328f 100644
@@ -1359,6 +1359,73 @@ static int prepare_dtb(struct domain *d, struct kernel_info *kinfo)
 #ifdef CONFIG_ACPI
 #define XEN_HYPERVISOR_ID 0x000058656E564D4D  /* "XenVMM" */
 
+static void acpi_xsdt_modify_entry(u64 entry[], unsigned long entry_count,

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1372

Quoted 10 lines
xen/arch/arm/domain_build.c +10 -0
+                                   char *signature, u64 addr)
+{
+    int i;
+    struct acpi_table_header *table;
+    u64 size = sizeof(struct acpi_table_header);
+
+    for( i = 0; i < entry_count; i++ )
+    {
+        table = acpi_os_map_memory(entry[i], size);
+	if ( ACPI_COMPARE_NAME(table->signature, signature) )

coding style

Quoted 20 lines
xen/arch/arm/domain_build.c +20 -0
+        {
+            entry[i] = addr;
+            acpi_os_unmap_memory(table, size);
+            break;
+        }
+        acpi_os_unmap_memory(table, size);
+    }
+}
+
+static int acpi_create_xsdt(struct domain *d, struct membank tbl_add[])
+{
+    struct acpi_table_header *table = NULL;
+    struct acpi_table_rsdp *rsdp_tbl;
+    struct acpi_table_xsdt *xsdt = NULL;
+    u64 table_size, addr;
+    unsigned long entry_count;
+    u8 *base_ptr;
+    u8 checksum;
+
+    addr = acpi_os_get_root_pointer();

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1402

Quoted 10 lines
xen/arch/arm/domain_build.c +10 -0
+    if ( !addr )
+    {
+        printk("Unable to get acpi root pointer\n");
+        return -EINVAL;
+    }
+    rsdp_tbl = acpi_os_map_memory(addr, sizeof(struct acpi_table_rsdp));
+    table = acpi_os_map_memory(rsdp_tbl->xsdt_physical_address,
+                               sizeof(struct acpi_table_header));
+
+    table_size = table->length + sizeof(u64); /* Add place for STAO table */

Please move the comment above the line.
It looks like you took into account this additional u64 in estimate_acpi_efi_size. Please add a comment there too.

For this patch, provided you fix the minor style issues:

Quoted 40 lines
xen/arch/arm/domain_build.c +30 -0
+    entry_count = (table->length - sizeof(struct acpi_table_header))
+                  / sizeof(u64);
+    base_ptr = d->arch.efi_acpi_table
+               + acpi_get_table_offset(tbl_add, TBL_XSDT);
+    ACPI_MEMCPY(base_ptr, table, table->length);
+    acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
+    acpi_os_unmap_memory(rsdp_tbl, sizeof(struct acpi_table_rsdp));
+
+    xsdt = (struct acpi_table_xsdt *)base_ptr;
+    acpi_xsdt_modify_entry(xsdt->table_offset_entry, entry_count,
+                           ACPI_SIG_FADT, tbl_add[TBL_FADT].start);
+    acpi_xsdt_modify_entry(xsdt->table_offset_entry, entry_count,
+                           ACPI_SIG_MADT, tbl_add[TBL_MADT].start);
+    xsdt->table_offset_entry[entry_count] = tbl_add[TBL_STAO].start;
+
+    xsdt->header.length = table_size;
+    checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, xsdt), table_size);
+    xsdt->header.checksum -= checksum;
+
+    tbl_add[TBL_XSDT].start = d->arch.efi_acpi_gpa
+                              + acpi_get_table_offset(tbl_add, TBL_XSDT);
+    tbl_add[TBL_XSDT].size = table_size;
+
+    return 0;
+}
+
 static int acpi_create_stao(struct domain *d, struct membank tbl_add[])
 {
     struct acpi_table_header *table = NULL;
@@ -1604,6 +1671,10 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
     if ( rc != 0 )
         return rc;
 
+    rc = acpi_create_xsdt(d, tbl_add);
+    if ( rc != 0 )
+        return rc;
+
     return 0;
 }
 #else
#239 lore raw

PATCH v3 47/62 arm/p2m: Add helper functions to map memory regions

In reply to shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

Create a helper function for mapping with cached attributes.

---
 xen/arch/arm/p2m.c        | 26 ++++++++++++++++++++++++++
 xen/include/asm-arm/p2m.h | 10 ++++++++++
 2 files changed, 36 insertions(+)
xen/arch/arm/p2m.c +26 -0
index e396c40..7a108d8 100644
@@ -1140,6 +1140,32 @@ int p2m_populate_ram(struct domain *d,
                              d->arch.p2m.default_access);
 }
 
+int map_regions(struct domain *d,
+                     unsigned long start_gfn,
+                     unsigned long nr,
+                     unsigned long mfn)
+{
+    return apply_p2m_changes(d, INSERT,
+                             pfn_to_paddr(start_gfn),
+                             pfn_to_paddr(start_gfn + nr),
+                             pfn_to_paddr(mfn),
+                             MATTR_MEM, 0, p2m_mmio_direct,
+                             d->arch.p2m.default_access);
+}
+
+int unmap_regions(struct domain *d,
+                       unsigned long start_gfn,
+                       unsigned long nr,
+                       unsigned long mfn)
+{
+    return apply_p2m_changes(d, REMOVE,
+                             pfn_to_paddr(start_gfn),
+                             pfn_to_paddr(start_gfn + nr),
+                             pfn_to_paddr(mfn),
+                             MATTR_MEM, 0, p2m_invalid,
+                             d->arch.p2m.default_access);
+}
+
 int map_mmio_regions(struct domain *d,
                      unsigned long start_gfn,
                      unsigned long nr,
xen/include/asm-arm/p2m.h +10 -0
index 08bdce3..b6215f9 100644
@@ -158,6 +158,16 @@ int p2m_cache_flush(struct domain *d, xen_pfn_t start_mfn, xen_pfn_t end_mfn);
 /* Setup p2m RAM mapping for domain d from start-end. */
 int p2m_populate_ram(struct domain *d, paddr_t start, paddr_t end);
 
+int map_regions(struct domain *d,
+                    unsigned long start_gfn,
+                    unsigned long nr_mfns,
+                    unsigned long mfn);
+
+int unmap_regions(struct domain *d,
+                    unsigned long start_gfn,
+                    unsigned long nr_mfns,
+                    unsigned long mfn);
+
 int guest_physmap_add_entry(struct domain *d,
                             unsigned long gfn,
                             unsigned long mfn,
Signature · 1 line
2.1.0
#240 lore raw

PATCH v3 47/62 arm/p2m: Add helper functions to map memory regions

Quoted 6 lines · shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

Create a helper function for mapping with cached attributes.

You might be able to use the existing guest_physmap_add_entry and guest_physmap_remove_page for your purposes.

Quoted 65 lines
 xen/arch/arm/p2m.c        | 26 ++++++++++++++++++++++++++
 xen/include/asm-arm/p2m.h | 10 ++++++++++
 2 files changed, 36 insertions(+)
xen/arch/arm/p2m.c +26 -0
index e396c40..7a108d8 100644
@@ -1140,6 +1140,32 @@ int p2m_populate_ram(struct domain *d,
                              d->arch.p2m.default_access);
 }
 
+int map_regions(struct domain *d,
+                     unsigned long start_gfn,
+                     unsigned long nr,
+                     unsigned long mfn)
+{
+    return apply_p2m_changes(d, INSERT,
+                             pfn_to_paddr(start_gfn),
+                             pfn_to_paddr(start_gfn + nr),
+                             pfn_to_paddr(mfn),
+                             MATTR_MEM, 0, p2m_mmio_direct,
+                             d->arch.p2m.default_access);
+}
+
+int unmap_regions(struct domain *d,
+                       unsigned long start_gfn,
+                       unsigned long nr,
+                       unsigned long mfn)
+{
+    return apply_p2m_changes(d, REMOVE,
+                             pfn_to_paddr(start_gfn),
+                             pfn_to_paddr(start_gfn + nr),
+                             pfn_to_paddr(mfn),
+                             MATTR_MEM, 0, p2m_invalid,
+                             d->arch.p2m.default_access);
+}
+
 int map_mmio_regions(struct domain *d,
                      unsigned long start_gfn,
                      unsigned long nr,
xen/include/asm-arm/p2m.h +10 -0
index 08bdce3..b6215f9 100644
@@ -158,6 +158,16 @@ int p2m_cache_flush(struct domain *d, xen_pfn_t start_mfn, xen_pfn_t end_mfn);
 /* Setup p2m RAM mapping for domain d from start-end. */
 int p2m_populate_ram(struct domain *d, paddr_t start, paddr_t end);
 
+int map_regions(struct domain *d,
+                    unsigned long start_gfn,
+                    unsigned long nr_mfns,
+                    unsigned long mfn);
+
+int unmap_regions(struct domain *d,
+                    unsigned long start_gfn,
+                    unsigned long nr_mfns,
+                    unsigned long mfn);
+
 int guest_physmap_add_entry(struct domain *d,
                             unsigned long gfn,
                             unsigned long mfn,
Signature · 1 line
2.1.0
#241 lore raw

PATCH v3 47/62 arm/p2m: Add helper functions to map memory regions

Hi,

Quoted 10 lines · Stefano Stabellini
Quoted 6 lines · shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

Create a helper function for mapping with cached attributes.

You might be able to use the existing guest_physmap_add_entry and guest_physmap_remove_page for your purposes.

I would rather avoid to do that, those function use the type p2m_ram_rw which imply the memory is executable.

Regards,

Signature · 1 line
Julien Grall
#242 lore raw

PATCH v3 47/62 arm/p2m: Add helper functions to map memory regions

Quoted 8 lines · Julien Grall

Hi,

Quoted 5 lines · Stefano Stabellini
Quoted 5 lines · shannon.zhao at linaro.org
Quoted 4 lines
Quoted 4 lines

From: Parth Dixit <[email protected]>

Create a helper function for mapping with cached attributes.

Quoted 7 lines
Quoted 5 lines
Quoted 5 lines
Quoted 2 lines
Quoted 2 lines

You might be able to use the existing guest_physmap_add_entry and guest_physmap_remove_page for your purposes.

I would rather avoid to do that, those function use the type p2m_ram_rw which imply the memory is executable.

It could pass the type p2m_mmio_direct or p2m_ram_ro to guest_physmap_add_entry, right?

Thanks,

Signature · 1 line
Shannon
#243 lore raw

Re: [PATCH v3 47/62] arm/p2m: Add helper functions to map memory regions

In reply to Julien Grall
Quoted 8 lines · Julien Grall

Hi,

Quoted 5 lines · Stefano Stabellini
Quoted 5 lines · On Tue, 17 Nov 2015, [email protected] wrote:
Quoted 4 lines
Quoted 4 lines

From: Parth Dixit <[email protected]>

Create a helper function for mapping with cached attributes.

Quoted 7 lines
Quoted 5 lines
Quoted 5 lines
Quoted 2 lines
Quoted 2 lines

You might be able to use the existing guest_physmap_add_entry and guest_physmap_remove_page for your purposes.

I would rather avoid to do that, those function use the type p2m_ram_rw which imply the memory is executable.

It could pass the type p2m_mmio_direct or p2m_ram_ro to guest_physmap_add_entry, right?

Thanks,

Signature · 1 line
Shannon
#244 lore raw

Re: [PATCH v3 47/62] arm/p2m: Add helper functions to map memory regions

In reply to Stefano Stabellini

Hi,

Quoted 10 lines · Stefano Stabellini
Quoted 6 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Parth Dixit <[email protected]>

Create a helper function for mapping with cached attributes.

You might be able to use the existing guest_physmap_add_entry and guest_physmap_remove_page for your purposes.

I would rather avoid to do that, those function use the type p2m_ram_rw which imply the memory is executable.

Regards,

Signature · 1 line
Julien Grall
#245 lore raw

Re: [PATCH v3 47/62] arm/p2m: Add helper functions to map memory regions

In reply to shannon.zhao at linaro.org
Quoted 6 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Parth Dixit <[email protected]>

Create a helper function for mapping with cached attributes.

You might be able to use the existing guest_physmap_add_entry and guest_physmap_remove_page for your purposes.

Quoted 65 lines
 xen/arch/arm/p2m.c        | 26 ++++++++++++++++++++++++++
 xen/include/asm-arm/p2m.h | 10 ++++++++++
 2 files changed, 36 insertions(+)
xen/arch/arm/p2m.c +26 -0
index e396c40..7a108d8 100644
@@ -1140,6 +1140,32 @@ int p2m_populate_ram(struct domain *d,
                              d->arch.p2m.default_access);
 }
 
+int map_regions(struct domain *d,
+                     unsigned long start_gfn,
+                     unsigned long nr,
+                     unsigned long mfn)
+{
+    return apply_p2m_changes(d, INSERT,
+                             pfn_to_paddr(start_gfn),
+                             pfn_to_paddr(start_gfn + nr),
+                             pfn_to_paddr(mfn),
+                             MATTR_MEM, 0, p2m_mmio_direct,
+                             d->arch.p2m.default_access);
+}
+
+int unmap_regions(struct domain *d,
+                       unsigned long start_gfn,
+                       unsigned long nr,
+                       unsigned long mfn)
+{
+    return apply_p2m_changes(d, REMOVE,
+                             pfn_to_paddr(start_gfn),
+                             pfn_to_paddr(start_gfn + nr),
+                             pfn_to_paddr(mfn),
+                             MATTR_MEM, 0, p2m_invalid,
+                             d->arch.p2m.default_access);
+}
+
 int map_mmio_regions(struct domain *d,
                      unsigned long start_gfn,
                      unsigned long nr,
xen/include/asm-arm/p2m.h +10 -0
index 08bdce3..b6215f9 100644
@@ -158,6 +158,16 @@ int p2m_cache_flush(struct domain *d, xen_pfn_t start_mfn, xen_pfn_t end_mfn);
 /* Setup p2m RAM mapping for domain d from start-end. */
 int p2m_populate_ram(struct domain *d, paddr_t start, paddr_t end);
 
+int map_regions(struct domain *d,
+                    unsigned long start_gfn,
+                    unsigned long nr_mfns,
+                    unsigned long mfn);
+
+int unmap_regions(struct domain *d,
+                    unsigned long start_gfn,
+                    unsigned long nr_mfns,
+                    unsigned long mfn);
+
 int guest_physmap_add_entry(struct domain *d,
                             unsigned long gfn,
                             unsigned long mfn,
Signature · 1 line
2.1.0
#246 lore raw

PATCH v3 47/62 arm/p2m: Add helper functions to map memory regions

In reply to shannon.zhao at linaro.org

Hi Shannon,

Quoted 3 lines · shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

Create a helper function for mapping with cached attributes.

You are using those helpers to map the ACPI table in the guest. Do we really need them to be mapped read-write?

Regards,

Signature · 1 line
Julien Grall
#248 lore raw

PATCH v3 48/62 arm/acpi: Prepare RSDP table for Dom0

In reply to shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Copy RSDP table and replace rsdp->xsdt_physical_address with new address of XSDT table, so it can point to the right XSDT table.

---
 xen/arch/arm/domain_build.c | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)
xen/arch/arm/domain_build.c +36 -0
index 894328f..6ae5761 100644
@@ -1359,6 +1359,38 @@ static int prepare_dtb(struct domain *d, struct kernel_info *kinfo)
 #ifdef CONFIG_ACPI
 #define XEN_HYPERVISOR_ID 0x000058656E564D4D  /* "XenVMM" */
 
+static int acpi_create_rsdp(struct domain *d, struct membank tbl_add[])
+{
+
+    struct acpi_table_rsdp *rsdp = NULL;
+    u64 addr;
+    u64 table_size = sizeof(struct acpi_table_rsdp);
+    u8 *base_ptr;
+    u8 checksum;
+
+    addr = acpi_os_get_root_pointer();
+    if( !addr )
+        panic("Unable to get acpi root pointer\n");
+
+    rsdp = acpi_os_map_memory(addr, table_size);
+    base_ptr = d->arch.efi_acpi_table
+               + acpi_get_table_offset(tbl_add, TBL_RSDP);
+    ACPI_MEMCPY(base_ptr, rsdp, table_size);
+    acpi_os_unmap_memory(rsdp, table_size);
+
+    rsdp = (struct acpi_table_rsdp *)base_ptr;
+    /* Replace xsdt_physical_address */
+    rsdp->xsdt_physical_address = tbl_add[TBL_XSDT].start;
+    checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, rsdp), table_size);
+    rsdp->checksum = rsdp->checksum - checksum;
+
+    tbl_add[TBL_RSDP].start = d->arch.efi_acpi_gpa
+                              + acpi_get_table_offset(tbl_add, TBL_RSDP);
+    tbl_add[TBL_RSDP].size = table_size;
+
+    return 0;
+}
+
 static void acpi_xsdt_modify_entry(u64 entry[], unsigned long entry_count,
                                    char *signature, u64 addr)
 {
@@ -1675,6 +1707,10 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
     if ( rc != 0 )
         return rc;
 
+    rc = acpi_create_rsdp(d, tbl_add);
+    if ( rc != 0 )
+        return rc;
+
     return 0;
 }
 #else
Signature · 1 line
2.1.0
#249 lore raw

PATCH v3 48/62 arm/acpi: Prepare RSDP table for Dom0

Quoted 6 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Copy RSDP table and replace rsdp->xsdt_physical_address with new address of XSDT table, so it can point to the right XSDT table.

Quoted 25 lines
 xen/arch/arm/domain_build.c | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)
xen/arch/arm/domain_build.c +14 -0
index 894328f..6ae5761 100644
@@ -1359,6 +1359,38 @@ static int prepare_dtb(struct domain *d, struct kernel_info *kinfo)
 #ifdef CONFIG_ACPI
 #define XEN_HYPERVISOR_ID 0x000058656E564D4D  /* "XenVMM" */
 
+static int acpi_create_rsdp(struct domain *d, struct membank tbl_add[])
+{
+
+    struct acpi_table_rsdp *rsdp = NULL;
+    u64 addr;
+    u64 table_size = sizeof(struct acpi_table_rsdp);
+    u8 *base_ptr;
+    u8 checksum;
+
+    addr = acpi_os_get_root_pointer();
+    if( !addr )
+        panic("Unable to get acpi root pointer\n");
+
+    rsdp = acpi_os_map_memory(addr, table_size);

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1385

Quoted 10 lines
xen/arch/arm/domain_build.c +10 -0
+    base_ptr = d->arch.efi_acpi_table
+               + acpi_get_table_offset(tbl_add, TBL_RSDP);
+    ACPI_MEMCPY(base_ptr, rsdp, table_size);
+    acpi_os_unmap_memory(rsdp, table_size);
+
+    rsdp = (struct acpi_table_rsdp *)base_ptr;
+    /* Replace xsdt_physical_address */
+    rsdp->xsdt_physical_address = tbl_add[TBL_XSDT].start;
+    checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, rsdp), table_size);
+    rsdp->checksum = rsdp->checksum - checksum;

You always did -= checksum in the other functions, let's keep a consistent style.

Quoted 25 lines
xen/arch/arm/domain_build.c +12 -0
+
+    tbl_add[TBL_RSDP].start = d->arch.efi_acpi_gpa
+                              + acpi_get_table_offset(tbl_add, TBL_RSDP);
+    tbl_add[TBL_RSDP].size = table_size;
+
+    return 0;
+}
+
 static void acpi_xsdt_modify_entry(u64 entry[], unsigned long entry_count,
                                    char *signature, u64 addr)
 {
@@ -1675,6 +1707,10 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
     if ( rc != 0 )
         return rc;
 
+    rc = acpi_create_rsdp(d, tbl_add);
+    if ( rc != 0 )
+        return rc;
+
     return 0;
 }
 #else
Signature · 1 line
2.1.0
Acked-by on v3 48/62
#250 lore raw

Re: [PATCH v3 48/62] arm/acpi: Prepare RSDP table for Dom0

In reply to shannon.zhao at linaro.org
Quoted 6 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Shannon Zhao <[email protected]>

Copy RSDP table and replace rsdp->xsdt_physical_address with new address of XSDT table, so it can point to the right XSDT table.

Quoted 25 lines
 xen/arch/arm/domain_build.c | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)
xen/arch/arm/domain_build.c +14 -0
index 894328f..6ae5761 100644
@@ -1359,6 +1359,38 @@ static int prepare_dtb(struct domain *d, struct kernel_info *kinfo)
 #ifdef CONFIG_ACPI
 #define XEN_HYPERVISOR_ID 0x000058656E564D4D  /* "XenVMM" */
 
+static int acpi_create_rsdp(struct domain *d, struct membank tbl_add[])
+{
+
+    struct acpi_table_rsdp *rsdp = NULL;
+    u64 addr;
+    u64 table_size = sizeof(struct acpi_table_rsdp);
+    u8 *base_ptr;
+    u8 checksum;
+
+    addr = acpi_os_get_root_pointer();
+    if( !addr )
+        panic("Unable to get acpi root pointer\n");
+
+    rsdp = acpi_os_map_memory(addr, table_size);

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1385

Quoted 10 lines
xen/arch/arm/domain_build.c +10 -0
+    base_ptr = d->arch.efi_acpi_table
+               + acpi_get_table_offset(tbl_add, TBL_RSDP);
+    ACPI_MEMCPY(base_ptr, rsdp, table_size);
+    acpi_os_unmap_memory(rsdp, table_size);
+
+    rsdp = (struct acpi_table_rsdp *)base_ptr;
+    /* Replace xsdt_physical_address */
+    rsdp->xsdt_physical_address = tbl_add[TBL_XSDT].start;
+    checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, rsdp), table_size);
+    rsdp->checksum = rsdp->checksum - checksum;

You always did -= checksum in the other functions, let's keep a consistent style.

Quoted 25 lines
xen/arch/arm/domain_build.c +12 -0
+
+    tbl_add[TBL_RSDP].start = d->arch.efi_acpi_gpa
+                              + acpi_get_table_offset(tbl_add, TBL_RSDP);
+    tbl_add[TBL_RSDP].size = table_size;
+
+    return 0;
+}
+
 static void acpi_xsdt_modify_entry(u64 entry[], unsigned long entry_count,
                                    char *signature, u64 addr)
 {
@@ -1675,6 +1707,10 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
     if ( rc != 0 )
         return rc;
 
+    rc = acpi_create_rsdp(d, tbl_add);
+    if ( rc != 0 )
+        return rc;
+
     return 0;
 }
 #else
Signature · 1 line
2.1.0
#251 lore raw

PATCH v3 49/62 arm/acpi: Map rest tables for Dom0

In reply to shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Map other reused tables for Dom0.

---
 xen/arch/arm/domain_build.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)
xen/arch/arm/domain_build.c +25 -0
index 6ae5761..da4e271 100644
@@ -1359,6 +1359,29 @@ static int prepare_dtb(struct domain *d, struct kernel_info *kinfo)
 #ifdef CONFIG_ACPI
 #define XEN_HYPERVISOR_ID 0x000058656E564D4D  /* "XenVMM" */
 
+static void acpi_map_rest_tables(struct domain *d)
+{
+    int i;
+    unsigned long res;
+    u64 addr, size;
+
+    for( i = 0; i < acpi_gbl_root_table_list.count; i++ )
+    {
+        addr = acpi_gbl_root_table_list.tables[i].address;
+        size = acpi_gbl_root_table_list.tables[i].length;
+        res = map_regions(d,
+                          paddr_to_pfn(addr & PAGE_MASK),
+                          DIV_ROUND_UP(size, PAGE_SIZE),
+                          paddr_to_pfn(addr & PAGE_MASK));
+        if ( res )
+        {
+             panic(XENLOG_ERR "Unable to map 0x%"PRIx64
+                   " - 0x%"PRIx64" in domain \n",
+                   addr & PAGE_MASK, PAGE_ALIGN(addr + size) - 1);
+        }
+    }
+}
+
 static int acpi_create_rsdp(struct domain *d, struct membank tbl_add[])
 {
 
@@ -1711,6 +1734,8 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
     if ( rc != 0 )
         return rc;
 
+    acpi_map_rest_tables(d);
+
     return 0;
 }
 #else
Signature · 1 line
2.1.0
#252 lore raw

PATCH v3 49/62 arm/acpi: Map rest tables for Dom0

Quoted 3 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Map other reused tables for Dom0.

"Map all other tables to Dom0 using 1:1 mappings."

Quoted 10 lines
---
 xen/arch/arm/domain_build.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)
xen/arch/arm/domain_build.c +0 -0
index 6ae5761..da4e271 100644

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1362

Quoted 4 lines
xen/arch/arm/domain_build.c +1 -0
@@ -1359,6 +1359,29 @@ static int prepare_dtb(struct domain *d, struct kernel_info *kinfo)
 #ifdef CONFIG_ACPI
 #define XEN_HYPERVISOR_ID 0x000058656E564D4D  /* "XenVMM" */
 
+static void acpi_map_rest_tables(struct domain *d)

The name doesn't sound nice, "acpi_map_other_tables" would be better. However this function is not actually mapping the other tables, it is mapping *all* of them, including the original madt and fadt, right? I think it would be best to avoid mapping the originals.

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1366

Quoted 4 lines
xen/arch/arm/domain_build.c +4 -0
+{
+    int i;
+    unsigned long res;
+    u64 addr, size;

Add a comment that they are being mapped 1:1

Quoted 29 lines
xen/arch/arm/domain_build.c +19 -0
+    for( i = 0; i < acpi_gbl_root_table_list.count; i++ )
+    {
+        addr = acpi_gbl_root_table_list.tables[i].address;
+        size = acpi_gbl_root_table_list.tables[i].length;
+        res = map_regions(d,
+                          paddr_to_pfn(addr & PAGE_MASK),
+                          DIV_ROUND_UP(size, PAGE_SIZE),
+                          paddr_to_pfn(addr & PAGE_MASK));
+        if ( res )
+        {
+             panic(XENLOG_ERR "Unable to map 0x%"PRIx64
+                   " - 0x%"PRIx64" in domain \n",
+                   addr & PAGE_MASK, PAGE_ALIGN(addr + size) - 1);
+        }
+    }
+}
+
 static int acpi_create_rsdp(struct domain *d, struct membank tbl_add[])
 {
 
@@ -1711,6 +1734,8 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
     if ( rc != 0 )
         return rc;
 
+    acpi_map_rest_tables(d);
+
     return 0;
 }
 #else
#253 lore raw

PATCH v3 49/62 arm/acpi: Map rest tables for Dom0

Hi,

Quoted 29 lines · Stefano Stabellini
Quoted 3 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Map other reused tables for Dom0.

"Map all other tables to Dom0 using 1:1 mappings."

Quoted 10 lines
---
 xen/arch/arm/domain_build.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)
xen/arch/arm/domain_build.c +0 -0
index 6ae5761..da4e271 100644

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1362

Quoted 4 lines
xen/arch/arm/domain_build.c +1 -0
@@ -1359,6 +1359,29 @@ static int prepare_dtb(struct domain *d, struct kernel_info *kinfo)
 #ifdef CONFIG_ACPI
 #define XEN_HYPERVISOR_ID 0x000058656E564D4D  /* "XenVMM" */
 
+static void acpi_map_rest_tables(struct domain *d)

The name doesn't sound nice, "acpi_map_other_tables" would be better. However this function is not actually mapping the other tables, it is mapping *all* of them, including the original madt and fadt, right? I think it would be best to avoid mapping the originals.

Quoted 6 lines

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1366

Quoted 4 lines
xen/arch/arm/domain_build.c +4 -0
+{
+    int i;
+    unsigned long res;
+    u64 addr, size;

Add a comment that they are being mapped 1:1

I don't like the fact that we begin to assume domain is mapped 1:1 in so many places.

If we decide one day to drop the 1:1 mapping it would be more difficult.

Can we try to rationalize the place where the 1:1 mapping is added?

Some ASSERT(is_domain_direct_mapped(..)) would be useful too.

Regards,

Signature · 1 line
Julien Grall
#254 lore raw

Re: [PATCH v3 49/62] arm/acpi: Map rest tables for Dom0

In reply to shannon.zhao at linaro.org
Quoted 3 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Shannon Zhao <[email protected]>

Map other reused tables for Dom0.

"Map all other tables to Dom0 using 1:1 mappings."

Quoted 10 lines
---
 xen/arch/arm/domain_build.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)
xen/arch/arm/domain_build.c +0 -0
index 6ae5761..da4e271 100644

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1362

Quoted 4 lines
xen/arch/arm/domain_build.c +1 -0
@@ -1359,6 +1359,29 @@ static int prepare_dtb(struct domain *d, struct kernel_info *kinfo)
 #ifdef CONFIG_ACPI
 #define XEN_HYPERVISOR_ID 0x000058656E564D4D  /* "XenVMM" */
 
+static void acpi_map_rest_tables(struct domain *d)

The name doesn't sound nice, "acpi_map_other_tables" would be better. However this function is not actually mapping the other tables, it is mapping *all* of them, including the original madt and fadt, right? I think it would be best to avoid mapping the originals.

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1366

Quoted 4 lines
xen/arch/arm/domain_build.c +4 -0
+{
+    int i;
+    unsigned long res;
+    u64 addr, size;

Add a comment that they are being mapped 1:1

Quoted 29 lines
xen/arch/arm/domain_build.c +19 -0
+    for( i = 0; i < acpi_gbl_root_table_list.count; i++ )
+    {
+        addr = acpi_gbl_root_table_list.tables[i].address;
+        size = acpi_gbl_root_table_list.tables[i].length;
+        res = map_regions(d,
+                          paddr_to_pfn(addr & PAGE_MASK),
+                          DIV_ROUND_UP(size, PAGE_SIZE),
+                          paddr_to_pfn(addr & PAGE_MASK));
+        if ( res )
+        {
+             panic(XENLOG_ERR "Unable to map 0x%"PRIx64
+                   " - 0x%"PRIx64" in domain \n",
+                   addr & PAGE_MASK, PAGE_ALIGN(addr + size) - 1);
+        }
+    }
+}
+
 static int acpi_create_rsdp(struct domain *d, struct membank tbl_add[])
 {
 
@@ -1711,6 +1734,8 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
     if ( rc != 0 )
         return rc;
 
+    acpi_map_rest_tables(d);
+
     return 0;
 }
 #else
#255 lore raw

PATCH v3 50/62 xen/efi: store EFI system table in efi structure

In reply to shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

When preparing EFI tables for Dom0, it needs the information of EFI system table. Here store it in efi structure.

---
 xen/common/efi/boot.c | 2 ++
 xen/include/xen/efi.h | 1 +
 2 files changed, 3 insertions(+)
xen/common/efi/boot.c +2 -0
index 78d8ae9..6a48624 100644
@@ -1155,6 +1155,8 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
 
     efi_tables();
 
+    efi.est = (long)SystemTable;
+
     /* Collect PCI ROM contents. */
     setup_efi_pci();
 
xen/include/xen/efi.h +1 -0
index e74dad1..e112296 100644
@@ -16,6 +16,7 @@ struct efi {
     unsigned long acpi20;       /* ACPI table (ACPI 2.0) */
     unsigned long smbios;       /* SM BIOS table */
     unsigned long smbios3;      /* SMBIOS v3 table */
+    unsigned long est;          /* EFI system table */
 };
 
 extern struct efi efi;
Signature · 1 line
2.1.0
#256 lore raw

PATCH v3 50/62 xen/efi: store EFI system table in efi structure

Quoted 5 lines
Quoted 1 line
Quoted 1 line · On 17.11.15 at 10:40, <[email protected]> wrote:

From: Shannon Zhao <[email protected]>

When preparing EFI tables for Dom0, it needs the information of EFI system table. Here store it in efi structure.

Again I'm pretty sure I had already pointed out that this not being needed on x86 calls for either more than the brief description above or this being done just for ARM or (preferably) the table pointer
- where _really_ needed - to be passed around as function argument(s).

Jan

#257 lore raw

Re: [PATCH v3 50/62] xen/efi: store EFI system table in efi structure

In reply to shannon.zhao at linaro.org
Quoted 5 lines
Quoted 1 line
Quoted 1 line · On 17.11.15 at 10:40, <[email protected]> wrote:

From: Shannon Zhao <[email protected]>

When preparing EFI tables for Dom0, it needs the information of EFI system table. Here store it in efi structure.

Again I'm pretty sure I had already pointed out that this not being needed on x86 calls for either more than the brief description above or this being done just for ARM or (preferably) the table pointer
- where _really_ needed - to be passed around as function argument(s).

Jan

#258 lore raw

PATCH v3 50/62 xen/efi: store EFI system table in efi structure

In reply to shannon.zhao at linaro.org

Hi Shannon,

Quoted 4 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

When preparing EFI tables for Dom0, it needs the information of EFI system table. Here store it in efi structure.

On ARM64 the EFI stub is completely independent and therefore it's not possible to share variable between Xen and the stub.

If it's working today is only by luck as we zero the BSS after the stub jumped to Xen entry point.

Regards,

Quoted 33 lines
---
 xen/common/efi/boot.c | 2 ++
 xen/include/xen/efi.h | 1 +
 2 files changed, 3 insertions(+)
xen/common/efi/boot.c +2 -0
index 78d8ae9..6a48624 100644
@@ -1155,6 +1155,8 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
 
     efi_tables();
 
+    efi.est = (long)SystemTable;
+
     /* Collect PCI ROM contents. */
     setup_efi_pci();
 
xen/include/xen/efi.h +1 -0
index e74dad1..e112296 100644
@@ -16,6 +16,7 @@ struct efi {
     unsigned long acpi20;       /* ACPI table (ACPI 2.0) */
     unsigned long smbios;       /* SM BIOS table */
     unsigned long smbios3;      /* SMBIOS v3 table */
+    unsigned long est;          /* EFI system table */
 };
 
 extern struct efi efi;
Signature · 1 line
Julien Grall
#259 lore raw

PATCH v3 50/62 xen/efi: store EFI system table in efi structure

Quoted 5 lines · Julien Grall

Hi Shannon,

Quoted 2 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Quoted 9 lines
Quoted 2 lines

When preparing EFI tables for Dom0, it needs the information of EFI system table. Here store it in efi structure.

On ARM64 the EFI stub is completely independent and therefore it's not possible to share variable between Xen and the stub.

If it's working today is only by luck as we zero the BSS after the stub jumped to Xen entry point.

Yes, that's right. Sorry, I didn't investigate this deeply while just getting this patch of Parth version.

I re-think about it. The reason why we need that variable is that when we create EFI System table for Dom0 it copies the table header from that. Since it supplies Dom0 a Xen specific UEFI and it could get the information from other way, this change is not necessary. I'll drop this at next version.

Thanks,

Signature · 1 line
Shannon
#260 lore raw

Re: [PATCH v3 50/62] xen/efi: store EFI system table in efi structure

In reply to Julien Grall
Quoted 5 lines · Julien Grall

Hi Shannon,

Quoted 2 lines · On 17/11/15 09:40, [email protected] wrote:

From: Shannon Zhao <[email protected]>

Quoted 9 lines
Quoted 2 lines

When preparing EFI tables for Dom0, it needs the information of EFI system table. Here store it in efi structure.

On ARM64 the EFI stub is completely independent and therefore it's not possible to share variable between Xen and the stub.

If it's working today is only by luck as we zero the BSS after the stub jumped to Xen entry point.

Yes, that's right. Sorry, I didn't investigate this deeply while just getting this patch of Parth version.

I re-think about it. The reason why we need that variable is that when we create EFI System table for Dom0 it copies the table header from that. Since it supplies Dom0 a Xen specific UEFI and it could get the information from other way, this change is not necessary. I'll drop this at next version.

Thanks,

Signature · 1 line
Shannon
#261 lore raw

Re: [PATCH v3 50/62] xen/efi: store EFI system table in efi structure

In reply to shannon.zhao at linaro.org

Hi Shannon,

Quoted 4 lines · On 17/11/15 09:40, [email protected] wrote:

From: Shannon Zhao <[email protected]>

When preparing EFI tables for Dom0, it needs the information of EFI system table. Here store it in efi structure.

On ARM64 the EFI stub is completely independent and therefore it's not possible to share variable between Xen and the stub.

If it's working today is only by luck as we zero the BSS after the stub jumped to Xen entry point.

Regards,

Quoted 33 lines
---
 xen/common/efi/boot.c | 2 ++
 xen/include/xen/efi.h | 1 +
 2 files changed, 3 insertions(+)
xen/common/efi/boot.c +2 -0
index 78d8ae9..6a48624 100644
@@ -1155,6 +1155,8 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
 
     efi_tables();
 
+    efi.est = (long)SystemTable;
+
     /* Collect PCI ROM contents. */
     setup_efi_pci();
 
xen/include/xen/efi.h +1 -0
index e74dad1..e112296 100644
@@ -16,6 +16,7 @@ struct efi {
     unsigned long acpi20;       /* ACPI table (ACPI 2.0) */
     unsigned long smbios;       /* SM BIOS table */
     unsigned long smbios3;      /* SMBIOS v3 table */
+    unsigned long est;          /* EFI system table */
 };
 
 extern struct efi efi;
Signature · 1 line
Julien Grall
#262 lore raw

PATCH v3 51/62 arm/acpi: Prepare EFI system table for Dom0

In reply to shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

---
 xen/arch/arm/domain_build.c |  2 ++
 xen/common/efi/boot.c       | 64 +++++++++++++++++++++++++++++++++++++++++++++
 xen/include/asm-arm/setup.h |  3 +++
 3 files changed, 69 insertions(+)
xen/arch/arm/domain_build.c +2 -0
index da4e271..9d667ea 100644
@@ -1735,6 +1735,8 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
         return rc;
 
     acpi_map_rest_tables(d);
+    acpi_create_efi_system_table(d->arch.efi_acpi_gpa, d->arch.efi_acpi_table,
+                                 tbl_add);
 
     return 0;
 }
xen/common/efi/boot.c +64 -0

70 lines not on this page · raw message

xen/include/asm-arm/setup.h +3 -0
index b759813..2d65796 100644
@@ -53,6 +53,9 @@ void copy_from_paddr(void *dst, paddr_t paddr, unsigned long len);
 
 int estimate_efi_size(int mem_nr_banks);
 
+void acpi_create_efi_system_table(paddr_t paddr, void *efi_acpi_table,
+                                  struct membank tbl_add[]);
+
 int construct_dom0(struct domain *d);
 
 void discard_initial_modules(void);
Signature · 1 line
2.1.0
#263 lore raw

PATCH v3 51/62 arm/acpi: Prepare EFI system table for Dom0

Hi Shannon,

Quoted 23 lines · shannon.zhao at linaro.org
xen/common/efi/boot.c +15 -0
index 6a48624..75835ae 100644
@@ -1192,6 +1192,70 @@ int __init estimate_efi_size(int mem_nr_banks)
 
     return size;
 }
+
+static uint32_t __init xz_crc32(uint8_t *buf, size_t size, uint32_t crc)
+{
+    uint32_t xz_crc32_table[256];
+    const uint32_t poly = 0xEDB88320;
+    uint32_t i;
+    uint32_t j;
+    uint32_t r;
+
+    for (i = 0; i < 256; ++i) {
+        r = i;
+        for (j = 0; j < 8; ++j)
+            r = (r >> 1) ^ (poly & ~((r & 1) - 1));
+
+        xz_crc32_table[i] = r;

xen/common/efi/boot.c int __init estimate_efi_size(int mem_nr_banks) · line 1219

Quoted 10 lines
xen/common/efi/boot.c +10 -0
+    }
+
+    crc = ~crc;
+    while (size != 0) {
+            crc = xz_crc32_table[*buf++ ^ (crc & 0xFF)] ^ (crc >> 8);
+            --size;
+    }
+
+    return ~crc;
+}

I'm nearly sure I already said it, this code already exists in the tree. Why do you need to implement a new version?

Regards,

Signature · 1 line
Julien Grall
#264 lore raw

Re: [PATCH v3 51/62] arm/acpi: Prepare EFI system table for Dom0

Quoted 2 lines · Julien Grall

I'm nearly sure I already said it, this code already exists in the tree. Why do you need to implement a new version?

Ok, it needs to move the functions to the public place, right? So they can be called from other places.

Thanks,

Signature · 1 line
Shannon
#265 lore raw

Re: [PATCH v3 51/62] arm/acpi: Prepare EFI system table for Dom0

Quoted 5 lines · Shannon Zhao
Quoted 2 lines · Julien Grall

I'm nearly sure I already said it, this code already exists in the tree. Why do you need to implement a new version?

Ok, it needs to move the functions to the public place, right? So they can be called from other places.

I don't think you need to move the current function code. AFAICT, it's already exported by common/xz/crc32.c

Regards,

Signature · 1 line
Julien Grall
#266 lore raw

Re: [PATCH v3 51/62] arm/acpi: Prepare EFI system table for Dom0

In reply to shannon.zhao at linaro.org

Hi Shannon,

Quoted 23 lines · On 17/11/15 09:40, [email protected] wrote:
xen/common/efi/boot.c +15 -0
index 6a48624..75835ae 100644
@@ -1192,6 +1192,70 @@ int __init estimate_efi_size(int mem_nr_banks)
 
     return size;
 }
+
+static uint32_t __init xz_crc32(uint8_t *buf, size_t size, uint32_t crc)
+{
+    uint32_t xz_crc32_table[256];
+    const uint32_t poly = 0xEDB88320;
+    uint32_t i;
+    uint32_t j;
+    uint32_t r;
+
+    for (i = 0; i < 256; ++i) {
+        r = i;
+        for (j = 0; j < 8; ++j)
+            r = (r >> 1) ^ (poly & ~((r & 1) - 1));
+
+        xz_crc32_table[i] = r;

xen/common/efi/boot.c int __init estimate_efi_size(int mem_nr_banks) · line 1219

Quoted 10 lines
xen/common/efi/boot.c +10 -0
+    }
+
+    crc = ~crc;
+    while (size != 0) {
+            crc = xz_crc32_table[*buf++ ^ (crc & 0xFF)] ^ (crc >> 8);
+            --size;
+    }
+
+    return ~crc;
+}

I'm nearly sure I already said it, this code already exists in the tree. Why do you need to implement a new version?

Regards,

Signature · 1 line
Julien Grall
#267 lore raw

PATCH v3 51/62 arm/acpi: Prepare EFI system table for Dom0

In reply to shannon.zhao at linaro.org
Quoted 7 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

---
 xen/arch/arm/domain_build.c |  2 ++
 xen/common/efi/boot.c       | 64 +++++++++++++++++++++++++++++++++++++++++++++

Why do you add the creation of ACPI table in efi/boot.c?

This file is only supposed to contain the EFI stub and nothing else.

Regards,

Signature · 1 line
Julien Grall
#268 lore raw

Re: [PATCH v3 51/62] arm/acpi: Prepare EFI system table for Dom0

In reply to shannon.zhao at linaro.org
Quoted 7 lines · On 17/11/15 09:40, [email protected] wrote:

From: Shannon Zhao <[email protected]>

---
 xen/arch/arm/domain_build.c |  2 ++
 xen/common/efi/boot.c       | 64 +++++++++++++++++++++++++++++++++++++++++++++

Why do you add the creation of ACPI table in efi/boot.c?

This file is only supposed to contain the EFI stub and nothing else.

Regards,

Signature · 1 line
Julien Grall
#269 lore raw

PATCH v3 51/62 arm/acpi: Prepare EFI system table for Dom0

In reply to shannon.zhao at linaro.org
Quoted 46 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

---
 xen/arch/arm/domain_build.c |  2 ++
 xen/common/efi/boot.c       | 64 +++++++++++++++++++++++++++++++++++++++++++++
 xen/include/asm-arm/setup.h |  3 +++
 3 files changed, 69 insertions(+)
xen/arch/arm/domain_build.c +2 -0
index da4e271..9d667ea 100644
@@ -1735,6 +1735,8 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
         return rc;
 
     acpi_map_rest_tables(d);
+    acpi_create_efi_system_table(d->arch.efi_acpi_gpa, d->arch.efi_acpi_table,
+                                 tbl_add);
 
     return 0;
 }
xen/common/efi/boot.c +15 -0
index 6a48624..75835ae 100644
@@ -1192,6 +1192,70 @@ int __init estimate_efi_size(int mem_nr_banks)
 
     return size;
 }
+
+static uint32_t __init xz_crc32(uint8_t *buf, size_t size, uint32_t crc)
+{
+    uint32_t xz_crc32_table[256];
+    const uint32_t poly = 0xEDB88320;
+    uint32_t i;
+    uint32_t j;
+    uint32_t r;
+
+    for (i = 0; i < 256; ++i) {
+        r = i;
+        for (j = 0; j < 8; ++j)
+            r = (r >> 1) ^ (poly & ~((r & 1) - 1));
+
+        xz_crc32_table[i] = r;

xen/common/efi/boot.c int __init estimate_efi_size(int mem_nr_banks) · line 1219

Quoted 10 lines
xen/common/efi/boot.c +10 -0
+    }
+
+    crc = ~crc;
+    while (size != 0) {
+            crc = xz_crc32_table[*buf++ ^ (crc & 0xFF)] ^ (crc >> 8);
+            --size;
+    }
+
+    return ~crc;
+}

I agree with Julien that we should reuse the existing functions for this

Quoted 29 lines
xen/common/efi/boot.c +29 -0
+void __init acpi_create_efi_system_table(paddr_t paddr, void *efi_acpi_table,
+                                         struct membank tbl_add[])
+{
+    u64 table_addr, table_size, offset = 0;
+    u8 *base_ptr;
+    EFI_CONFIGURATION_TABLE *efi_conf_tbl;
+    EFI_SYSTEM_TABLE *efi_sys_tbl;
+    EFI_SYSTEM_TABLE *est = (EFI_SYSTEM_TABLE *)maddr_to_virt(efi.est);
+
+    table_addr = paddr + acpi_get_table_offset(tbl_add, TBL_EFIT);
+    table_size = sizeof(EFI_SYSTEM_TABLE) + sizeof(EFI_CONFIGURATION_TABLE)
+                 + sizeof(XEN_EFI_FW_VENDOR);
+    base_ptr = efi_acpi_table + acpi_get_table_offset(tbl_add, TBL_EFIT);
+    efi_sys_tbl = (EFI_SYSTEM_TABLE *)base_ptr;
+
+    memcpy((EFI_TABLE_HEADER *)&(efi_sys_tbl->Hdr),
+           (EFI_TABLE_HEADER *)&(est->Hdr), sizeof(EFI_TABLE_HEADER));
+    efi_sys_tbl->Hdr.HeaderSize = table_size;
+
+    efi_sys_tbl->FirmwareRevision = est->FirmwareRevision;
+    efi_sys_tbl->NumberOfTableEntries = 1;
+    offset += sizeof(EFI_SYSTEM_TABLE);
+    memcpy((u16 *)(base_ptr + offset), XEN_EFI_FW_VENDOR,
+           sizeof(XEN_EFI_FW_VENDOR));
+    efi_sys_tbl->FirmwareVendor = (CHAR16 *)(table_addr + offset);
+
+    offset += sizeof(XEN_EFI_FW_VENDOR);
+    efi_conf_tbl = (EFI_CONFIGURATION_TABLE *)(base_ptr + offset);
+    efi_conf_tbl->VendorGuid = (EFI_GUID)ACPI_20_TABLE_GUID;

xen/common/efi/boot.c int __init estimate_efi_size(int mem_nr_banks) · line 1259

Quoted 10 lines
xen/common/efi/boot.c +9 -0
+    efi_conf_tbl->VendorTable = (VOID *)tbl_add[TBL_RSDP].start;
+    efi_sys_tbl->ConfigurationTable = (EFI_CONFIGURATION_TABLE *)(table_addr
+                                                                  + offset);
+    efi_sys_tbl->Hdr.CRC32 = xz_crc32((uint8_t *)efi_sys_tbl,
+                                      efi_sys_tbl->Hdr.HeaderSize, 0);
+
+    tbl_add[TBL_EFIT].start = table_addr;
+    tbl_add[TBL_EFIT].size = table_size;
+}
 #endif

I also agree with Julien that acpi_create_efi_system_table shouldn't be here. You should be able to move the function to xen/arch/arm/domain_build.c.

The rest is OK.

Quoted 18 lines
xen/common/efi/boot.c +0 -0
 #ifndef CONFIG_ARM /* TODO - runtime service support */
xen/include/asm-arm/setup.h +3 -0
index b759813..2d65796 100644
@@ -53,6 +53,9 @@ void copy_from_paddr(void *dst, paddr_t paddr, unsigned long len);
 
 int estimate_efi_size(int mem_nr_banks);
 
+void acpi_create_efi_system_table(paddr_t paddr, void *efi_acpi_table,
+                                  struct membank tbl_add[]);
+
 int construct_dom0(struct domain *d);
 
 void discard_initial_modules(void);
Signature · 1 line
2.1.0
#270 lore raw

Re: [PATCH v3 51/62] arm/acpi: Prepare EFI system table for Dom0

In reply to shannon.zhao at linaro.org
Quoted 46 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Shannon Zhao <[email protected]>

---
 xen/arch/arm/domain_build.c |  2 ++
 xen/common/efi/boot.c       | 64 +++++++++++++++++++++++++++++++++++++++++++++
 xen/include/asm-arm/setup.h |  3 +++
 3 files changed, 69 insertions(+)
xen/arch/arm/domain_build.c +2 -0
index da4e271..9d667ea 100644
@@ -1735,6 +1735,8 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
         return rc;
 
     acpi_map_rest_tables(d);
+    acpi_create_efi_system_table(d->arch.efi_acpi_gpa, d->arch.efi_acpi_table,
+                                 tbl_add);
 
     return 0;
 }
xen/common/efi/boot.c +15 -0
index 6a48624..75835ae 100644
@@ -1192,6 +1192,70 @@ int __init estimate_efi_size(int mem_nr_banks)
 
     return size;
 }
+
+static uint32_t __init xz_crc32(uint8_t *buf, size_t size, uint32_t crc)
+{
+    uint32_t xz_crc32_table[256];
+    const uint32_t poly = 0xEDB88320;
+    uint32_t i;
+    uint32_t j;
+    uint32_t r;
+
+    for (i = 0; i < 256; ++i) {
+        r = i;
+        for (j = 0; j < 8; ++j)
+            r = (r >> 1) ^ (poly & ~((r & 1) - 1));
+
+        xz_crc32_table[i] = r;

xen/common/efi/boot.c int __init estimate_efi_size(int mem_nr_banks) · line 1219

Quoted 10 lines
xen/common/efi/boot.c +10 -0
+    }
+
+    crc = ~crc;
+    while (size != 0) {
+            crc = xz_crc32_table[*buf++ ^ (crc & 0xFF)] ^ (crc >> 8);
+            --size;
+    }
+
+    return ~crc;
+}

I agree with Julien that we should reuse the existing functions for this

Quoted 29 lines
xen/common/efi/boot.c +29 -0
+void __init acpi_create_efi_system_table(paddr_t paddr, void *efi_acpi_table,
+                                         struct membank tbl_add[])
+{
+    u64 table_addr, table_size, offset = 0;
+    u8 *base_ptr;
+    EFI_CONFIGURATION_TABLE *efi_conf_tbl;
+    EFI_SYSTEM_TABLE *efi_sys_tbl;
+    EFI_SYSTEM_TABLE *est = (EFI_SYSTEM_TABLE *)maddr_to_virt(efi.est);
+
+    table_addr = paddr + acpi_get_table_offset(tbl_add, TBL_EFIT);
+    table_size = sizeof(EFI_SYSTEM_TABLE) + sizeof(EFI_CONFIGURATION_TABLE)
+                 + sizeof(XEN_EFI_FW_VENDOR);
+    base_ptr = efi_acpi_table + acpi_get_table_offset(tbl_add, TBL_EFIT);
+    efi_sys_tbl = (EFI_SYSTEM_TABLE *)base_ptr;
+
+    memcpy((EFI_TABLE_HEADER *)&(efi_sys_tbl->Hdr),
+           (EFI_TABLE_HEADER *)&(est->Hdr), sizeof(EFI_TABLE_HEADER));
+    efi_sys_tbl->Hdr.HeaderSize = table_size;
+
+    efi_sys_tbl->FirmwareRevision = est->FirmwareRevision;
+    efi_sys_tbl->NumberOfTableEntries = 1;
+    offset += sizeof(EFI_SYSTEM_TABLE);
+    memcpy((u16 *)(base_ptr + offset), XEN_EFI_FW_VENDOR,
+           sizeof(XEN_EFI_FW_VENDOR));
+    efi_sys_tbl->FirmwareVendor = (CHAR16 *)(table_addr + offset);
+
+    offset += sizeof(XEN_EFI_FW_VENDOR);
+    efi_conf_tbl = (EFI_CONFIGURATION_TABLE *)(base_ptr + offset);
+    efi_conf_tbl->VendorGuid = (EFI_GUID)ACPI_20_TABLE_GUID;

xen/common/efi/boot.c int __init estimate_efi_size(int mem_nr_banks) · line 1259

Quoted 10 lines
xen/common/efi/boot.c +9 -0
+    efi_conf_tbl->VendorTable = (VOID *)tbl_add[TBL_RSDP].start;
+    efi_sys_tbl->ConfigurationTable = (EFI_CONFIGURATION_TABLE *)(table_addr
+                                                                  + offset);
+    efi_sys_tbl->Hdr.CRC32 = xz_crc32((uint8_t *)efi_sys_tbl,
+                                      efi_sys_tbl->Hdr.HeaderSize, 0);
+
+    tbl_add[TBL_EFIT].start = table_addr;
+    tbl_add[TBL_EFIT].size = table_size;
+}
 #endif

I also agree with Julien that acpi_create_efi_system_table shouldn't be here. You should be able to move the function to xen/arch/arm/domain_build.c.

The rest is OK.

Quoted 18 lines
xen/common/efi/boot.c +0 -0
 #ifndef CONFIG_ARM /* TODO - runtime service support */
xen/include/asm-arm/setup.h +3 -0
index b759813..2d65796 100644
@@ -53,6 +53,9 @@ void copy_from_paddr(void *dst, paddr_t paddr, unsigned long len);
 
 int estimate_efi_size(int mem_nr_banks);
 
+void acpi_create_efi_system_table(paddr_t paddr, void *efi_acpi_table,
+                                  struct membank tbl_add[]);
+
 int construct_dom0(struct domain *d);
 
 void discard_initial_modules(void);
Signature · 1 line
2.1.0
#271 lore raw

PATCH v3 52/62 arm/acpi: Prepare EFI memory descriptor for Dom0

In reply to shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Create a few EFI memory descriptors to tell Dom0 the RAM region information, ACPI table regions and EFI tables reserved resions.

---
 xen/arch/arm/domain_build.c |  2 ++
 xen/common/efi/boot.c       | 48 +++++++++++++++++++++++++++++++++++++++++++++
 xen/include/asm-arm/setup.h |  4 ++++
 3 files changed, 54 insertions(+)
xen/arch/arm/domain_build.c +2 -0
index 9d667ea..073c634 100644
@@ -1737,6 +1737,8 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
     acpi_map_rest_tables(d);
     acpi_create_efi_system_table(d->arch.efi_acpi_gpa, d->arch.efi_acpi_table,
                                  tbl_add);
+    acpi_create_efi_mmap_table(d->arch.efi_acpi_gpa, d->arch.efi_acpi_table,
+                               &kinfo->mem, tbl_add);
 
     return 0;
 }
xen/common/efi/boot.c +48 -0

54 lines not on this page · raw message

xen/include/asm-arm/setup.h +4 -0
index 2d65796..35447ee 100644
@@ -56,6 +56,10 @@ int estimate_efi_size(int mem_nr_banks);
 void acpi_create_efi_system_table(paddr_t paddr, void *efi_acpi_table,
                                   struct membank tbl_add[]);
 
+void acpi_create_efi_mmap_table(paddr_t paddr, void *efi_acpi_table,
+                                const struct meminfo *mem,
+                                struct membank tbl_add[]);
+
 int construct_dom0(struct domain *d);
 
 void discard_initial_modules(void);
Signature · 1 line
2.1.0
#272 lore raw

PATCH v3 52/62 arm/acpi: Prepare EFI memory descriptor for Dom0

Quoted 31 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Create a few EFI memory descriptors to tell Dom0 the RAM region information, ACPI table regions and EFI tables reserved resions.

---
 xen/arch/arm/domain_build.c |  2 ++
 xen/common/efi/boot.c       | 48 +++++++++++++++++++++++++++++++++++++++++++++
 xen/include/asm-arm/setup.h |  4 ++++
 3 files changed, 54 insertions(+)
xen/arch/arm/domain_build.c +2 -0
index 9d667ea..073c634 100644
@@ -1737,6 +1737,8 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
     acpi_map_rest_tables(d);
     acpi_create_efi_system_table(d->arch.efi_acpi_gpa, d->arch.efi_acpi_table,
                                  tbl_add);
+    acpi_create_efi_mmap_table(d->arch.efi_acpi_gpa, d->arch.efi_acpi_table,
+                               &kinfo->mem, tbl_add);
 
     return 0;
 }
xen/common/efi/boot.c +0 -0
index 75835ae..ff2faed 100644

xen/common/efi/boot.c void __init acpi_create_efi_system_table(paddr_t paddr, void *efi_acpi_table, · line 1262

Quoted 7 lines
xen/common/efi/boot.c +4 -0
@@ -1256,6 +1256,54 @@ void __init acpi_create_efi_system_table(paddr_t paddr, void *efi_acpi_table,
     tbl_add[TBL_EFIT].start = table_addr;
     tbl_add[TBL_EFIT].size = table_size;
 }
+
+void __init acpi_create_efi_mmap_table(paddr_t paddr, void *efi_acpi_table,
+                                       const struct meminfo *mem,
+                                       struct membank tbl_add[])

This function shouldn't be in this file.

Quoted 8 lines
xen/common/efi/boot.c +8 -0
+{
+    EFI_MEMORY_DESCRIPTOR *memory_map;
+    int i, offset;
+    u8 *base_ptr;
+
+    tbl_add[TBL_MMAP].start = paddr + acpi_get_table_offset(tbl_add, TBL_MMAP);
+    tbl_add[TBL_MMAP].size = sizeof(EFI_MEMORY_DESCRIPTOR)
+                             * (mem->nr_banks + acpi_mem.nr_banks + TBL_MMAX);

xen/common/efi/boot.c void __init acpi_create_efi_system_table(paddr_t paddr, void *efi_acpi_table,

Quoted 10 lines
xen/common/efi/boot.c +10 -0
+
+    base_ptr = efi_acpi_table + acpi_get_table_offset(tbl_add, TBL_MMAP);
+    memory_map = (EFI_MEMORY_DESCRIPTOR *)(base_ptr);
+
+    offset = 0;
+    for( i = 0; i < mem->nr_banks; i++, offset++ )
+    {
+        memory_map[offset].Type = EfiConventionalMemory;
+        memory_map[offset].PhysicalStart = mem->bank[i].start;
+        memory_map[offset].NumberOfPages = mem->bank[i].size/PAGE_SIZE;

Use PAGE_SHIFT throughout the function.

Quoted 8 lines
xen/common/efi/boot.c +8 -0
+        memory_map[offset].Attribute = EFI_MEMORY_WB;
+    }
+
+    for( i = 0; i < acpi_mem.nr_banks; i++, offset++ )
+    {
+        memory_map[offset].Type = EfiACPIReclaimMemory;
+        memory_map[offset].PhysicalStart = acpi_mem.bank[i].start;
+        memory_map[offset].NumberOfPages = acpi_mem.bank[i].size/PAGE_SIZE;

xen/common/efi/boot.c void __init acpi_create_efi_system_table(paddr_t paddr, void *efi_acpi_table, · line 1297

Quoted 10 lines
xen/common/efi/boot.c +10 -0
+        memory_map[offset].Attribute = EFI_MEMORY_WB;
+    }
+
+    for( i = 0; i < TBL_EFIT; i++, offset++ )
+    {
+        memory_map[offset].Type = EfiACPIReclaimMemory;
+        memory_map[offset].PhysicalStart = tbl_add[i].start;
+        memory_map[offset].NumberOfPages =tbl_add[i].size/PAGE_SIZE;
+        memory_map[offset].Attribute = EFI_MEMORY_WB;
+    }

Can't we just use a single EFI_MEMORY_DESCRIPTOR (or maybe 2, to cover EfiACPIReclaimMemory and EfiReservedMemoryType regions) to describe the whole efi_acpi_gpa region? Using one EFI_MEMORY_DESCRIPTOR per table, and PAGE_ALIGNing each of them, looks like a waste of memory to me. Unless it's an ACPI or EFI spec requirement.

Quoted 29 lines
xen/common/efi/boot.c +8 -0
+    for( i = TBL_EFIT; i < TBL_MMAX; i++, offset++ )
+    {
+        memory_map[offset].Type = EfiReservedMemoryType;
+        memory_map[offset].PhysicalStart = tbl_add[i].start;
+        memory_map[offset].NumberOfPages =tbl_add[i].size/PAGE_SIZE;
+        memory_map[offset].Attribute = EFI_MEMORY_WB;
+    }
+}
 #endif
 
 #ifndef CONFIG_ARM /* TODO - runtime service support */
xen/include/asm-arm/setup.h +4 -0
index 2d65796..35447ee 100644
@@ -56,6 +56,10 @@ int estimate_efi_size(int mem_nr_banks);
 void acpi_create_efi_system_table(paddr_t paddr, void *efi_acpi_table,
                                   struct membank tbl_add[]);
 
+void acpi_create_efi_mmap_table(paddr_t paddr, void *efi_acpi_table,
+                                const struct meminfo *mem,
+                                struct membank tbl_add[]);
+
 int construct_dom0(struct domain *d);
 
 void discard_initial_modules(void);
Signature · 1 line
2.1.0
#273 lore raw

PATCH v3 52/62 arm/acpi: Prepare EFI memory descriptor for Dom0

Quoted 79 lines · Stefano Stabellini
Quoted 24 lines · shannon.zhao at linaro.org
Quoted 24 lines

From: Shannon Zhao <[email protected]>

Create a few EFI memory descriptors to tell Dom0 the RAM region information, ACPI table regions and EFI tables reserved resions.

---
 xen/arch/arm/domain_build.c |  2 ++
 xen/common/efi/boot.c       | 48 +++++++++++++++++++++++++++++++++++++++++++++
 xen/include/asm-arm/setup.h |  4 ++++
 3 files changed, 54 insertions(+)
xen/arch/arm/domain_build.c +2 -0
index 9d667ea..073c634 100644
@@ -1737,6 +1737,8 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
     acpi_map_rest_tables(d);
     acpi_create_efi_system_table(d->arch.efi_acpi_gpa, d->arch.efi_acpi_table,
                                  tbl_add);
+    acpi_create_efi_mmap_table(d->arch.efi_acpi_gpa, d->arch.efi_acpi_table,
+                               &kinfo->mem, tbl_add);
 
Quoted 14 lines
Quoted 7 lines
xen/arch/arm/domain_build.c +0 -0
     return 0;
 }
xen/common/efi/boot.c +0 -0
index 75835ae..ff2faed 100644

xen/common/efi/boot.c void __init acpi_create_efi_system_table(paddr_t paddr, void *efi_acpi_table, · line 1262

Quoted 7 lines
xen/common/efi/boot.c +4 -0
@@ -1256,6 +1256,54 @@ void __init acpi_create_efi_system_table(paddr_t paddr, void *efi_acpi_table,
     tbl_add[TBL_EFIT].start = table_addr;
     tbl_add[TBL_EFIT].size = table_size;
 }
+
+void __init acpi_create_efi_mmap_table(paddr_t paddr, void *efi_acpi_table,
+                                       const struct meminfo *mem,
+                                       struct membank tbl_add[])

This function shouldn't be in this file.

Quoted 10 lines
Quoted 10 lines
xen/common/efi/boot.c +10 -0
+{
+    EFI_MEMORY_DESCRIPTOR *memory_map;
+    int i, offset;
+    u8 *base_ptr;
+
+    tbl_add[TBL_MMAP].start = paddr + acpi_get_table_offset(tbl_add, TBL_MMAP);
+    tbl_add[TBL_MMAP].size = sizeof(EFI_MEMORY_DESCRIPTOR)
+                             * (mem->nr_banks + acpi_mem.nr_banks + TBL_MMAX);
+
+    base_ptr = efi_acpi_table + acpi_get_table_offset(tbl_add, TBL_MMAP);
Quoted 8 lines

xen/common/efi/boot.c void __init acpi_create_efi_system_table(paddr_t paddr, void *efi_acpi_table, · line 1279

Quoted 8 lines
xen/common/efi/boot.c +8 -0
+    memory_map = (EFI_MEMORY_DESCRIPTOR *)(base_ptr);
+
+    offset = 0;
+    for( i = 0; i < mem->nr_banks; i++, offset++ )
+    {
+        memory_map[offset].Type = EfiConventionalMemory;
+        memory_map[offset].PhysicalStart = mem->bank[i].start;
+        memory_map[offset].NumberOfPages = mem->bank[i].size/PAGE_SIZE;

Use PAGE_SHIFT throughout the function.

Quoted 15 lines
Quoted 15 lines
xen/common/efi/boot.c +15 -0
+        memory_map[offset].Attribute = EFI_MEMORY_WB;
+    }
+
+    for( i = 0; i < acpi_mem.nr_banks; i++, offset++ )
+    {
+        memory_map[offset].Type = EfiACPIReclaimMemory;
+        memory_map[offset].PhysicalStart = acpi_mem.bank[i].start;
+        memory_map[offset].NumberOfPages = acpi_mem.bank[i].size/PAGE_SIZE;
+        memory_map[offset].Attribute = EFI_MEMORY_WB;
+    }
+
+    for( i = 0; i < TBL_EFIT; i++, offset++ )
+    {
+        memory_map[offset].Type = EfiACPIReclaimMemory;
+        memory_map[offset].PhysicalStart = tbl_add[i].start;
Quoted 9 lines
Quoted 3 lines

xen/common/efi/boot.c void __init acpi_create_efi_system_table(paddr_t paddr, void *efi_acpi_table, · line 1297

Quoted 3 lines
xen/common/efi/boot.c +3 -0
+        memory_map[offset].NumberOfPages =tbl_add[i].size/PAGE_SIZE;
+        memory_map[offset].Attribute = EFI_MEMORY_WB;
+    }

Can't we just use a single EFI_MEMORY_DESCRIPTOR (or maybe 2, to cover EfiACPIReclaimMemory and EfiReservedMemoryType regions) to describe the whole efi_acpi_gpa region? Using one EFI_MEMORY_DESCRIPTOR per table, and PAGE_ALIGNing each of them, looks like a waste of memory to me. Unless it's an ACPI or EFI spec requirement.

Looking at the UEFI SPEC it says
"EFI memory descriptors of type EfiACPIReclaimMemory and EfiACPIMemoryNVS must be aligned on a 4 KiB boundary and must be a multiple of 4 KiB in size"

Signature · 1 line
Shannon
#274 lore raw

PATCH v3 52/62 arm/acpi: Prepare EFI memory descriptor for Dom0

Quoted 90 lines · Shannon Zhao
Quoted 79 lines · Stefano Stabellini
Quoted 24 lines · shannon.zhao at linaro.org
Quoted 24 lines

From: Shannon Zhao <[email protected]>

Create a few EFI memory descriptors to tell Dom0 the RAM region information, ACPI table regions and EFI tables reserved resions.

---
 xen/arch/arm/domain_build.c |  2 ++
 xen/common/efi/boot.c       | 48 +++++++++++++++++++++++++++++++++++++++++++++
 xen/include/asm-arm/setup.h |  4 ++++
 3 files changed, 54 insertions(+)
xen/arch/arm/domain_build.c +2 -0
index 9d667ea..073c634 100644
@@ -1737,6 +1737,8 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
     acpi_map_rest_tables(d);
     acpi_create_efi_system_table(d->arch.efi_acpi_gpa, d->arch.efi_acpi_table,
                                  tbl_add);
+    acpi_create_efi_mmap_table(d->arch.efi_acpi_gpa, d->arch.efi_acpi_table,
+                               &kinfo->mem, tbl_add);
 
Quoted 14 lines
Quoted 7 lines
xen/arch/arm/domain_build.c +0 -0
     return 0;
 }
xen/common/efi/boot.c +0 -0
index 75835ae..ff2faed 100644

xen/common/efi/boot.c void __init acpi_create_efi_system_table(paddr_t paddr, void *efi_acpi_table, · line 1262

Quoted 7 lines
xen/common/efi/boot.c +4 -0
@@ -1256,6 +1256,54 @@ void __init acpi_create_efi_system_table(paddr_t paddr, void *efi_acpi_table,
     tbl_add[TBL_EFIT].start = table_addr;
     tbl_add[TBL_EFIT].size = table_size;
 }
+
+void __init acpi_create_efi_mmap_table(paddr_t paddr, void *efi_acpi_table,
+                                       const struct meminfo *mem,
+                                       struct membank tbl_add[])

This function shouldn't be in this file.

Quoted 10 lines
Quoted 10 lines
xen/common/efi/boot.c +10 -0
+{
+    EFI_MEMORY_DESCRIPTOR *memory_map;
+    int i, offset;
+    u8 *base_ptr;
+
+    tbl_add[TBL_MMAP].start = paddr + acpi_get_table_offset(tbl_add, TBL_MMAP);
+    tbl_add[TBL_MMAP].size = sizeof(EFI_MEMORY_DESCRIPTOR)
+                             * (mem->nr_banks + acpi_mem.nr_banks + TBL_MMAX);
+
+    base_ptr = efi_acpi_table + acpi_get_table_offset(tbl_add, TBL_MMAP);
Quoted 8 lines

xen/common/efi/boot.c void __init acpi_create_efi_system_table(paddr_t paddr, void *efi_acpi_table, · line 1279

Quoted 8 lines
xen/common/efi/boot.c +8 -0
+    memory_map = (EFI_MEMORY_DESCRIPTOR *)(base_ptr);
+
+    offset = 0;
+    for( i = 0; i < mem->nr_banks; i++, offset++ )
+    {
+        memory_map[offset].Type = EfiConventionalMemory;
+        memory_map[offset].PhysicalStart = mem->bank[i].start;
+        memory_map[offset].NumberOfPages = mem->bank[i].size/PAGE_SIZE;

Use PAGE_SHIFT throughout the function.

Quoted 15 lines
Quoted 15 lines
xen/common/efi/boot.c +15 -0
+        memory_map[offset].Attribute = EFI_MEMORY_WB;
+    }
+
+    for( i = 0; i < acpi_mem.nr_banks; i++, offset++ )
+    {
+        memory_map[offset].Type = EfiACPIReclaimMemory;
+        memory_map[offset].PhysicalStart = acpi_mem.bank[i].start;
+        memory_map[offset].NumberOfPages = acpi_mem.bank[i].size/PAGE_SIZE;
+        memory_map[offset].Attribute = EFI_MEMORY_WB;
+    }
+
+    for( i = 0; i < TBL_EFIT; i++, offset++ )
+    {
+        memory_map[offset].Type = EfiACPIReclaimMemory;
+        memory_map[offset].PhysicalStart = tbl_add[i].start;
Quoted 9 lines
Quoted 3 lines

xen/common/efi/boot.c void __init acpi_create_efi_system_table(paddr_t paddr, void *efi_acpi_table, · line 1297

Quoted 3 lines
xen/common/efi/boot.c +3 -0
+        memory_map[offset].NumberOfPages =tbl_add[i].size/PAGE_SIZE;
+        memory_map[offset].Attribute = EFI_MEMORY_WB;
+    }

Can't we just use a single EFI_MEMORY_DESCRIPTOR (or maybe 2, to cover EfiACPIReclaimMemory and EfiReservedMemoryType regions) to describe the whole efi_acpi_gpa region? Using one EFI_MEMORY_DESCRIPTOR per table, and PAGE_ALIGNing each of them, looks like a waste of memory to me. Unless it's an ACPI or EFI spec requirement.

Quoted 3 lines

Looking at the UEFI SPEC it says
"EFI memory descriptors of type EfiACPIReclaimMemory and EfiACPIMemoryNVS must be aligned on a 4 KiB boundary and must be a multiple of 4 KiB in size"

OK, but can we use only one, 4 KiB aligned, descriptor for all tables?

#275 lore raw

Re: [PATCH v3 52/62] arm/acpi: Prepare EFI memory descriptor for Dom0

In reply to Shannon Zhao
Quoted 90 lines · Shannon Zhao
Quoted 79 lines · Stefano Stabellini
Quoted 24 lines · On Tue, 17 Nov 2015, [email protected] wrote:
Quoted 24 lines

From: Shannon Zhao <[email protected]>

Create a few EFI memory descriptors to tell Dom0 the RAM region information, ACPI table regions and EFI tables reserved resions.

---
 xen/arch/arm/domain_build.c |  2 ++
 xen/common/efi/boot.c       | 48 +++++++++++++++++++++++++++++++++++++++++++++
 xen/include/asm-arm/setup.h |  4 ++++
 3 files changed, 54 insertions(+)
xen/arch/arm/domain_build.c +2 -0
index 9d667ea..073c634 100644
@@ -1737,6 +1737,8 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
     acpi_map_rest_tables(d);
     acpi_create_efi_system_table(d->arch.efi_acpi_gpa, d->arch.efi_acpi_table,
                                  tbl_add);
+    acpi_create_efi_mmap_table(d->arch.efi_acpi_gpa, d->arch.efi_acpi_table,
+                               &kinfo->mem, tbl_add);
 
Quoted 14 lines
Quoted 7 lines
xen/arch/arm/domain_build.c +0 -0
     return 0;
 }
xen/common/efi/boot.c +0 -0
index 75835ae..ff2faed 100644

xen/common/efi/boot.c void __init acpi_create_efi_system_table(paddr_t paddr, void *efi_acpi_table, · line 1262

Quoted 7 lines
xen/common/efi/boot.c +4 -0
@@ -1256,6 +1256,54 @@ void __init acpi_create_efi_system_table(paddr_t paddr, void *efi_acpi_table,
     tbl_add[TBL_EFIT].start = table_addr;
     tbl_add[TBL_EFIT].size = table_size;
 }
+
+void __init acpi_create_efi_mmap_table(paddr_t paddr, void *efi_acpi_table,
+                                       const struct meminfo *mem,
+                                       struct membank tbl_add[])

This function shouldn't be in this file.

Quoted 10 lines
Quoted 10 lines
xen/common/efi/boot.c +10 -0
+{
+    EFI_MEMORY_DESCRIPTOR *memory_map;
+    int i, offset;
+    u8 *base_ptr;
+
+    tbl_add[TBL_MMAP].start = paddr + acpi_get_table_offset(tbl_add, TBL_MMAP);
+    tbl_add[TBL_MMAP].size = sizeof(EFI_MEMORY_DESCRIPTOR)
+                             * (mem->nr_banks + acpi_mem.nr_banks + TBL_MMAX);
+
+    base_ptr = efi_acpi_table + acpi_get_table_offset(tbl_add, TBL_MMAP);
Quoted 8 lines

xen/common/efi/boot.c void __init acpi_create_efi_system_table(paddr_t paddr, void *efi_acpi_table, · line 1279

Quoted 8 lines
xen/common/efi/boot.c +8 -0
+    memory_map = (EFI_MEMORY_DESCRIPTOR *)(base_ptr);
+
+    offset = 0;
+    for( i = 0; i < mem->nr_banks; i++, offset++ )
+    {
+        memory_map[offset].Type = EfiConventionalMemory;
+        memory_map[offset].PhysicalStart = mem->bank[i].start;
+        memory_map[offset].NumberOfPages = mem->bank[i].size/PAGE_SIZE;

Use PAGE_SHIFT throughout the function.

Quoted 15 lines
Quoted 15 lines
xen/common/efi/boot.c +15 -0
+        memory_map[offset].Attribute = EFI_MEMORY_WB;
+    }
+
+    for( i = 0; i < acpi_mem.nr_banks; i++, offset++ )
+    {
+        memory_map[offset].Type = EfiACPIReclaimMemory;
+        memory_map[offset].PhysicalStart = acpi_mem.bank[i].start;
+        memory_map[offset].NumberOfPages = acpi_mem.bank[i].size/PAGE_SIZE;
+        memory_map[offset].Attribute = EFI_MEMORY_WB;
+    }
+
+    for( i = 0; i < TBL_EFIT; i++, offset++ )
+    {
+        memory_map[offset].Type = EfiACPIReclaimMemory;
+        memory_map[offset].PhysicalStart = tbl_add[i].start;
Quoted 9 lines
Quoted 3 lines

xen/common/efi/boot.c void __init acpi_create_efi_system_table(paddr_t paddr, void *efi_acpi_table, · line 1297

Quoted 3 lines
xen/common/efi/boot.c +3 -0
+        memory_map[offset].NumberOfPages =tbl_add[i].size/PAGE_SIZE;
+        memory_map[offset].Attribute = EFI_MEMORY_WB;
+    }

Can't we just use a single EFI_MEMORY_DESCRIPTOR (or maybe 2, to cover EfiACPIReclaimMemory and EfiReservedMemoryType regions) to describe the whole efi_acpi_gpa region? Using one EFI_MEMORY_DESCRIPTOR per table, and PAGE_ALIGNing each of them, looks like a waste of memory to me. Unless it's an ACPI or EFI spec requirement.

Quoted 3 lines

Looking at the UEFI SPEC it says
"EFI memory descriptors of type EfiACPIReclaimMemory and EfiACPIMemoryNVS must be aligned on a 4 KiB boundary and must be a multiple of 4 KiB in size"

OK, but can we use only one, 4 KiB aligned, descriptor for all tables?

#276 lore raw

Re: [PATCH v3 52/62] arm/acpi: Prepare EFI memory descriptor for Dom0

In reply to shannon.zhao at linaro.org
Quoted 31 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Shannon Zhao <[email protected]>

Create a few EFI memory descriptors to tell Dom0 the RAM region information, ACPI table regions and EFI tables reserved resions.

---
 xen/arch/arm/domain_build.c |  2 ++
 xen/common/efi/boot.c       | 48 +++++++++++++++++++++++++++++++++++++++++++++
 xen/include/asm-arm/setup.h |  4 ++++
 3 files changed, 54 insertions(+)
xen/arch/arm/domain_build.c +2 -0
index 9d667ea..073c634 100644
@@ -1737,6 +1737,8 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
     acpi_map_rest_tables(d);
     acpi_create_efi_system_table(d->arch.efi_acpi_gpa, d->arch.efi_acpi_table,
                                  tbl_add);
+    acpi_create_efi_mmap_table(d->arch.efi_acpi_gpa, d->arch.efi_acpi_table,
+                               &kinfo->mem, tbl_add);
 
     return 0;
 }
xen/common/efi/boot.c +0 -0
index 75835ae..ff2faed 100644

xen/common/efi/boot.c void __init acpi_create_efi_system_table(paddr_t paddr, void *efi_acpi_table, · line 1262

Quoted 7 lines
xen/common/efi/boot.c +4 -0
@@ -1256,6 +1256,54 @@ void __init acpi_create_efi_system_table(paddr_t paddr, void *efi_acpi_table,
     tbl_add[TBL_EFIT].start = table_addr;
     tbl_add[TBL_EFIT].size = table_size;
 }
+
+void __init acpi_create_efi_mmap_table(paddr_t paddr, void *efi_acpi_table,
+                                       const struct meminfo *mem,
+                                       struct membank tbl_add[])

This function shouldn't be in this file.

Quoted 8 lines
xen/common/efi/boot.c +8 -0
+{
+    EFI_MEMORY_DESCRIPTOR *memory_map;
+    int i, offset;
+    u8 *base_ptr;
+
+    tbl_add[TBL_MMAP].start = paddr + acpi_get_table_offset(tbl_add, TBL_MMAP);
+    tbl_add[TBL_MMAP].size = sizeof(EFI_MEMORY_DESCRIPTOR)
+                             * (mem->nr_banks + acpi_mem.nr_banks + TBL_MMAX);

xen/common/efi/boot.c void __init acpi_create_efi_system_table(paddr_t paddr, void *efi_acpi_table,

Quoted 10 lines
xen/common/efi/boot.c +10 -0
+
+    base_ptr = efi_acpi_table + acpi_get_table_offset(tbl_add, TBL_MMAP);
+    memory_map = (EFI_MEMORY_DESCRIPTOR *)(base_ptr);
+
+    offset = 0;
+    for( i = 0; i < mem->nr_banks; i++, offset++ )
+    {
+        memory_map[offset].Type = EfiConventionalMemory;
+        memory_map[offset].PhysicalStart = mem->bank[i].start;
+        memory_map[offset].NumberOfPages = mem->bank[i].size/PAGE_SIZE;

Use PAGE_SHIFT throughout the function.

Quoted 8 lines
xen/common/efi/boot.c +8 -0
+        memory_map[offset].Attribute = EFI_MEMORY_WB;
+    }
+
+    for( i = 0; i < acpi_mem.nr_banks; i++, offset++ )
+    {
+        memory_map[offset].Type = EfiACPIReclaimMemory;
+        memory_map[offset].PhysicalStart = acpi_mem.bank[i].start;
+        memory_map[offset].NumberOfPages = acpi_mem.bank[i].size/PAGE_SIZE;

xen/common/efi/boot.c void __init acpi_create_efi_system_table(paddr_t paddr, void *efi_acpi_table, · line 1297

Quoted 10 lines
xen/common/efi/boot.c +10 -0
+        memory_map[offset].Attribute = EFI_MEMORY_WB;
+    }
+
+    for( i = 0; i < TBL_EFIT; i++, offset++ )
+    {
+        memory_map[offset].Type = EfiACPIReclaimMemory;
+        memory_map[offset].PhysicalStart = tbl_add[i].start;
+        memory_map[offset].NumberOfPages =tbl_add[i].size/PAGE_SIZE;
+        memory_map[offset].Attribute = EFI_MEMORY_WB;
+    }

Can't we just use a single EFI_MEMORY_DESCRIPTOR (or maybe 2, to cover EfiACPIReclaimMemory and EfiReservedMemoryType regions) to describe the whole efi_acpi_gpa region? Using one EFI_MEMORY_DESCRIPTOR per table, and PAGE_ALIGNing each of them, looks like a waste of memory to me. Unless it's an ACPI or EFI spec requirement.

Quoted 29 lines
xen/common/efi/boot.c +8 -0
+    for( i = TBL_EFIT; i < TBL_MMAX; i++, offset++ )
+    {
+        memory_map[offset].Type = EfiReservedMemoryType;
+        memory_map[offset].PhysicalStart = tbl_add[i].start;
+        memory_map[offset].NumberOfPages =tbl_add[i].size/PAGE_SIZE;
+        memory_map[offset].Attribute = EFI_MEMORY_WB;
+    }
+}
 #endif
 
 #ifndef CONFIG_ARM /* TODO - runtime service support */
xen/include/asm-arm/setup.h +4 -0
index 2d65796..35447ee 100644
@@ -56,6 +56,10 @@ int estimate_efi_size(int mem_nr_banks);
 void acpi_create_efi_system_table(paddr_t paddr, void *efi_acpi_table,
                                   struct membank tbl_add[]);
 
+void acpi_create_efi_mmap_table(paddr_t paddr, void *efi_acpi_table,
+                                const struct meminfo *mem,
+                                struct membank tbl_add[]);
+
 int construct_dom0(struct domain *d);
 
 void discard_initial_modules(void);
Signature · 1 line
2.1.0
#277 lore raw

PATCH v3 53/62 arm/acpi: Map the new created EFI and ACPI tables to Dom0

In reply to shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Here we map these new created EFI and ACPI tables to the non-RAM space of Dom0. Then Dom0 could visit them.

---
 xen/arch/arm/domain_build.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
xen/arch/arm/domain_build.c +15 -0
index 073c634..55f85b4 100644
@@ -1740,6 +1740,21 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
     acpi_create_efi_mmap_table(d->arch.efi_acpi_gpa, d->arch.efi_acpi_table,
                                &kinfo->mem, tbl_add);
 
+    /* Map the EFI and ACPI tables to Dom0 */
+    rc = map_regions(d,
+                     paddr_to_pfn(d->arch.efi_acpi_gpa),
+                     DIV_ROUND_UP(d->arch.efi_acpi_len, PAGE_SIZE),
+                     paddr_to_pfn(virt_to_maddr(d->arch.efi_acpi_table)));
+    if ( rc != 0 )
+    {
+        printk(XENLOG_ERR "Unable to map 0x%"PRIx64
+               " - 0x%"PRIx64" in domain %d\n",
+               d->arch.efi_acpi_gpa & PAGE_MASK,
+               PAGE_ALIGN(d->arch.efi_acpi_gpa + d->arch.efi_acpi_len) - 1,
+               d->domain_id);
+        return rc;
+    }
+
     return 0;
 }
 #else
Signature · 1 line
2.1.0
#278 lore raw

PATCH v3 53/62 arm/acpi: Map the new created EFI and ACPI tables to Dom0

Quoted 4 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Here we map these new created EFI and ACPI tables to the non-RAM space of Dom0. Then Dom0 could visit them.

"Map the UEFI and ACPI tables which we created to non-RAM space in Dom0."

Quoted 10 lines
---
 xen/arch/arm/domain_build.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
xen/arch/arm/domain_build.c +0 -0
index 073c634..55f85b4 100644

xen/arch/arm/domain_build.c static int prepare_acpi(struct domain *d, struct kernel_info *kinfo) · line 1746

Quoted 7 lines
xen/arch/arm/domain_build.c +4 -0
@@ -1740,6 +1740,21 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
     acpi_create_efi_mmap_table(d->arch.efi_acpi_gpa, d->arch.efi_acpi_table,
                                &kinfo->mem, tbl_add);
 
+    /* Map the EFI and ACPI tables to Dom0 */
+    rc = map_regions(d,
+                     paddr_to_pfn(d->arch.efi_acpi_gpa),
+                     DIV_ROUND_UP(d->arch.efi_acpi_len, PAGE_SIZE),

PFN_UP

Quoted 17 lines
xen/arch/arm/domain_build.c +11 -0
+                     paddr_to_pfn(virt_to_maddr(d->arch.efi_acpi_table)));
+    if ( rc != 0 )
+    {
+        printk(XENLOG_ERR "Unable to map 0x%"PRIx64
+               " - 0x%"PRIx64" in domain %d\n",
+               d->arch.efi_acpi_gpa & PAGE_MASK,
+               PAGE_ALIGN(d->arch.efi_acpi_gpa + d->arch.efi_acpi_len) - 1,
+               d->domain_id);
+        return rc;
+    }
+
     return 0;
 }
 #else
Signature · 1 line
2.1.0
#279 lore raw

Re: [PATCH v3 53/62] arm/acpi: Map the new created EFI and ACPI tables to Dom0

In reply to shannon.zhao at linaro.org
Quoted 4 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Shannon Zhao <[email protected]>

Here we map these new created EFI and ACPI tables to the non-RAM space of Dom0. Then Dom0 could visit them.

"Map the UEFI and ACPI tables which we created to non-RAM space in Dom0."

Quoted 10 lines
---
 xen/arch/arm/domain_build.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
xen/arch/arm/domain_build.c +0 -0
index 073c634..55f85b4 100644

xen/arch/arm/domain_build.c static int prepare_acpi(struct domain *d, struct kernel_info *kinfo) · line 1746

Quoted 7 lines
xen/arch/arm/domain_build.c +4 -0
@@ -1740,6 +1740,21 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
     acpi_create_efi_mmap_table(d->arch.efi_acpi_gpa, d->arch.efi_acpi_table,
                                &kinfo->mem, tbl_add);
 
+    /* Map the EFI and ACPI tables to Dom0 */
+    rc = map_regions(d,
+                     paddr_to_pfn(d->arch.efi_acpi_gpa),
+                     DIV_ROUND_UP(d->arch.efi_acpi_len, PAGE_SIZE),

PFN_UP

Quoted 17 lines
xen/arch/arm/domain_build.c +11 -0
+                     paddr_to_pfn(virt_to_maddr(d->arch.efi_acpi_table)));
+    if ( rc != 0 )
+    {
+        printk(XENLOG_ERR "Unable to map 0x%"PRIx64
+               " - 0x%"PRIx64" in domain %d\n",
+               d->arch.efi_acpi_gpa & PAGE_MASK,
+               PAGE_ALIGN(d->arch.efi_acpi_gpa + d->arch.efi_acpi_len) - 1,
+               d->domain_id);
+        return rc;
+    }
+
     return 0;
 }
 #else
Signature · 1 line
2.1.0
#280 lore raw

PATCH v3 54/62 arm/acpi: Create min DT stub for Dom0

In reply to shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Create a DT for Dom0 for ACPI-case only. DT contains minimal required informations such as Dom0 bootargs, initrd, efi description table and address of uefi memory table.

---
 xen/arch/arm/domain_build.c | 142 ++++++++++++++++++++++++++++++++++++++++++++
 xen/common/efi/boot.c       |  47 +++++++++++++++
 xen/include/asm-arm/setup.h |   2 +
 3 files changed, 191 insertions(+)
xen/arch/arm/domain_build.c +142 -0
index 55f85b4..6d8536b 100644
@@ -1358,6 +1358,144 @@ static int prepare_dtb(struct domain *d, struct kernel_info *kinfo)
 
 #ifdef CONFIG_ACPI
 #define XEN_HYPERVISOR_ID 0x000058656E564D4D  /* "XenVMM" */
+#define ACPI_DOM0_FDT_MIN_SIZE 4096
+
+static int make_chosen_node(const struct kernel_info *kinfo,
+                            struct membank tbl_add[])
+{
+    int res;
+    const char *bootargs = NULL;
+    const struct bootmodule *mod = kinfo->kernel_bootmodule;
+    void *fdt = kinfo->fdt;
+
+    DPRINT("Create chosen node\n");
+    res = fdt_begin_node(fdt, "chosen");
+    if ( res )
+        return res;
+
+    if ( mod && mod->cmdline[0] )
+    {
+        bootargs = &mod->cmdline[0];
+        res = fdt_property(fdt, "bootargs", bootargs, strlen(bootargs) + 1);
+        if ( res )
+           return res;
+    }
+
+    /*
+     * If the bootloader provides an initrd, we must create a placeholder
+     * for the initrd properties. The values will be replaced later.
+     */
+    if ( mod && mod->size )
+    {
+        u64 a = 0;
+        res = fdt_property(kinfo->fdt, "linux,initrd-start", &a, sizeof(a));
+        if ( res )
+            return res;
+
+        res = fdt_property(kinfo->fdt, "linux,initrd-end", &a, sizeof(a));
+        if ( res )
+            return res;
+    }
+
+    res = fdt_end_node(fdt);
+
+    return res;
+}
+
+static int acpi_make_hypervisor_node(const struct kernel_info *kinfo,
+                                     struct membank tbl_add[])
+{
+    const char compat[] =
+        "xen,xen-"__stringify(XEN_VERSION)"."__stringify(XEN_SUBVERSION)"\0"
+        "xen,xen";
+    int res;
+    /* Convenience alias */
+    void *fdt = kinfo->fdt;
+
+    DPRINT("Create hypervisor node\n");
+
+    /* See linux Documentation/devicetree/bindings/arm/xen.txt */
+    res = fdt_begin_node(fdt, "hypervisor");
+    if ( res )
+        return res;
+
+    /* Cannot use fdt_property_string due to embedded nulls */
+    res = fdt_property(fdt, "compatible", compat, sizeof(compat));
+    if ( res )
+        return res;
+
+    res = arm_acpi_make_efi_nodes(fdt, tbl_add);
+    if ( res )
+        return res;
+
+    res = fdt_end_node(fdt);
+
+    return res;
+}
+
+/*
+ * Prepare a minimal DTB for Dom0 which contains bootargs, initrd, memory
+ * information, EFI table.
+ */
+static int create_acpi_dtb(struct kernel_info *kinfo, struct membank tbl_add[])
+{
+    int new_size;
+    int ret;
+
+    DPRINT("Prepare a min DTB for DOM0\n");
+
+    /* Allocate min size for DT */
+    new_size = ACPI_DOM0_FDT_MIN_SIZE;
+    kinfo->fdt = xmalloc_bytes(new_size);
+
+    if ( kinfo->fdt == NULL )
+        return -ENOMEM;
+
+    /* Create a new empty DT for DOM0 */
+    ret = fdt_create(kinfo->fdt, new_size);
+    if ( ret < 0 )
+        goto err;
+
+    ret = fdt_finish_reservemap(kinfo->fdt);
+    if ( ret < 0 )
+        goto err;
+
+    ret = fdt_begin_node(kinfo->fdt, "/");
+    if ( ret < 0 )
+        goto err;
+
+    ret = fdt_property_cell(kinfo->fdt, "#address-cells", 2);
+    if ( ret )
+        return ret;
+
+    ret = fdt_property_cell(kinfo->fdt, "#size-cells", 1);
+    if ( ret )
+        return ret;
+
+    /* Create a chosen node for DOM0 */
+    ret = make_chosen_node(kinfo, tbl_add);
+    if ( ret )
+        goto err;
+
+    ret = acpi_make_hypervisor_node(kinfo, tbl_add);
+    if ( ret )
+        goto err;
+
+    ret = fdt_end_node(kinfo->fdt);
+    if ( ret < 0 )
+        goto err;
+
+    ret = fdt_finish(kinfo->fdt);
+    if ( ret < 0 )
+        goto err;
+
+    return 0;
+
+  err:
+    printk("Device tree generation failed (%d).\n", ret);
+    xfree(kinfo->fdt);
+    return -EINVAL;
+}
 
 static void acpi_map_rest_tables(struct domain *d)
 {
@@ -1755,6 +1893,10 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
         return rc;
     }
 
+    rc = create_acpi_dtb(kinfo, tbl_add);
+    if ( rc != 0 )
+        return rc;
+
     return 0;
 }
 #else
xen/common/efi/boot.c +47 -0

53 lines not on this page · raw message

xen/include/asm-arm/setup.h +2 -0
index 35447ee..c4cf5ea 100644
@@ -60,6 +60,8 @@ void acpi_create_efi_mmap_table(paddr_t paddr, void *efi_acpi_table,
                                 const struct meminfo *mem,
                                 struct membank tbl_add[]);
 
+int arm_acpi_make_efi_nodes(void *fdt, struct membank tbl_add[]);
+
 int construct_dom0(struct domain *d);
 
 void discard_initial_modules(void);
Signature · 1 line
2.1.0
#281 lore raw

PATCH v3 54/62 arm/acpi: Create min DT stub for Dom0

Quoted 9 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Create a DT for Dom0 for ACPI-case only. DT contains minimal required informations such as Dom0 bootargs, initrd, efi description table and address of uefi memory table.

We should add a document under docs/misc/arm/device-tree for these bindings. This is an external interface maintained by Xen for compatibility.

Quoted 210 lines
 xen/arch/arm/domain_build.c | 142 ++++++++++++++++++++++++++++++++++++++++++++
 xen/common/efi/boot.c       |  47 +++++++++++++++
 xen/include/asm-arm/setup.h |   2 +
 3 files changed, 191 insertions(+)
xen/arch/arm/domain_build.c +142 -0
index 55f85b4..6d8536b 100644
@@ -1358,6 +1358,144 @@ static int prepare_dtb(struct domain *d, struct kernel_info *kinfo)
 
 #ifdef CONFIG_ACPI
 #define XEN_HYPERVISOR_ID 0x000058656E564D4D  /* "XenVMM" */
+#define ACPI_DOM0_FDT_MIN_SIZE 4096
+
+static int make_chosen_node(const struct kernel_info *kinfo,
+                            struct membank tbl_add[])
+{
+    int res;
+    const char *bootargs = NULL;
+    const struct bootmodule *mod = kinfo->kernel_bootmodule;
+    void *fdt = kinfo->fdt;
+
+    DPRINT("Create chosen node\n");
+    res = fdt_begin_node(fdt, "chosen");
+    if ( res )
+        return res;
+
+    if ( mod && mod->cmdline[0] )
+    {
+        bootargs = &mod->cmdline[0];
+        res = fdt_property(fdt, "bootargs", bootargs, strlen(bootargs) + 1);
+        if ( res )
+           return res;
+    }
+
+    /*
+     * If the bootloader provides an initrd, we must create a placeholder
+     * for the initrd properties. The values will be replaced later.
+     */
+    if ( mod && mod->size )
+    {
+        u64 a = 0;
+        res = fdt_property(kinfo->fdt, "linux,initrd-start", &a, sizeof(a));
+        if ( res )
+            return res;
+
+        res = fdt_property(kinfo->fdt, "linux,initrd-end", &a, sizeof(a));
+        if ( res )
+            return res;
+    }
+
+    res = fdt_end_node(fdt);
+
+    return res;
+}
+
+static int acpi_make_hypervisor_node(const struct kernel_info *kinfo,
+                                     struct membank tbl_add[])
+{
+    const char compat[] =
+        "xen,xen-"__stringify(XEN_VERSION)"."__stringify(XEN_SUBVERSION)"\0"
+        "xen,xen";
+    int res;
+    /* Convenience alias */
+    void *fdt = kinfo->fdt;
+
+    DPRINT("Create hypervisor node\n");
+
+    /* See linux Documentation/devicetree/bindings/arm/xen.txt */
+    res = fdt_begin_node(fdt, "hypervisor");
+    if ( res )
+        return res;
+
+    /* Cannot use fdt_property_string due to embedded nulls */
+    res = fdt_property(fdt, "compatible", compat, sizeof(compat));
+    if ( res )
+        return res;
+
+    res = arm_acpi_make_efi_nodes(fdt, tbl_add);
+    if ( res )
+        return res;
+
+    res = fdt_end_node(fdt);
+
+    return res;
+}
+
+/*
+ * Prepare a minimal DTB for Dom0 which contains bootargs, initrd, memory
+ * information, EFI table.
+ */
+static int create_acpi_dtb(struct kernel_info *kinfo, struct membank tbl_add[])
+{
+    int new_size;
+    int ret;
+
+    DPRINT("Prepare a min DTB for DOM0\n");
+
+    /* Allocate min size for DT */
+    new_size = ACPI_DOM0_FDT_MIN_SIZE;
+    kinfo->fdt = xmalloc_bytes(new_size);
+
+    if ( kinfo->fdt == NULL )
+        return -ENOMEM;
+
+    /* Create a new empty DT for DOM0 */
+    ret = fdt_create(kinfo->fdt, new_size);
+    if ( ret < 0 )
+        goto err;
+
+    ret = fdt_finish_reservemap(kinfo->fdt);
+    if ( ret < 0 )
+        goto err;
+
+    ret = fdt_begin_node(kinfo->fdt, "/");
+    if ( ret < 0 )
+        goto err;
+
+    ret = fdt_property_cell(kinfo->fdt, "#address-cells", 2);
+    if ( ret )
+        return ret;
+
+    ret = fdt_property_cell(kinfo->fdt, "#size-cells", 1);
+    if ( ret )
+        return ret;
+
+    /* Create a chosen node for DOM0 */
+    ret = make_chosen_node(kinfo, tbl_add);
+    if ( ret )
+        goto err;
+
+    ret = acpi_make_hypervisor_node(kinfo, tbl_add);
+    if ( ret )
+        goto err;
+
+    ret = fdt_end_node(kinfo->fdt);
+    if ( ret < 0 )
+        goto err;
+
+    ret = fdt_finish(kinfo->fdt);
+    if ( ret < 0 )
+        goto err;
+
+    return 0;
+
+  err:
+    printk("Device tree generation failed (%d).\n", ret);
+    xfree(kinfo->fdt);
+    return -EINVAL;
+}
 
 static void acpi_map_rest_tables(struct domain *d)
 {
@@ -1755,6 +1893,10 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
         return rc;
     }
 
+    rc = create_acpi_dtb(kinfo, tbl_add);
+    if ( rc != 0 )
+        return rc;
+
     return 0;
 }
 #else
xen/common/efi/boot.c +37 -0
index ff2faed..d233cef 100644
@@ -1304,6 +1304,53 @@ void __init acpi_create_efi_mmap_table(paddr_t paddr, void *efi_acpi_table,
         memory_map[offset].Attribute = EFI_MEMORY_WB;
     }
 }
+
+/* Create place holder for efi values. */
+int __init arm_acpi_make_efi_nodes(void *fdt, struct membank tbl_add[])
+{
+    u64 fdt_val64;
+    u32 fdt_val32;
+    int desc_ver = mdesc_ver;
+    int res;
+
+    res = fdt_begin_node(fdt, "uefi");
+    if ( res )
+        return res;
+
+    fdt_val64 = cpu_to_fdt64(tbl_add[TBL_EFIT].start);
+    res = fdt_property(fdt, "xen,uefi-system-table",
+                       &fdt_val64, sizeof(fdt_val64));
+    if ( res )
+        return res;
+
+    fdt_val64 = cpu_to_fdt64(tbl_add[TBL_MMAP].start);
+    res = fdt_property(fdt, "xen,uefi-mmap-start",
+                       &fdt_val64,  sizeof(fdt_val64));
+    if ( res )
+        return res;
+
+    fdt_val32 = cpu_to_fdt32(tbl_add[TBL_MMAP].size);
+    res = fdt_property(fdt, "xen,uefi-mmap-size",
+                       &fdt_val32,  sizeof(fdt_val32));
+    if ( res )
+        return res;
+
+    fdt_val32 = cpu_to_fdt32(sizeof(EFI_MEMORY_DESCRIPTOR));
+    res = fdt_property(fdt, "xen,uefi-mmap-desc-size",
+                         &fdt_val32, sizeof(fdt_val32));
+    if ( res )
+        return res;
+

xen/common/efi/boot.c void __init acpi_create_efi_mmap_table(paddr_t paddr, void *efi_acpi_table, · line 1353

Quoted 10 lines
xen/common/efi/boot.c +10 -0
+    fdt_val32 = cpu_to_fdt32(desc_ver);
+    res = fdt_property(fdt, "xen,uefi-mmap-desc-ver",
+                         &fdt_val32, sizeof(fdt_val32));
+    if ( res )
+        return res;
+
+    res = fdt_end_node(fdt);
+
+    return res;
+}

This function shouldn't be in this file.

Quoted 25 lines
xen/common/efi/boot.c +0 -0
 #endif
 
 #ifndef CONFIG_ARM /* TODO - runtime service support */
xen/include/asm-arm/setup.h +2 -0
index 35447ee..c4cf5ea 100644
@@ -60,6 +60,8 @@ void acpi_create_efi_mmap_table(paddr_t paddr, void *efi_acpi_table,
                                 const struct meminfo *mem,
                                 struct membank tbl_add[]);
 
+int arm_acpi_make_efi_nodes(void *fdt, struct membank tbl_add[]);
+
 int construct_dom0(struct domain *d);
 
 void discard_initial_modules(void);
Signature · 7 lines
2.1.0


_______________________________________________
Xen-devel mailing list
Xen-devel at lists.xen.org
http://lists.xen.org/xen-devel
#282 lore raw

Re: [PATCH v3 54/62] arm/acpi: Create min DT stub for Dom0

In reply to shannon.zhao at linaro.org
Quoted 9 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Shannon Zhao <[email protected]>

Create a DT for Dom0 for ACPI-case only. DT contains minimal required informations such as Dom0 bootargs, initrd, efi description table and address of uefi memory table.

We should add a document under docs/misc/arm/device-tree for these bindings. This is an external interface maintained by Xen for compatibility.

Quoted 210 lines
 xen/arch/arm/domain_build.c | 142 ++++++++++++++++++++++++++++++++++++++++++++
 xen/common/efi/boot.c       |  47 +++++++++++++++
 xen/include/asm-arm/setup.h |   2 +
 3 files changed, 191 insertions(+)
xen/arch/arm/domain_build.c +142 -0
index 55f85b4..6d8536b 100644
@@ -1358,6 +1358,144 @@ static int prepare_dtb(struct domain *d, struct kernel_info *kinfo)
 
 #ifdef CONFIG_ACPI
 #define XEN_HYPERVISOR_ID 0x000058656E564D4D  /* "XenVMM" */
+#define ACPI_DOM0_FDT_MIN_SIZE 4096
+
+static int make_chosen_node(const struct kernel_info *kinfo,
+                            struct membank tbl_add[])
+{
+    int res;
+    const char *bootargs = NULL;
+    const struct bootmodule *mod = kinfo->kernel_bootmodule;
+    void *fdt = kinfo->fdt;
+
+    DPRINT("Create chosen node\n");
+    res = fdt_begin_node(fdt, "chosen");
+    if ( res )
+        return res;
+
+    if ( mod && mod->cmdline[0] )
+    {
+        bootargs = &mod->cmdline[0];
+        res = fdt_property(fdt, "bootargs", bootargs, strlen(bootargs) + 1);
+        if ( res )
+           return res;
+    }
+
+    /*
+     * If the bootloader provides an initrd, we must create a placeholder
+     * for the initrd properties. The values will be replaced later.
+     */
+    if ( mod && mod->size )
+    {
+        u64 a = 0;
+        res = fdt_property(kinfo->fdt, "linux,initrd-start", &a, sizeof(a));
+        if ( res )
+            return res;
+
+        res = fdt_property(kinfo->fdt, "linux,initrd-end", &a, sizeof(a));
+        if ( res )
+            return res;
+    }
+
+    res = fdt_end_node(fdt);
+
+    return res;
+}
+
+static int acpi_make_hypervisor_node(const struct kernel_info *kinfo,
+                                     struct membank tbl_add[])
+{
+    const char compat[] =
+        "xen,xen-"__stringify(XEN_VERSION)"."__stringify(XEN_SUBVERSION)"\0"
+        "xen,xen";
+    int res;
+    /* Convenience alias */
+    void *fdt = kinfo->fdt;
+
+    DPRINT("Create hypervisor node\n");
+
+    /* See linux Documentation/devicetree/bindings/arm/xen.txt */
+    res = fdt_begin_node(fdt, "hypervisor");
+    if ( res )
+        return res;
+
+    /* Cannot use fdt_property_string due to embedded nulls */
+    res = fdt_property(fdt, "compatible", compat, sizeof(compat));
+    if ( res )
+        return res;
+
+    res = arm_acpi_make_efi_nodes(fdt, tbl_add);
+    if ( res )
+        return res;
+
+    res = fdt_end_node(fdt);
+
+    return res;
+}
+
+/*
+ * Prepare a minimal DTB for Dom0 which contains bootargs, initrd, memory
+ * information, EFI table.
+ */
+static int create_acpi_dtb(struct kernel_info *kinfo, struct membank tbl_add[])
+{
+    int new_size;
+    int ret;
+
+    DPRINT("Prepare a min DTB for DOM0\n");
+
+    /* Allocate min size for DT */
+    new_size = ACPI_DOM0_FDT_MIN_SIZE;
+    kinfo->fdt = xmalloc_bytes(new_size);
+
+    if ( kinfo->fdt == NULL )
+        return -ENOMEM;
+
+    /* Create a new empty DT for DOM0 */
+    ret = fdt_create(kinfo->fdt, new_size);
+    if ( ret < 0 )
+        goto err;
+
+    ret = fdt_finish_reservemap(kinfo->fdt);
+    if ( ret < 0 )
+        goto err;
+
+    ret = fdt_begin_node(kinfo->fdt, "/");
+    if ( ret < 0 )
+        goto err;
+
+    ret = fdt_property_cell(kinfo->fdt, "#address-cells", 2);
+    if ( ret )
+        return ret;
+
+    ret = fdt_property_cell(kinfo->fdt, "#size-cells", 1);
+    if ( ret )
+        return ret;
+
+    /* Create a chosen node for DOM0 */
+    ret = make_chosen_node(kinfo, tbl_add);
+    if ( ret )
+        goto err;
+
+    ret = acpi_make_hypervisor_node(kinfo, tbl_add);
+    if ( ret )
+        goto err;
+
+    ret = fdt_end_node(kinfo->fdt);
+    if ( ret < 0 )
+        goto err;
+
+    ret = fdt_finish(kinfo->fdt);
+    if ( ret < 0 )
+        goto err;
+
+    return 0;
+
+  err:
+    printk("Device tree generation failed (%d).\n", ret);
+    xfree(kinfo->fdt);
+    return -EINVAL;
+}
 
 static void acpi_map_rest_tables(struct domain *d)
 {
@@ -1755,6 +1893,10 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
         return rc;
     }
 
+    rc = create_acpi_dtb(kinfo, tbl_add);
+    if ( rc != 0 )
+        return rc;
+
     return 0;
 }
 #else
xen/common/efi/boot.c +37 -0
index ff2faed..d233cef 100644
@@ -1304,6 +1304,53 @@ void __init acpi_create_efi_mmap_table(paddr_t paddr, void *efi_acpi_table,
         memory_map[offset].Attribute = EFI_MEMORY_WB;
     }
 }
+
+/* Create place holder for efi values. */
+int __init arm_acpi_make_efi_nodes(void *fdt, struct membank tbl_add[])
+{
+    u64 fdt_val64;
+    u32 fdt_val32;
+    int desc_ver = mdesc_ver;
+    int res;
+
+    res = fdt_begin_node(fdt, "uefi");
+    if ( res )
+        return res;
+
+    fdt_val64 = cpu_to_fdt64(tbl_add[TBL_EFIT].start);
+    res = fdt_property(fdt, "xen,uefi-system-table",
+                       &fdt_val64, sizeof(fdt_val64));
+    if ( res )
+        return res;
+
+    fdt_val64 = cpu_to_fdt64(tbl_add[TBL_MMAP].start);
+    res = fdt_property(fdt, "xen,uefi-mmap-start",
+                       &fdt_val64,  sizeof(fdt_val64));
+    if ( res )
+        return res;
+
+    fdt_val32 = cpu_to_fdt32(tbl_add[TBL_MMAP].size);
+    res = fdt_property(fdt, "xen,uefi-mmap-size",
+                       &fdt_val32,  sizeof(fdt_val32));
+    if ( res )
+        return res;
+
+    fdt_val32 = cpu_to_fdt32(sizeof(EFI_MEMORY_DESCRIPTOR));
+    res = fdt_property(fdt, "xen,uefi-mmap-desc-size",
+                         &fdt_val32, sizeof(fdt_val32));
+    if ( res )
+        return res;
+

xen/common/efi/boot.c void __init acpi_create_efi_mmap_table(paddr_t paddr, void *efi_acpi_table, · line 1353

Quoted 10 lines
xen/common/efi/boot.c +10 -0
+    fdt_val32 = cpu_to_fdt32(desc_ver);
+    res = fdt_property(fdt, "xen,uefi-mmap-desc-ver",
+                         &fdt_val32, sizeof(fdt_val32));
+    if ( res )
+        return res;
+
+    res = fdt_end_node(fdt);
+
+    return res;
+}

This function shouldn't be in this file.

Quoted 25 lines
xen/common/efi/boot.c +0 -0
 #endif
 
 #ifndef CONFIG_ARM /* TODO - runtime service support */
xen/include/asm-arm/setup.h +2 -0
index 35447ee..c4cf5ea 100644
@@ -60,6 +60,8 @@ void acpi_create_efi_mmap_table(paddr_t paddr, void *efi_acpi_table,
                                 const struct meminfo *mem,
                                 struct membank tbl_add[]);
 
+int arm_acpi_make_efi_nodes(void *fdt, struct membank tbl_add[]);
+
 int construct_dom0(struct domain *d);
 
 void discard_initial_modules(void);
Signature · 7 lines
2.1.0


_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
#283 lore raw

PATCH v3 55/62 arm/acpi: Route all Xen unused SPIs to Dom0

In reply to shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Route all SPIs to Dom0 except the interrupts that Xen uses. Since Xen already uses the uart interrupt, the desc->action will not be NULL, so it will skip it.

---
 xen/arch/arm/domain_build.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)
xen/arch/arm/domain_build.c +33 -0
index 6d8536b..6945f89 100644
@@ -1360,6 +1360,35 @@ static int prepare_dtb(struct domain *d, struct kernel_info *kinfo)
 #define XEN_HYPERVISOR_ID 0x000058656E564D4D  /* "XenVMM" */
 #define ACPI_DOM0_FDT_MIN_SIZE 4096
 
+static int acpi_route_spi(struct domain *d)
+{
+    int i, res;
+    struct irq_desc *desc;
+
+    /* Don't route Xen used interrupt to Dom0. Since Xen already uses the uart
+     * interrupt, the desc->action will not be NULL, so it will skip it.
+     */
+    for( i = NR_LOCAL_IRQS; i < vgic_num_irqs(d); i++ )
+    {
+        /* Don't route uart interrupt to Dom0 */
+        desc = irq_to_desc(i);
+        if( desc->action != NULL)
+            continue;
+
+        vgic_reserve_virq(d, i);
+        irq_set_type(i, ACPI_IRQ_TYPE_NONE);
+        res = route_irq_to_guest(d, i, i, NULL);
+        if ( res )
+        {
+            printk(XENLOG_ERR "Unable to route IRQ %u to domain %u\n",
+                   i, d->domain_id);
+            continue;
+        }
+    }
+
+    return 0;
+}
+
 static int make_chosen_node(const struct kernel_info *kinfo,
                             struct membank tbl_add[])
 {
@@ -1897,6 +1926,10 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
     if ( rc != 0 )
         return rc;
 
+    rc = acpi_route_spi(d);
+    if ( rc != 0 )
+        return rc;
+
     return 0;
 }
 #else
Signature · 1 line
2.1.0
#284 lore raw

PATCH v3 55/62 arm/acpi: Route all Xen unused SPIs to Dom0

Hi Shannon,

Quoted 20 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Route all SPIs to Dom0 except the interrupts that Xen uses. Since Xen already uses the uart interrupt, the desc->action will not be NULL, so it will skip it.

---
 xen/arch/arm/domain_build.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)
xen/arch/arm/domain_build.c +1 -0
index 6d8536b..6945f89 100644
@@ -1360,6 +1360,35 @@ static int prepare_dtb(struct domain *d, struct kernel_info *kinfo)
 #define XEN_HYPERVISOR_ID 0x000058656E564D4D  /* "XenVMM" */
 #define ACPI_DOM0_FDT_MIN_SIZE 4096
 
+static int acpi_route_spi(struct domain *d)

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1373

Quoted 10 lines
xen/arch/arm/domain_build.c +10 -0
+{
+    int i, res;
+    struct irq_desc *desc;
+
+    /* Don't route Xen used interrupt to Dom0. Since Xen already uses the uart
+     * interrupt, the desc->action will not be NULL, so it will skip it.
+     */
+    for( i = NR_LOCAL_IRQS; i < vgic_num_irqs(d); i++ )
+    {
+        /* Don't route uart interrupt to Dom0 */

Your comments are wrong. desc->action != NULL means Xen is using the interrupt. It could be for the SMMU, the UART...

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1375

Quoted 2 lines
xen/arch/arm/domain_build.c +2 -0
+        desc = irq_to_desc(i);
+        if( desc->action != NULL)

Coding style.

Quoted 6 lines
xen/arch/arm/domain_build.c +6 -0
+            continue;
+
+        vgic_reserve_virq(d, i);
+        irq_set_type(i, ACPI_IRQ_TYPE_NONE);
+        res = route_irq_to_guest(d, i, i, NULL);
+        if ( res )

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1391

Quoted 10 lines
xen/arch/arm/domain_build.c +10 -0
+        {
+            printk(XENLOG_ERR "Unable to route IRQ %u to domain %u\n",
+                   i, d->domain_id);
+            continue;
+        }
+    }
+
+    return 0;
+}
+

Regards,

Signature · 1 line
Julien Grall
#285 lore raw

Re: [PATCH v3 55/62] arm/acpi: Route all Xen unused SPIs to Dom0

In reply to shannon.zhao at linaro.org

Hi Shannon,

Quoted 20 lines · On 17/11/15 09:40, [email protected] wrote:

From: Shannon Zhao <[email protected]>

Route all SPIs to Dom0 except the interrupts that Xen uses. Since Xen already uses the uart interrupt, the desc->action will not be NULL, so it will skip it.

---
 xen/arch/arm/domain_build.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)
xen/arch/arm/domain_build.c +1 -0
index 6d8536b..6945f89 100644
@@ -1360,6 +1360,35 @@ static int prepare_dtb(struct domain *d, struct kernel_info *kinfo)
 #define XEN_HYPERVISOR_ID 0x000058656E564D4D  /* "XenVMM" */
 #define ACPI_DOM0_FDT_MIN_SIZE 4096
 
+static int acpi_route_spi(struct domain *d)

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1373

Quoted 10 lines
xen/arch/arm/domain_build.c +10 -0
+{
+    int i, res;
+    struct irq_desc *desc;
+
+    /* Don't route Xen used interrupt to Dom0. Since Xen already uses the uart
+     * interrupt, the desc->action will not be NULL, so it will skip it.
+     */
+    for( i = NR_LOCAL_IRQS; i < vgic_num_irqs(d); i++ )
+    {
+        /* Don't route uart interrupt to Dom0 */

Your comments are wrong. desc->action != NULL means Xen is using the interrupt. It could be for the SMMU, the UART...

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1375

Quoted 2 lines
xen/arch/arm/domain_build.c +2 -0
+        desc = irq_to_desc(i);
+        if( desc->action != NULL)

Coding style.

Quoted 6 lines
xen/arch/arm/domain_build.c +6 -0
+            continue;
+
+        vgic_reserve_virq(d, i);
+        irq_set_type(i, ACPI_IRQ_TYPE_NONE);
+        res = route_irq_to_guest(d, i, i, NULL);
+        if ( res )

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1391

Quoted 10 lines
xen/arch/arm/domain_build.c +10 -0
+        {
+            printk(XENLOG_ERR "Unable to route IRQ %u to domain %u\n",
+                   i, d->domain_id);
+            continue;
+        }
+    }
+
+    return 0;
+}
+

Regards,

Signature · 1 line
Julien Grall
#286 lore raw

PATCH v3 55/62 arm/acpi: Route all Xen unused SPIs to Dom0

In reply to shannon.zhao at linaro.org
Quoted 23 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Route all SPIs to Dom0 except the interrupts that Xen uses. Since Xen already uses the uart interrupt, the desc->action will not be NULL, so it will skip it.

---
 xen/arch/arm/domain_build.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)
xen/arch/arm/domain_build.c +4 -0
index 6d8536b..6945f89 100644
@@ -1360,6 +1360,35 @@ static int prepare_dtb(struct domain *d, struct kernel_info *kinfo)
 #define XEN_HYPERVISOR_ID 0x000058656E564D4D  /* "XenVMM" */
 #define ACPI_DOM0_FDT_MIN_SIZE 4096
 
+static int acpi_route_spi(struct domain *d)
+{
+    int i, res;
+    struct irq_desc *desc;

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1376

Quoted 10 lines
xen/arch/arm/domain_build.c +10 -0
+
+    /* Don't route Xen used interrupt to Dom0. Since Xen already uses the uart
+     * interrupt, the desc->action will not be NULL, so it will skip it.
+     */
+    for( i = NR_LOCAL_IRQS; i < vgic_num_irqs(d); i++ )
+    {
+        /* Don't route uart interrupt to Dom0 */
+        desc = irq_to_desc(i);
+        if( desc->action != NULL)
+            continue;

Don't you need to call irq_permit_access too?

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1379

Quoted 2 lines
xen/arch/arm/domain_build.c +2 -0
+        vgic_reserve_virq(d, i);
+        irq_set_type(i, ACPI_IRQ_TYPE_NONE);

I don't know if there is any point in setting the type to NONE. It's the default, isn't it?

Quoted 29 lines
xen/arch/arm/domain_build.c +16 -0
+        res = route_irq_to_guest(d, i, i, NULL);
+        if ( res )
+        {
+            printk(XENLOG_ERR "Unable to route IRQ %u to domain %u\n",
+                   i, d->domain_id);
+            continue;
+        }
+    }
+
+    return 0;
+}
+
 static int make_chosen_node(const struct kernel_info *kinfo,
                             struct membank tbl_add[])
 {
@@ -1897,6 +1926,10 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
     if ( rc != 0 )
         return rc;
 
+    rc = acpi_route_spi(d);
+    if ( rc != 0 )
+        return rc;
+
     return 0;
 }
 #else
Signature · 1 line
2.1.0
#287 lore raw

PATCH v3 55/62 arm/acpi: Route all Xen unused SPIs to Dom0

Quoted 5 lines · Stefano Stabellini

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1379

Quoted 2 lines
xen/arch/arm/domain_build.c +2 -0
+        vgic_reserve_virq(d, i);
+        irq_set_type(i, ACPI_IRQ_TYPE_NONE);

I don't know if there is any point in setting the type to NONE. It's the default, isn't it?

No, the default is *_IRQ_TYPE_INVALID.

Regards,

Signature · 1 line
Julien Grall
#288 lore raw

Re: [PATCH v3 55/62] arm/acpi: Route all Xen unused SPIs to Dom0

In reply to Stefano Stabellini
Quoted 5 lines · Stefano Stabellini

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1379

Quoted 2 lines
xen/arch/arm/domain_build.c +2 -0
+        vgic_reserve_virq(d, i);
+        irq_set_type(i, ACPI_IRQ_TYPE_NONE);

I don't know if there is any point in setting the type to NONE. It's the default, isn't it?

No, the default is *_IRQ_TYPE_INVALID.

Regards,

Signature · 1 line
Julien Grall
#289 lore raw

Re: [PATCH v3 55/62] arm/acpi: Route all Xen unused SPIs to Dom0

In reply to shannon.zhao at linaro.org
Quoted 23 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Shannon Zhao <[email protected]>

Route all SPIs to Dom0 except the interrupts that Xen uses. Since Xen already uses the uart interrupt, the desc->action will not be NULL, so it will skip it.

---
 xen/arch/arm/domain_build.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)
xen/arch/arm/domain_build.c +4 -0
index 6d8536b..6945f89 100644
@@ -1360,6 +1360,35 @@ static int prepare_dtb(struct domain *d, struct kernel_info *kinfo)
 #define XEN_HYPERVISOR_ID 0x000058656E564D4D  /* "XenVMM" */
 #define ACPI_DOM0_FDT_MIN_SIZE 4096
 
+static int acpi_route_spi(struct domain *d)
+{
+    int i, res;
+    struct irq_desc *desc;

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1376

Quoted 10 lines
xen/arch/arm/domain_build.c +10 -0
+
+    /* Don't route Xen used interrupt to Dom0. Since Xen already uses the uart
+     * interrupt, the desc->action will not be NULL, so it will skip it.
+     */
+    for( i = NR_LOCAL_IRQS; i < vgic_num_irqs(d); i++ )
+    {
+        /* Don't route uart interrupt to Dom0 */
+        desc = irq_to_desc(i);
+        if( desc->action != NULL)
+            continue;

Don't you need to call irq_permit_access too?

xen/arch/arm/domain_build.c static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) · line 1379

Quoted 2 lines
xen/arch/arm/domain_build.c +2 -0
+        vgic_reserve_virq(d, i);
+        irq_set_type(i, ACPI_IRQ_TYPE_NONE);

I don't know if there is any point in setting the type to NONE. It's the default, isn't it?

Quoted 29 lines
xen/arch/arm/domain_build.c +16 -0
+        res = route_irq_to_guest(d, i, i, NULL);
+        if ( res )
+        {
+            printk(XENLOG_ERR "Unable to route IRQ %u to domain %u\n",
+                   i, d->domain_id);
+            continue;
+        }
+    }
+
+    return 0;
+}
+
 static int make_chosen_node(const struct kernel_info *kinfo,
                             struct membank tbl_add[])
 {
@@ -1897,6 +1926,10 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
     if ( rc != 0 )
         return rc;
 
+    rc = acpi_route_spi(d);
+    if ( rc != 0 )
+        return rc;
+
     return 0;
 }
 #else
Signature · 1 line
2.1.0
#290 lore raw

PATCH v3 56/62 arm/acpi: Deny MMIO access of UART

In reply to shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Firstly it permits full MMIO capabilities for Dom0. Then deny MMIO access of UART device.

---
 xen/arch/arm/domain_build.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)
xen/arch/arm/domain_build.c +30 -0
index 6945f89..9532807 100644
@@ -1360,6 +1360,32 @@ static int prepare_dtb(struct domain *d, struct kernel_info *kinfo)
 #define XEN_HYPERVISOR_ID 0x000058656E564D4D  /* "XenVMM" */
 #define ACPI_DOM0_FDT_MIN_SIZE 4096
 
+static int acpi_iomem_deny_access(struct domain *d)
+{
+    acpi_status status;
+    struct acpi_table_spcr *spcr=NULL;
+    unsigned long gfn;
+    int rc;
+
+    /* Firstly permit full MMIO capabilities. */
+    rc = iomem_permit_access(d, 0UL, ~0UL);
+    if (rc)
+        return rc;
+
+    status = acpi_get_table(ACPI_SIG_SPCR, 0,
+                            (struct acpi_table_header **)&spcr);
+
+    if ( ACPI_FAILURE(status) )
+    {
+        printk("Failed to get SPCR table\n");
+        return -EINVAL;
+    }
+
+    gfn = spcr->serial_port.address >> PAGE_SHIFT;
+    /* Deny MMIO access for UART */
+    return iomem_deny_access(d, gfn, gfn + 1);
+}
+
 static int acpi_route_spi(struct domain *d)
 {
     int i, res;
@@ -1930,6 +1956,10 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
     if ( rc != 0 )
         return rc;
 
+    rc = acpi_iomem_deny_access(d);
+    if ( rc != 0 )
+        return rc;
+
     return 0;
 }
 #else
Signature · 1 line
2.1.0
#291 lore raw

PATCH v3 56/62 arm/acpi: Deny MMIO access of UART

Quoted 4 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Firstly it permits full MMIO capabilities for Dom0. Then deny MMIO access of UART device.

I'm nearly sure we want to deny other MMIO such as the GIC regions and SMMU.

Regards,

Signature · 1 line
Julien Grall
#292 lore raw

PATCH v3 56/62 arm/acpi: Deny MMIO access of UART

Quoted 8 lines · Julien Grall
Quoted 4 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Firstly it permits full MMIO capabilities for Dom0. Then deny MMIO access of UART device.

I'm nearly sure we want to deny other MMIO such as the GIC regions and SMMU.

But Dom0 will not know the real GIC hardware MMIO space, how would it map these regions? In case of wrong use?
Regarding SMMU, since it doesn't support now, so I didn't add it but it could be added later.

Signature · 1 line
Shannon
#293 lore raw

PATCH v3 56/62 arm/acpi: Deny MMIO access of UART

Quoted 11 lines · Shannon Zhao
Quoted 8 lines · Julien Grall
Quoted 4 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Firstly it permits full MMIO capabilities for Dom0. Then deny MMIO access of UART device.

I'm nearly sure we want to deny other MMIO such as the GIC regions and SMMU.

But Dom0 will not know the real GIC hardware MMIO space, how would it map these regions? In case of wrong use?

It could try regions at random or by mistake.
I know that Dom0 is "trusted", but the less we trust it, the better.

Quoted 2 lines

Regarding SMMU, since it doesn't support now, so I didn't add it but it could be added later.

#294 lore raw

Re: [PATCH v3 56/62] arm/acpi: Deny MMIO access of UART

In reply to Shannon Zhao
Quoted 11 lines · Shannon Zhao
Quoted 8 lines · Julien Grall
Quoted 4 lines · On 17/11/15 09:40, [email protected] wrote:

From: Shannon Zhao <[email protected]>

Firstly it permits full MMIO capabilities for Dom0. Then deny MMIO access of UART device.

I'm nearly sure we want to deny other MMIO such as the GIC regions and SMMU.

But Dom0 will not know the real GIC hardware MMIO space, how would it map these regions? In case of wrong use?

It could try regions at random or by mistake.
I know that Dom0 is "trusted", but the less we trust it, the better.

Quoted 2 lines

Regarding SMMU, since it doesn't support now, so I didn't add it but it could be added later.

#295 lore raw

PATCH v3 56/62 arm/acpi: Deny MMIO access of UART

In reply to Shannon Zhao

Hi Shannon,

Quoted 2 lines · Shannon Zhao

Regarding SMMU, since it doesn't support now, so I didn't add it but it could be added later.

Then please add a TODO, otherwise it's a call to forget it.

Regards,

Signature · 1 line
Julien Grall
#296 lore raw

Re: [PATCH v3 56/62] arm/acpi: Deny MMIO access of UART

In reply to Shannon Zhao

Hi Shannon,

Quoted 2 lines · Shannon Zhao

Regarding SMMU, since it doesn't support now, so I didn't add it but it could be added later.

Then please add a TODO, otherwise it's a call to forget it.

Regards,

Signature · 1 line
Julien Grall
#297 lore raw

Re: [PATCH v3 56/62] arm/acpi: Deny MMIO access of UART

In reply to Julien Grall
Quoted 8 lines · Julien Grall
Quoted 4 lines · On 17/11/15 09:40, [email protected] wrote:

From: Shannon Zhao <[email protected]>

Firstly it permits full MMIO capabilities for Dom0. Then deny MMIO access of UART device.

I'm nearly sure we want to deny other MMIO such as the GIC regions and SMMU.

But Dom0 will not know the real GIC hardware MMIO space, how would it map these regions? In case of wrong use?
Regarding SMMU, since it doesn't support now, so I didn't add it but it could be added later.

Signature · 1 line
Shannon
#299 lore raw

PATCH v3 57/62 hvm/params: Add a new dilivery type for event-channel in HVM_PARAM_CALLBACK_IRQ

In reply to shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

Add a new dilivery type:
val[63:56] == 3: val[15:8] is flag: val[7:0] is a PPI.
To the flag, bit 0 stands the interrupt mode is edge(1) or level(0) and bit 1 stands the interrupt polarity is active low(1) or high(0).

---
 xen/include/public/hvm/params.h | 5 +++++
 1 file changed, 5 insertions(+)
xen/include/public/hvm/params.h +5 -0
index 356dfd3..5aa2aba 100644
@@ -38,6 +38,11 @@
  * val[63:56] == 2: val[7:0] is a vector number, check for
  *                  XENFEAT_hvm_callback_vector to know if this delivery
  *                  method is available.
+ * val[63:56] == 3: val[15:8] is flag of event-channel interrupt:
+ *                      bit 0: interrupt is edge(1) or level(0) triggered
+ *                      bit 1: interrupt is active low(1) or high(0)
+ *                  val[7:0] is PPI number used by event-channel.
+ *                  This is only used by ARM/ARM64.
  * If val == 0 then CPU0 event-channel notifications are not delivered.
  */
 #define HVM_PARAM_CALLBACK_IRQ 0
Signature · 1 line
2.1.0
#300 lore raw

PATCH v3 57/62 hvm/params: Add a new dilivery type for event-channel in HVM_PARAM_CALLBACK_IRQ

Quoted 9 lines
Quoted 1 line
Quoted 1 line · On 17.11.15 at 10:40, <[email protected]> wrote:

From: Shannon Zhao <[email protected]>

Add a new dilivery type:
val[63:56] == 3: val[15:8] is flag: val[7:0] is a PPI.
To the flag, bit 0 stands the interrupt mode is edge(1) or level(0) and bit 1 stands the interrupt polarity is active low(1) or high(0).

Please sync up with Andrew's cleaning up of the modified comment; I definitely will want that to go in first.

Jan

#301 lore raw

Re: [PATCH v3 57/62] hvm/params: Add a new dilivery type for event-channel in HVM_PARAM_CALLBACK_IRQ

In reply to shannon.zhao at linaro.org
Quoted 9 lines
Quoted 1 line
Quoted 1 line · On 17.11.15 at 10:40, <[email protected]> wrote:

From: Shannon Zhao <[email protected]>

Add a new dilivery type:
val[63:56] == 3: val[15:8] is flag: val[7:0] is a PPI.
To the flag, bit 0 stands the interrupt mode is edge(1) or level(0) and bit 1 stands the interrupt polarity is active low(1) or high(0).

Please sync up with Andrew's cleaning up of the modified comment; I definitely will want that to go in first.

Jan

#302 lore raw

PATCH v3 58/62 xen/acpi: Fix event-channel interrupt when booting with ACPI

In reply to shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

When booting with ACPI, store the event-channel interrupt number and flag in HVM parameter HVM_PARAM_CALLBACK_IRQ. Then Dom0 could get it through hypercall HVMOP_get_param.

---
 xen/arch/arm/domain_build.c | 45 ++++++++++++++++++++++++++++-----------------
 1 file changed, 28 insertions(+), 17 deletions(-)
xen/arch/arm/domain_build.c +28 -17
index 9532807..36917be 100644
@@ -2067,23 +2067,34 @@ static void evtchn_fixup(struct domain *d, struct kernel_info *kinfo)
     printk("Allocating PPI %u for event channel interrupt\n",
            d->arch.evtchn_irq);
 
-    /* Fix up "interrupts" in /hypervisor node */
-    node = fdt_path_offset(kinfo->fdt, "/hypervisor");
-    if ( node < 0 )
-        panic("Cannot find the /hypervisor node");
-
-    /* Interrupt event channel upcall:
-     *  - Active-low level-sensitive
-     *  - All CPUs
-     *
-     *  TODO: Handle properly the cpumask
-     */
-    set_interrupt_ppi(intr, d->arch.evtchn_irq, 0xf,
-                      DT_IRQ_TYPE_LEVEL_LOW);
-    res = fdt_setprop_inplace(kinfo->fdt, node, "interrupts",
-                              &intr, sizeof(intr));
-    if ( res )
-        panic("Cannot fix up \"interrupts\" property of the hypervisor node");
+    if ( acpi_disabled )
+    {
+        /* Fix up "interrupts" in /hypervisor node */
+        node = fdt_path_offset(kinfo->fdt, "/hypervisor");
+        if ( node < 0 )
+            panic("Cannot find the /hypervisor node");
+
+        /* Interrupt event channel upcall:
+         *  - Active-low level-sensitive
+         *  - All CPUs
+         *
+         *  TODO: Handle properly the cpumask
+         */
+        set_interrupt_ppi(intr, d->arch.evtchn_irq, 0xf,
+                          DT_IRQ_TYPE_LEVEL_LOW);
+        res = fdt_setprop_inplace(kinfo->fdt, node, "interrupts",
+                                  &intr, sizeof(intr));
+        if ( res )
+            panic("Cannot fix up \"interrupts\" property of the hypervisor node");
+    }
+    else
+    {
+        int type = 3;
+        int flag = 2; /* Active-low level-sensitive  */
+        d->arch.hvm_domain.params[HVM_PARAM_CALLBACK_IRQ] = (u64)type << 56
+                                                            | flag << 8
+                                                            | d->arch.evtchn_irq;
+    }
 }
 
 static void __init find_gnttab_region(struct domain *d,
Signature · 1 line
2.1.0
#303 lore raw

PATCH v3 58/62 xen/acpi: Fix event-channel interrupt when booting with ACPI

Quoted 45 lines · shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

When booting with ACPI, store the event-channel interrupt number and flag in HVM parameter HVM_PARAM_CALLBACK_IRQ. Then Dom0 could get it through hypercall HVMOP_get_param.

---
 xen/arch/arm/domain_build.c | 45 ++++++++++++++++++++++++++++-----------------
 1 file changed, 28 insertions(+), 17 deletions(-)
xen/arch/arm/domain_build.c +9 -17
index 9532807..36917be 100644
@@ -2067,23 +2067,34 @@ static void evtchn_fixup(struct domain *d, struct kernel_info *kinfo)
     printk("Allocating PPI %u for event channel interrupt\n",
            d->arch.evtchn_irq);
 
-    /* Fix up "interrupts" in /hypervisor node */
-    node = fdt_path_offset(kinfo->fdt, "/hypervisor");
-    if ( node < 0 )
-        panic("Cannot find the /hypervisor node");
-
-    /* Interrupt event channel upcall:
-     *  - Active-low level-sensitive
-     *  - All CPUs
-     *
-     *  TODO: Handle properly the cpumask
-     */
-    set_interrupt_ppi(intr, d->arch.evtchn_irq, 0xf,
-                      DT_IRQ_TYPE_LEVEL_LOW);
-    res = fdt_setprop_inplace(kinfo->fdt, node, "interrupts",
-                              &intr, sizeof(intr));
-    if ( res )
-        panic("Cannot fix up \"interrupts\" property of the hypervisor node");
+    if ( acpi_disabled )
+    {
+        /* Fix up "interrupts" in /hypervisor node */
+        node = fdt_path_offset(kinfo->fdt, "/hypervisor");
+        if ( node < 0 )
+            panic("Cannot find the /hypervisor node");
+
+        /* Interrupt event channel upcall:
+         *  - Active-low level-sensitive

xen/arch/arm/domain_build.c static void evtchn_fixup(struct domain *d, struct kernel_info *kinfo) · line 2088

Quoted 10 lines
xen/arch/arm/domain_build.c +10 -0
+         *  - All CPUs
+         *
+         *  TODO: Handle properly the cpumask
+         */
+        set_interrupt_ppi(intr, d->arch.evtchn_irq, 0xf,
+                          DT_IRQ_TYPE_LEVEL_LOW);
+        res = fdt_setprop_inplace(kinfo->fdt, node, "interrupts",
+                                  &intr, sizeof(intr));
+        if ( res )
+            panic("Cannot fix up \"interrupts\" property of the hypervisor node");

This code could be moved out to a dt_set_evtchn_irq function

xen/arch/arm/domain_build.c static void evtchn_fixup(struct domain *d, struct kernel_info *kinfo) · line 2098

Quoted 10 lines
xen/arch/arm/domain_build.c +9 -0
+    }
+    else
+    {
+        int type = 3;
+        int flag = 2; /* Active-low level-sensitive  */
+        d->arch.hvm_domain.params[HVM_PARAM_CALLBACK_IRQ] = (u64)type << 56
+                                                            | flag << 8
+                                                            | d->arch.evtchn_irq;
+    }
 }

Actually there is no point in setting HVM_PARAM_CALLBACK_IRQ only on
ACPI: I would just set it on all cases.

#304 lore raw

PATCH v3 58/62 xen/acpi: Fix event-channel interrupt when booting with ACPI

Quoted 11 lines · Stefano Stabellini

xen/arch/arm/domain_build.c static void evtchn_fixup(struct domain *d, struct kernel_info *kinfo) · line 2098

Quoted 10 lines
xen/arch/arm/domain_build.c +9 -0
+    }
+    else
+    {
+        int type = 3;
+        int flag = 2; /* Active-low level-sensitive  */
+        d->arch.hvm_domain.params[HVM_PARAM_CALLBACK_IRQ] = (u64)type << 56
+                                                            | flag << 8
+                                                            | d->arch.evtchn_irq;
+    }
 }
Quoted 2 lines

Actually there is no point in setting HVM_PARAM_CALLBACK_IRQ only on
ACPI: I would just set it on all cases.

+1

Regards,

Signature · 1 line
Julien Grall
#305 lore raw

Re: [PATCH v3 58/62] xen/acpi: Fix event-channel interrupt when booting with ACPI

In reply to shannon.zhao at linaro.org
Quoted 45 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Shannon Zhao <[email protected]>

When booting with ACPI, store the event-channel interrupt number and flag in HVM parameter HVM_PARAM_CALLBACK_IRQ. Then Dom0 could get it through hypercall HVMOP_get_param.

---
 xen/arch/arm/domain_build.c | 45 ++++++++++++++++++++++++++++-----------------
 1 file changed, 28 insertions(+), 17 deletions(-)
xen/arch/arm/domain_build.c +9 -17
index 9532807..36917be 100644
@@ -2067,23 +2067,34 @@ static void evtchn_fixup(struct domain *d, struct kernel_info *kinfo)
     printk("Allocating PPI %u for event channel interrupt\n",
            d->arch.evtchn_irq);
 
-    /* Fix up "interrupts" in /hypervisor node */
-    node = fdt_path_offset(kinfo->fdt, "/hypervisor");
-    if ( node < 0 )
-        panic("Cannot find the /hypervisor node");
-
-    /* Interrupt event channel upcall:
-     *  - Active-low level-sensitive
-     *  - All CPUs
-     *
-     *  TODO: Handle properly the cpumask
-     */
-    set_interrupt_ppi(intr, d->arch.evtchn_irq, 0xf,
-                      DT_IRQ_TYPE_LEVEL_LOW);
-    res = fdt_setprop_inplace(kinfo->fdt, node, "interrupts",
-                              &intr, sizeof(intr));
-    if ( res )
-        panic("Cannot fix up \"interrupts\" property of the hypervisor node");
+    if ( acpi_disabled )
+    {
+        /* Fix up "interrupts" in /hypervisor node */
+        node = fdt_path_offset(kinfo->fdt, "/hypervisor");
+        if ( node < 0 )
+            panic("Cannot find the /hypervisor node");
+
+        /* Interrupt event channel upcall:
+         *  - Active-low level-sensitive

xen/arch/arm/domain_build.c static void evtchn_fixup(struct domain *d, struct kernel_info *kinfo) · line 2088

Quoted 10 lines
xen/arch/arm/domain_build.c +10 -0
+         *  - All CPUs
+         *
+         *  TODO: Handle properly the cpumask
+         */
+        set_interrupt_ppi(intr, d->arch.evtchn_irq, 0xf,
+                          DT_IRQ_TYPE_LEVEL_LOW);
+        res = fdt_setprop_inplace(kinfo->fdt, node, "interrupts",
+                                  &intr, sizeof(intr));
+        if ( res )
+            panic("Cannot fix up \"interrupts\" property of the hypervisor node");

This code could be moved out to a dt_set_evtchn_irq function

xen/arch/arm/domain_build.c static void evtchn_fixup(struct domain *d, struct kernel_info *kinfo) · line 2098

Quoted 10 lines
xen/arch/arm/domain_build.c +9 -0
+    }
+    else
+    {
+        int type = 3;
+        int flag = 2; /* Active-low level-sensitive  */
+        d->arch.hvm_domain.params[HVM_PARAM_CALLBACK_IRQ] = (u64)type << 56
+                                                            | flag << 8
+                                                            | d->arch.evtchn_irq;
+    }
 }

Actually there is no point in setting HVM_PARAM_CALLBACK_IRQ only on
ACPI: I would just set it on all cases.

#306 lore raw

PATCH v3 59/62 xen/arm: Add a hypercall for device mmio mapping

In reply to shannon.zhao at linaro.org

From: Shannon Zhao <[email protected]>

It needs to map platform or amba device mmio to Dom0 on ARM. But when booting with ACPI, it can't get the mmio region in Xen due to lack of AML interpreter to parse DSDT table. Therefore, let Dom0 call a hypercall to map mmio region when it adds the devices.

---
 xen/arch/arm/mm.c           |  4 ++++
 xen/arch/arm/p2m.c          | 34 ++++++++++++++++++++++++++++++++++
 xen/include/asm-arm/p2m.h   |  5 +++++
 xen/include/public/memory.h |  1 +
 4 files changed, 44 insertions(+)
xen/arch/arm/mm.c +4 -0
index 8b6d915..fbe0406 100644
@@ -1138,6 +1138,10 @@ int xenmem_add_to_physmap_one(
         rcu_unlock_domain(od);
         break;
     }
+    case XENMAPSPACE_dev_mmio:
+        rc = map_dev_mmio_region(d, gpfn, 1, idx);
+        return rc;
+        break;
 
     default:
         return -ENOSYS;
xen/arch/arm/p2m.c +34 -0
index 7a108d8..b44ad76 100644
@@ -7,6 +7,7 @@
 #include <xen/bitops.h>
 #include <xen/vm_event.h>
 #include <xen/mem_access.h>
+#include <xen/iocap.h>
 #include <public/vm_event.h>
 #include <asm/flushtlb.h>
 #include <asm/gic.h>
@@ -1192,6 +1193,39 @@ int unmap_mmio_regions(struct domain *d,
                              d->arch.p2m.default_access);
 }
 
+int map_dev_mmio_region(struct domain *d,
+                        unsigned long start_gfn,
+                        unsigned long nr,
+                        unsigned long mfn)
+{
+    int res;
+
+    if(!iomem_access_permitted(d, start_gfn, start_gfn + nr))
+        return 0;
+
+    res = iomem_permit_access(d, start_gfn, (start_gfn + nr));
+    if ( res )
+    {
+        printk(XENLOG_ERR "Unable to permit to dom%d access to"
+               " 0x%"PRIx64" - 0x%"PRIx64"\n",
+               d->domain_id,
+               start_gfn << PAGE_SHIFT, (start_gfn + nr) << PAGE_SHIFT);
+        return res;
+    }
+
+    res = map_mmio_regions(d, start_gfn, nr, mfn);
+    if ( res < 0 )
+    {
+        printk(XENLOG_ERR "Unable to map 0x%"PRIx64
+               " - 0x%"PRIx64" in domain %d\n",
+               start_gfn << PAGE_SHIFT, (start_gfn + nr) << PAGE_SHIFT,
+               d->domain_id);
+        return res;
+    }
+
+    return 0;
+}
+
 int guest_physmap_add_entry(struct domain *d,
                             unsigned long gpfn,
                             unsigned long mfn,
xen/include/asm-arm/p2m.h +5 -0
index b6215f9..5e9d0a1 100644
@@ -168,6 +168,11 @@ int unmap_regions(struct domain *d,
                     unsigned long nr_mfns,
                     unsigned long mfn);
 
+int map_dev_mmio_region(struct domain *d,
+                        unsigned long start_gfn,
+                        unsigned long nr,
+                        unsigned long mfn);
+
 int guest_physmap_add_entry(struct domain *d,
                             unsigned long gfn,
                             unsigned long mfn,
xen/include/public/memory.h +1 -0
index 4df38d6..c19da1a 100644
@@ -220,6 +220,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_machphys_mapping_t);
 #define XENMAPSPACE_gmfn_range   3 /* GMFN range, XENMEM_add_to_physmap only. */
 #define XENMAPSPACE_gmfn_foreign 4 /* GMFN from another dom,
                                     * XENMEM_add_to_physmap_batch only. */
+#define XENMAPSPACE_dev_mmio     5 /* device mmio region */
 /* ` } */
 
 /*
Signature · 1 line
2.1.0
#307 lore raw

PATCH v3 59/62 xen/arm: Add a hypercall for device mmio mapping

xen/arch/arm/mm.c int xenmem_add_to_physmap_one( · line 1144

Quoted 11 lines
Quoted 1 line
Quoted 1 line · On 17.11.15 at 10:40, <[email protected]> wrote:
xen/arch/arm/mm.c +4 -0
@@ -1138,6 +1138,10 @@ int xenmem_add_to_physmap_one(
         rcu_unlock_domain(od);
         break;
     }
+    case XENMAPSPACE_dev_mmio:
+        rc = map_dev_mmio_region(d, gpfn, 1, idx);
+        return rc;
+        break;

Blindly for any kind of domain? The XSM check in the XENMEM_add_to_physmap_batch handler (in common code) doesn't even know which map space is to be used...

Jan

#308 lore raw

PATCH v3 59/62 xen/arm: Add a hypercall for device mmio mapping

Hi Jan,

Quoted 14 lines · Jan Beulich
Quoted 11 lines

xen/arch/arm/mm.c int xenmem_add_to_physmap_one( · line 1144

Quoted 11 lines
Quoted 1 line · On 17.11.15 at 10:40, <[email protected]> wrote:
xen/arch/arm/mm.c +4 -0
@@ -1138,6 +1138,10 @@ int xenmem_add_to_physmap_one(
         rcu_unlock_domain(od);
         break;
     }
+    case XENMAPSPACE_dev_mmio:
+        rc = map_dev_mmio_region(d, gpfn, 1, idx);
+        return rc;
+        break;

Blindly for any kind of domain? The XSM check in the XENMEM_add_to_physmap_batch handler (in common code) doesn't even know which map space is to be used...

Sorry, I know little about XSM. Could you suggest me how to add the check for this new type here?

Thanks,

Signature · 1 line
Shannon
#309 lore raw

PATCH v3 59/62 xen/arm: Add a hypercall for device mmio mapping

Quoted 17 lines
Quoted 1 line
Quoted 1 line · On 07.01.16 at 07:58, <[email protected]> wrote:
Quoted 14 lines · Jan Beulich
Quoted 11 lines

xen/arch/arm/mm.c int xenmem_add_to_physmap_one( · line 1144

Quoted 11 lines
Quoted 1 line · On 17.11.15 at 10:40, <[email protected]> wrote:
xen/arch/arm/mm.c +4 -0
@@ -1138,6 +1138,10 @@ int xenmem_add_to_physmap_one(
         rcu_unlock_domain(od);
         break;
     }
+    case XENMAPSPACE_dev_mmio:
+        rc = map_dev_mmio_region(d, gpfn, 1, idx);
+        return rc;
+        break;

Blindly for any kind of domain? The XSM check in the XENMEM_add_to_physmap_batch handler (in common code) doesn't even know which map space is to be used...

Quoted 2 lines

Sorry, I know little about XSM. Could you suggest me how to add the check for this new type here?

I'm sorry to push back here, but did you at least try to derive what is wanted from the multitude of other XSM checks present throughout the tree?

Jan

#310 lore raw

PATCH v3 59/62 xen/arm: Add a hypercall for device mmio mapping

Hi Jan,

Quoted 17 lines · Jan Beulich
Quoted 17 lines
Quoted 17 lines
Quoted 1 line · On 07.01.16 at 07:58, <[email protected]> wrote:
Quoted 14 lines · Jan Beulich
Quoted 14 lines
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines

xen/arch/arm/mm.c int xenmem_add_to_physmap_one( · line 1144

Quoted 11 lines
Quoted 1 line
Quoted 1 line · On 17.11.15 at 10:40, <[email protected]> wrote:
xen/arch/arm/mm.c +4 -0
@@ -1138,6 +1138,10 @@ int xenmem_add_to_physmap_one(
         rcu_unlock_domain(od);
         break;
     }
+    case XENMAPSPACE_dev_mmio:
+        rc = map_dev_mmio_region(d, gpfn, 1, idx);
+        return rc;
+        break;

Blindly for any kind of domain? The XSM check in the XENMEM_add_to_physmap_batch handler (in common code) doesn't even know which map space is to be used...

Quoted 5 lines
Quoted 2 lines
Quoted 2 lines

Sorry, I know little about XSM. Could you suggest me how to add the check for this new type here?

I'm sorry to push back here, but did you at least try to derive what is wanted from the multitude of other XSM checks present throughout the tree?

IIUC, you mean that it doean't need to change the XSM check itself, but we should check if the current->domain is hardware domain and it maps the space to itself before the XSM check, right?

If so, how about below patch on top of this patch?

xen/common/memory.c +0 -0
index 9ff1145..33feb2d 100644
@@ -980,6 +980,13 @@ long do_memory_op(unsigned long cmd,

XEN_GUEST_HANDLE_PARAM(void) arg)

         if ( d == NULL )
             return -ESRCH;

+ /* Device MMIO mapping is only supported for Domain0 to map
these ranges

+        * to itself
+        */
+        if ( (xatp.space == XENMAPSPACE_dev_mmio) &&

+ (!is_hardware_domain(current->domain) || (d !=
current->domain)) )
+ return -EOPNOTSUPP;
+

         rc = xsm_add_to_physmap(XSM_TARGET, current->domain, d);
         if ( rc )
         {
@@ -1024,6 +1031,13 @@ long do_memory_op(unsigned long cmd,
XEN_GUEST_HANDLE_PARAM(void) arg)
         if ( d == NULL )
             return -ESRCH;

+ /* Device MMIO mapping is only supported for Domain0 to map
these ranges
+ * to itself
+ */
+ if ( (xatpb.space == XENMAPSPACE_dev_mmio) &&
+ (!is_hardware_domain(current->domain) || (d !=
current->domain)) )
+ return -EOPNOTSUPP;
+

          rc = xsm_add_to_physmap(XSM_TARGET, current->domain, d);
          if ( rc )
          {

Thanks,

Signature · 1 line
Shannon
#311 lore raw

PATCH v3 59/62 xen/arm: Add a hypercall for device mmio mapping

Quoted 23 lines
Quoted 1 line
Quoted 1 line · On 07.01.16 at 10:11, <[email protected]> wrote:

Hi Jan,

Quoted 19 lines · Jan Beulich
Quoted 19 lines
Quoted 19 lines
Quoted 1 line · On 07.01.16 at 07:58, <[email protected]> wrote:
Quoted 14 lines · Jan Beulich
Quoted 14 lines
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines

xen/arch/arm/mm.c int xenmem_add_to_physmap_one( · line 1144

Quoted 11 lines
Quoted 1 line
Quoted 1 line · On 17.11.15 at 10:40, <[email protected]> wrote:
xen/arch/arm/mm.c +4 -0
@@ -1138,6 +1138,10 @@ int xenmem_add_to_physmap_one(
         rcu_unlock_domain(od);
         break;
     }
+    case XENMAPSPACE_dev_mmio:
+        rc = map_dev_mmio_region(d, gpfn, 1, idx);
+        return rc;
+        break;

Blindly for any kind of domain? The XSM check in the XENMEM_add_to_physmap_batch handler (in common code) doesn't even know which map space is to be used...

Sorry, I know little about XSM. Could you suggest me how to add the check for this new type here?

Quoted 7 lines
Quoted 3 lines

I'm sorry to push back here, but did you at least try to derive what is wanted from the multitude of other XSM checks present throughout the tree?

IIUC, you mean that it doean't need to change the XSM check itself, but we should check if the current->domain is hardware domain and it maps the space to itself before the XSM check, right?

No, I actually think that you need to add a new, secondary XSM check. But you may want to consult with Daniel (who so far wasn't even Cc-ed).

Jan

#312 lore raw

PATCH v3 59/62 xen/arm: Add a hypercall for device mmio mapping

Quoted 27 lines · Jan Beulich
Quoted 27 lines
Quoted 1 line
Quoted 1 line · On 07.01.16 at 10:11, <[email protected]> wrote:

Hi Jan,

Quoted 22 lines · Jan Beulich
Quoted 17 lines
Quoted 17 lines
Quoted 1 line · On 07.01.16 at 07:58, <[email protected]> wrote:
Quoted 14 lines · Jan Beulich
Quoted 14 lines
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines

xen/arch/arm/mm.c int xenmem_add_to_physmap_one( · line 1144

Quoted 11 lines
Quoted 1 line
Quoted 1 line · On 17.11.15 at 10:40, <[email protected]> wrote:
xen/arch/arm/mm.c +4 -0
@@ -1138,6 +1138,10 @@ int xenmem_add_to_physmap_one(
          rcu_unlock_domain(od);
          break;
      }
+    case XENMAPSPACE_dev_mmio:
+        rc = map_dev_mmio_region(d, gpfn, 1, idx);
+        return rc;
+        break;

Blindly for any kind of domain? The XSM check in the XENMEM_add_to_physmap_batch handler (in common code) doesn't even know which map space is to be used...

Quoted 2 lines
Quoted 2 lines

Sorry, I know little about XSM. Could you suggest me how to add the check for this new type here?

I'm sorry to push back here, but did you at least try to derive what is wanted from the multitude of other XSM checks present throughout the tree?

Quoted 7 lines
Quoted 3 lines

IIUC, you mean that it doean't need to change the XSM check itself, but we should check if the current->domain is hardware domain and it maps the space to itself before the XSM check, right?

No, I actually think that you need to add a new, secondary XSM check. But you may want to consult with Daniel (who so far wasn't even Cc-ed).

Looking at the original patch, I am not sure if I understand the
checks: it seems like the iomem_access_permitted check is being done on the guest's page range instead of the actual IO memory, which ends up allowing the guest to map anything as long as it maps it in the right guest area. The iomem_permit_access call there also seems to be redundant because it is the same range that was just checked.

If the [start_gfn, start_gfn + nr) memory range actually describes the physical addresses, then this operation is taking advantage of the existing XSM checks on XEN_DOMCTL_iomem_permission, and the only XSM check that is needed would be that current->domain has permission to modify (d)'s mappings - and this is done by the xsm_add_to_physmap check in XENMEM_add_to_physmap.

Signature · 2 lines
Daniel De Graaf
National Security Agency
#313 lore raw

PATCH v3 59/62 xen/arm: Add a hypercall for device mmio mapping

Quoted 36 lines · Daniel De Graaf
Quoted 27 lines · Jan Beulich
Quoted 27 lines
Quoted 1 line
Quoted 1 line · On 07.01.16 at 10:11, <[email protected]> wrote:

Hi Jan,

Quoted 22 lines · Jan Beulich
Quoted 17 lines
Quoted 17 lines
Quoted 1 line · On 07.01.16 at 07:58, <[email protected]> wrote:
Quoted 14 lines · Jan Beulich
Quoted 14 lines
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines

xen/arch/arm/mm.c int xenmem_add_to_physmap_one( · line 1144

Quoted 11 lines
Quoted 1 line

On 17.11.15 at 10:40, <[email protected]> wrote:

xen/arch/arm/mm.c +4 -0
@@ -1138,6 +1138,10 @@ int xenmem_add_to_physmap_one(
          rcu_unlock_domain(od);
          break;
      }
+    case XENMAPSPACE_dev_mmio:
+        rc = map_dev_mmio_region(d, gpfn, 1, idx);
+        return rc;
+        break;

Blindly for any kind of domain? The XSM check in the XENMEM_add_to_physmap_batch handler (in common code) doesn't even know which map space is to be used...

Quoted 2 lines
Quoted 2 lines

Sorry, I know little about XSM. Could you suggest me how to add the check for this new type here?

I'm sorry to push back here, but did you at least try to derive what is wanted from the multitude of other XSM checks present throughout the tree?

Quoted 7 lines
Quoted 3 lines

IIUC, you mean that it doean't need to change the XSM check itself, but we should check if the current->domain is hardware domain and it maps the space to itself before the XSM check, right?

No, I actually think that you need to add a new, secondary XSM check. But you may want to consult with Daniel (who so far wasn't even Cc-ed).

Quoted 5 lines

Looking at the original patch, I am not sure if I understand the
checks: it seems like the iomem_access_permitted check is being done on the guest's page range instead of the actual IO memory, which ends up allowing the guest to map anything as long as it maps it in the right guest area.

Yeah, since it's hard to know the MMIO range from the DSDT in XEN, we permit full mmio capabilities for Dom0 and deny mmio access for some devices e.g. uart. Then when Dom0 add those devices, call XENMEM_add_to_physmap to map their MMIO ranges. This looks similar with what x86 does.

    /* The hardware domain is initially permitted full I/O capabilities. */
    rc |= ioports_permit_access(d, 0, 0xFFFF);
    rc |= iomem_permit_access(d, 0UL, ~0UL);
    rc |= irqs_permit_access(d, 1, nr_irqs_gsi - 1);
Quoted 3 lines

The iomem_permit_access call there also seems
to be redundant because it is the same range that was just checked.

Ah, I'll drop this at next version.

Quoted 6 lines

If the [start_gfn, start_gfn + nr) memory range actually describes the physical addresses, then this operation is taking advantage of the existing XSM checks on XEN_DOMCTL_iomem_permission, and the only XSM check that is needed would be that current->domain has permission to modify (d)'s mappings - and this is done by the xsm_add_to_physmap check in XENMEM_add_to_physmap.

Thanks,

Signature · 1 line
Shannon
#314 lore raw

Re: [PATCH v3 59/62] xen/arm: Add a hypercall for device mmio mapping

In reply to Daniel De Graaf
Quoted 36 lines · Daniel De Graaf
Quoted 27 lines · Jan Beulich
Quoted 27 lines
Quoted 1 line
Quoted 1 line · On 07.01.16 at 10:11, <[email protected]> wrote:

Hi Jan,

Quoted 22 lines · Jan Beulich
Quoted 17 lines
Quoted 17 lines
Quoted 1 line · On 07.01.16 at 07:58, <[email protected]> wrote:
Quoted 14 lines · Jan Beulich
Quoted 14 lines
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines

xen/arch/arm/mm.c int xenmem_add_to_physmap_one( · line 1144

Quoted 11 lines
Quoted 1 line

On 17.11.15 at 10:40, <[email protected]> wrote:

xen/arch/arm/mm.c +4 -0
@@ -1138,6 +1138,10 @@ int xenmem_add_to_physmap_one(
          rcu_unlock_domain(od);
          break;
      }
+    case XENMAPSPACE_dev_mmio:
+        rc = map_dev_mmio_region(d, gpfn, 1, idx);
+        return rc;
+        break;

Blindly for any kind of domain? The XSM check in the XENMEM_add_to_physmap_batch handler (in common code) doesn't even know which map space is to be used...

Quoted 2 lines
Quoted 2 lines

Sorry, I know little about XSM. Could you suggest me how to add the check for this new type here?

I'm sorry to push back here, but did you at least try to derive what is wanted from the multitude of other XSM checks present throughout the tree?

Quoted 7 lines
Quoted 3 lines

IIUC, you mean that it doean't need to change the XSM check itself, but we should check if the current->domain is hardware domain and it maps the space to itself before the XSM check, right?

No, I actually think that you need to add a new, secondary XSM check. But you may want to consult with Daniel (who so far wasn't even Cc-ed).

Quoted 5 lines

Looking at the original patch, I am not sure if I understand the
checks: it seems like the iomem_access_permitted check is being done on the guest's page range instead of the actual IO memory, which ends up allowing the guest to map anything as long as it maps it in the right guest area.

Yeah, since it's hard to know the MMIO range from the DSDT in XEN, we permit full mmio capabilities for Dom0 and deny mmio access for some devices e.g. uart. Then when Dom0 add those devices, call XENMEM_add_to_physmap to map their MMIO ranges. This looks similar with what x86 does.

    /* The hardware domain is initially permitted full I/O capabilities. */
    rc |= ioports_permit_access(d, 0, 0xFFFF);
    rc |= iomem_permit_access(d, 0UL, ~0UL);
    rc |= irqs_permit_access(d, 1, nr_irqs_gsi - 1);
Quoted 3 lines

The iomem_permit_access call there also seems
to be redundant because it is the same range that was just checked.

Ah, I'll drop this at next version.

Quoted 6 lines

If the [start_gfn, start_gfn + nr) memory range actually describes the physical addresses, then this operation is taking advantage of the existing XSM checks on XEN_DOMCTL_iomem_permission, and the only XSM check that is needed would be that current->domain has permission to modify (d)'s mappings - and this is done by the xsm_add_to_physmap check in XENMEM_add_to_physmap.

Thanks,

Signature · 1 line
Shannon
#315 lore raw

Re: [PATCH v3 59/62] xen/arm: Add a hypercall for device mmio mapping

In reply to Jan Beulich
Quoted 27 lines · Jan Beulich
Quoted 27 lines
Quoted 1 line
Quoted 1 line · On 07.01.16 at 10:11, <[email protected]> wrote:

Hi Jan,

Quoted 22 lines · Jan Beulich
Quoted 17 lines
Quoted 17 lines
Quoted 1 line · On 07.01.16 at 07:58, <[email protected]> wrote:
Quoted 14 lines · Jan Beulich
Quoted 14 lines
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines

xen/arch/arm/mm.c int xenmem_add_to_physmap_one( · line 1144

Quoted 11 lines
Quoted 1 line
Quoted 1 line · On 17.11.15 at 10:40, <[email protected]> wrote:
xen/arch/arm/mm.c +4 -0
@@ -1138,6 +1138,10 @@ int xenmem_add_to_physmap_one(
          rcu_unlock_domain(od);
          break;
      }
+    case XENMAPSPACE_dev_mmio:
+        rc = map_dev_mmio_region(d, gpfn, 1, idx);
+        return rc;
+        break;

Blindly for any kind of domain? The XSM check in the XENMEM_add_to_physmap_batch handler (in common code) doesn't even know which map space is to be used...

Quoted 2 lines
Quoted 2 lines

Sorry, I know little about XSM. Could you suggest me how to add the check for this new type here?

I'm sorry to push back here, but did you at least try to derive what is wanted from the multitude of other XSM checks present throughout the tree?

Quoted 7 lines
Quoted 3 lines

IIUC, you mean that it doean't need to change the XSM check itself, but we should check if the current->domain is hardware domain and it maps the space to itself before the XSM check, right?

No, I actually think that you need to add a new, secondary XSM check. But you may want to consult with Daniel (who so far wasn't even Cc-ed).

Looking at the original patch, I am not sure if I understand the
checks: it seems like the iomem_access_permitted check is being done on the guest's page range instead of the actual IO memory, which ends up allowing the guest to map anything as long as it maps it in the right guest area. The iomem_permit_access call there also seems to be redundant because it is the same range that was just checked.

If the [start_gfn, start_gfn + nr) memory range actually describes the physical addresses, then this operation is taking advantage of the existing XSM checks on XEN_DOMCTL_iomem_permission, and the only XSM check that is needed would be that current->domain has permission to modify (d)'s mappings - and this is done by the xsm_add_to_physmap check in XENMEM_add_to_physmap.

Signature · 2 lines
Daniel De Graaf
National Security Agency
#316 lore raw

Re: [PATCH v3 59/62] xen/arm: Add a hypercall for device mmio mapping

In reply to Shannon Zhao
Quoted 23 lines
Quoted 1 line
Quoted 1 line · On 07.01.16 at 10:11, <[email protected]> wrote:

Hi Jan,

Quoted 19 lines · Jan Beulich
Quoted 19 lines
Quoted 19 lines
Quoted 1 line · On 07.01.16 at 07:58, <[email protected]> wrote:
Quoted 14 lines · Jan Beulich
Quoted 14 lines
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines

xen/arch/arm/mm.c int xenmem_add_to_physmap_one( · line 1144

Quoted 11 lines
Quoted 1 line
Quoted 1 line · On 17.11.15 at 10:40, <[email protected]> wrote:
xen/arch/arm/mm.c +4 -0
@@ -1138,6 +1138,10 @@ int xenmem_add_to_physmap_one(
         rcu_unlock_domain(od);
         break;
     }
+    case XENMAPSPACE_dev_mmio:
+        rc = map_dev_mmio_region(d, gpfn, 1, idx);
+        return rc;
+        break;

Blindly for any kind of domain? The XSM check in the XENMEM_add_to_physmap_batch handler (in common code) doesn't even know which map space is to be used...

Sorry, I know little about XSM. Could you suggest me how to add the check for this new type here?

Quoted 7 lines
Quoted 3 lines

I'm sorry to push back here, but did you at least try to derive what is wanted from the multitude of other XSM checks present throughout the tree?

IIUC, you mean that it doean't need to change the XSM check itself, but we should check if the current->domain is hardware domain and it maps the space to itself before the XSM check, right?

No, I actually think that you need to add a new, secondary XSM check. But you may want to consult with Daniel (who so far wasn't even Cc-ed).

Jan

#317 lore raw

Re: [PATCH v3 59/62] xen/arm: Add a hypercall for device mmio mapping

In reply to Jan Beulich

Hi Jan,

Quoted 17 lines · Jan Beulich
Quoted 17 lines
Quoted 17 lines
Quoted 1 line · On 07.01.16 at 07:58, <[email protected]> wrote:
Quoted 14 lines · Jan Beulich
Quoted 14 lines
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines

xen/arch/arm/mm.c int xenmem_add_to_physmap_one( · line 1144

Quoted 11 lines
Quoted 1 line
Quoted 1 line · On 17.11.15 at 10:40, <[email protected]> wrote:
xen/arch/arm/mm.c +4 -0
@@ -1138,6 +1138,10 @@ int xenmem_add_to_physmap_one(
         rcu_unlock_domain(od);
         break;
     }
+    case XENMAPSPACE_dev_mmio:
+        rc = map_dev_mmio_region(d, gpfn, 1, idx);
+        return rc;
+        break;

Blindly for any kind of domain? The XSM check in the XENMEM_add_to_physmap_batch handler (in common code) doesn't even know which map space is to be used...

Quoted 5 lines
Quoted 2 lines
Quoted 2 lines

Sorry, I know little about XSM. Could you suggest me how to add the check for this new type here?

I'm sorry to push back here, but did you at least try to derive what is wanted from the multitude of other XSM checks present throughout the tree?

IIUC, you mean that it doean't need to change the XSM check itself, but we should check if the current->domain is hardware domain and it maps the space to itself before the XSM check, right?

If so, how about below patch on top of this patch?

xen/common/memory.c +0 -0
index 9ff1145..33feb2d 100644
@@ -980,6 +980,13 @@ long do_memory_op(unsigned long cmd,

XEN_GUEST_HANDLE_PARAM(void) arg)

         if ( d == NULL )
             return -ESRCH;

+ /* Device MMIO mapping is only supported for Domain0 to map
these ranges

+        * to itself
+        */
+        if ( (xatp.space == XENMAPSPACE_dev_mmio) &&

+ (!is_hardware_domain(current->domain) || (d !=
current->domain)) )
+ return -EOPNOTSUPP;
+

         rc = xsm_add_to_physmap(XSM_TARGET, current->domain, d);
         if ( rc )
         {
@@ -1024,6 +1031,13 @@ long do_memory_op(unsigned long cmd,
XEN_GUEST_HANDLE_PARAM(void) arg)
         if ( d == NULL )
             return -ESRCH;

+ /* Device MMIO mapping is only supported for Domain0 to map
these ranges
+ * to itself
+ */
+ if ( (xatpb.space == XENMAPSPACE_dev_mmio) &&
+ (!is_hardware_domain(current->domain) || (d !=
current->domain)) )
+ return -EOPNOTSUPP;
+

          rc = xsm_add_to_physmap(XSM_TARGET, current->domain, d);
          if ( rc )
          {

Thanks,

Signature · 1 line
Shannon
#318 lore raw

Re: [PATCH v3 59/62] xen/arm: Add a hypercall for device mmio mapping

In reply to Shannon Zhao
Quoted 17 lines
Quoted 1 line
Quoted 1 line · On 07.01.16 at 07:58, <[email protected]> wrote:
Quoted 14 lines · Jan Beulich
Quoted 11 lines

xen/arch/arm/mm.c int xenmem_add_to_physmap_one( · line 1144

Quoted 11 lines
Quoted 1 line · On 17.11.15 at 10:40, <[email protected]> wrote:
xen/arch/arm/mm.c +4 -0
@@ -1138,6 +1138,10 @@ int xenmem_add_to_physmap_one(
         rcu_unlock_domain(od);
         break;
     }
+    case XENMAPSPACE_dev_mmio:
+        rc = map_dev_mmio_region(d, gpfn, 1, idx);
+        return rc;
+        break;

Blindly for any kind of domain? The XSM check in the XENMEM_add_to_physmap_batch handler (in common code) doesn't even know which map space is to be used...

Quoted 2 lines

Sorry, I know little about XSM. Could you suggest me how to add the check for this new type here?

I'm sorry to push back here, but did you at least try to derive what is wanted from the multitude of other XSM checks present throughout the tree?

Jan

#319 lore raw

Re: [PATCH v3 59/62] xen/arm: Add a hypercall for device mmio mapping

In reply to shannon.zhao at linaro.org

xen/arch/arm/mm.c int xenmem_add_to_physmap_one( · line 1144

Quoted 11 lines
Quoted 1 line
Quoted 1 line · On 17.11.15 at 10:40, <[email protected]> wrote:
xen/arch/arm/mm.c +4 -0
@@ -1138,6 +1138,10 @@ int xenmem_add_to_physmap_one(
         rcu_unlock_domain(od);
         break;
     }
+    case XENMAPSPACE_dev_mmio:
+        rc = map_dev_mmio_region(d, gpfn, 1, idx);
+        return rc;
+        break;

Blindly for any kind of domain? The XSM check in the XENMEM_add_to_physmap_batch handler (in common code) doesn't even know which map space is to be used...

Jan

#320 lore raw

PATCH v3 60/62 arm/acpi: Configure interrupts dynamically

In reply to shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

Interrupt information is described in DSDT and is not available at the time of booting. Configure the interrupts dynamically when requested by Dom0

---
 xen/arch/arm/vgic.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
xen/arch/arm/vgic.c +19 -0
index 7bb4570..d05abde 100644
@@ -25,6 +25,7 @@
 #include <xen/irq.h>
 #include <xen/sched.h>
 #include <xen/perfc.h>
+#include <xen/acpi.h>
 
 #include <asm/current.h>
 
@@ -310,6 +311,8 @@ void vgic_disable_irqs(struct vcpu *v, uint32_t r, int n)
     }
 }
 
+#define VGIC_ICFG_MASK(intr) ( 1 << ( ( 2 * ( intr % 16 ) ) + 1 ) )
+
 void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n)
 {
     struct domain *d = v->domain;
@@ -321,7 +324,23 @@ void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n)
     struct vcpu *v_target;
 
     while ( (i = find_next_bit(&mask, 32, i)) < 32 ) {
+#ifdef CONFIG_ACPI
+        struct vgic_irq_rank *vr = vgic_get_rank(v, n);
+        uint32_t tr;
+
         irq = i + (32 * n);
+        if( ( !acpi_disabled ) && ( n != 0 ) && is_hardware_domain(d) )
+        {
+            tr = vr->icfg[i >> 4] ;
+
+            if( ( tr & VGIC_ICFG_MASK(i) ) )
+                irq_set_type(irq, ACPI_IRQ_TYPE_EDGE_BOTH);
+            else
+                irq_set_type(irq, ACPI_IRQ_TYPE_LEVEL_MASK);
+        }
+#else
+        irq = i + (32 * n);
+#endif
         v_target = d->arch.vgic.handler->get_target_vcpu(v, irq);
         p = irq_to_pending(v_target, irq);
         set_bit(GIC_IRQ_GUEST_ENABLED, &p->status);
Signature · 1 line
2.1.0
#321 lore raw

PATCH v3 60/62 arm/acpi: Configure interrupts dynamically

Quoted 25 lines · shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

Interrupt information is described in DSDT and is not available at the time of booting. Configure the interrupts dynamically when requested by Dom0

---
 xen/arch/arm/vgic.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
xen/arch/arm/vgic.c +1 -0
index 7bb4570..d05abde 100644
@@ -25,6 +25,7 @@
 #include <xen/irq.h>
 #include <xen/sched.h>
 #include <xen/perfc.h>
+#include <xen/acpi.h>
 
 #include <asm/current.h>
 

xen/arch/arm/vgic.c void vgic_disable_irqs(struct vcpu *v, uint32_t r, int n) · line 314

Quoted 4 lines
xen/arch/arm/vgic.c +1 -0
@@ -310,6 +311,8 @@ void vgic_disable_irqs(struct vcpu *v, uint32_t r, int n)
     }
 }
 
+#define VGIC_ICFG_MASK(intr) ( 1 << ( ( 2 * ( intr % 16 ) ) + 1 ) )

Coding style.

xen/arch/arm/vgic.c void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) · line 328

Quoted 9 lines
xen/arch/arm/vgic.c +2 -0
 void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n)
 {
     struct domain *d = v->domain;
@@ -321,7 +324,23 @@ void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n)
     struct vcpu *v_target;
 
     while ( (i = find_next_bit(&mask, 32, i)) < 32 ) {
+#ifdef CONFIG_ACPI
+        struct vgic_irq_rank *vr = vgic_get_rank(v, n);

The rank is always the same, you can move this out of the while loop.

xen/arch/arm/vgic.c void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) · line 332

Quoted 4 lines
xen/arch/arm/vgic.c +3 -0
+        uint32_t tr;
+
         irq = i + (32 * n);
+        if( ( !acpi_disabled ) && ( n != 0 ) && is_hardware_domain(d) )

Instead of n != 0, I would prefer a more obvious irq >= 32 check

xen/arch/arm/vgic.c void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) · line 336

Quoted 4 lines
xen/arch/arm/vgic.c +4 -0
+        {
+            tr = vr->icfg[i >> 4] ;
+
+            if( ( tr & VGIC_ICFG_MASK(i) ) )

Coding style.

xen/arch/arm/vgic.c void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) · line 339

Quoted 3 lines
xen/arch/arm/vgic.c +3 -0
+                irq_set_type(irq, ACPI_IRQ_TYPE_EDGE_BOTH);
+            else
+                irq_set_type(irq, ACPI_IRQ_TYPE_LEVEL_MASK);

Instead of this ad-hoc ACPI code, I would prefer if we get the irq type and, if it is set to NONE or INVALID, we set it to what is in the r->icfg (only for the hardware_domain of course). If it is set to something other than NONE or INVALID, and it doesn't match what is on r->icfg, then we could print out a warning.

xen/arch/arm/vgic.c void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) · line 343

Quoted 4 lines
xen/arch/arm/vgic.c +4 -0
+        }
+#else
+        irq = i + (32 * n);
+#endif

Please leave the irq = i + (32 * n) out of the #ifdef.

Quoted 6 lines
xen/arch/arm/vgic.c +0 -0
         v_target = d->arch.vgic.handler->get_target_vcpu(v, irq);
         p = irq_to_pending(v_target, irq);
         set_bit(GIC_IRQ_GUEST_ENABLED, &p->status);
Signature · 1 line
2.1.0
#322 lore raw

PATCH v3 60/62 arm/acpi: Configure interrupts dynamically

Quoted 6 lines · Stefano Stabellini
Quoted 5 lines · shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

Interrupt information is described in DSDT and is not available at the time of booting. Configure the interrupts dynamically when requested by Dom0

Actually wouldn't it make more sense to configure the physical interrupts when dom0 writes to the virtual ICFG registers?

Quoted 82 lines
Quoted 19 lines
---
 xen/arch/arm/vgic.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
xen/arch/arm/vgic.c +1 -0
index 7bb4570..d05abde 100644
@@ -25,6 +25,7 @@
 #include <xen/irq.h>
 #include <xen/sched.h>
 #include <xen/perfc.h>
+#include <xen/acpi.h>
 
 #include <asm/current.h>
 

xen/arch/arm/vgic.c void vgic_disable_irqs(struct vcpu *v, uint32_t r, int n) · line 314

Quoted 4 lines
xen/arch/arm/vgic.c +1 -0
@@ -310,6 +311,8 @@ void vgic_disable_irqs(struct vcpu *v, uint32_t r, int n)
     }
 }
 
+#define VGIC_ICFG_MASK(intr) ( 1 << ( ( 2 * ( intr % 16 ) ) + 1 ) )

Coding style.

xen/arch/arm/vgic.c void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) · line 328

Quoted 9 lines
xen/arch/arm/vgic.c +2 -0
 void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n)
 {
     struct domain *d = v->domain;
@@ -321,7 +324,23 @@ void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n)
     struct vcpu *v_target;
 
     while ( (i = find_next_bit(&mask, 32, i)) < 32 ) {
+#ifdef CONFIG_ACPI
+        struct vgic_irq_rank *vr = vgic_get_rank(v, n);

The rank is always the same, you can move this out of the while loop.

xen/arch/arm/vgic.c void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) · line 332

Quoted 4 lines
xen/arch/arm/vgic.c +3 -0
+        uint32_t tr;
+
         irq = i + (32 * n);
+        if( ( !acpi_disabled ) && ( n != 0 ) && is_hardware_domain(d) )

Instead of n != 0, I would prefer a more obvious irq >= 32 check

xen/arch/arm/vgic.c void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) · line 336

Quoted 4 lines
xen/arch/arm/vgic.c +4 -0
+        {
+            tr = vr->icfg[i >> 4] ;
+
+            if( ( tr & VGIC_ICFG_MASK(i) ) )

Coding style.

xen/arch/arm/vgic.c void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) · line 339

Quoted 3 lines
xen/arch/arm/vgic.c +3 -0
+                irq_set_type(irq, ACPI_IRQ_TYPE_EDGE_BOTH);
+            else
+                irq_set_type(irq, ACPI_IRQ_TYPE_LEVEL_MASK);

Instead of this ad-hoc ACPI code, I would prefer if we get the irq type and, if it is set to NONE or INVALID, we set it to what is in the r->icfg (only for the hardware_domain of course). If it is set to something other than NONE or INVALID, and it doesn't match what is on r->icfg, then we could print out a warning.

xen/arch/arm/vgic.c void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) · line 343

Quoted 4 lines
xen/arch/arm/vgic.c +4 -0
+        }
+#else
+        irq = i + (32 * n);
+#endif

Please leave the irq = i + (32 * n) out of the #ifdef.

Quoted 6 lines
xen/arch/arm/vgic.c +0 -0
         v_target = d->arch.vgic.handler->get_target_vcpu(v, irq);
         p = irq_to_pending(v_target, irq);
         set_bit(GIC_IRQ_GUEST_ENABLED, &p->status);
Signature · 1 line
2.1.0
#323 lore raw

Re: [PATCH v3 60/62] arm/acpi: Configure interrupts dynamically

In reply to Stefano Stabellini
Quoted 6 lines · Stefano Stabellini
Quoted 5 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Parth Dixit <[email protected]>

Interrupt information is described in DSDT and is not available at the time of booting. Configure the interrupts dynamically when requested by Dom0

Actually wouldn't it make more sense to configure the physical interrupts when dom0 writes to the virtual ICFG registers?

Quoted 82 lines
Quoted 19 lines
---
 xen/arch/arm/vgic.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
xen/arch/arm/vgic.c +1 -0
index 7bb4570..d05abde 100644
@@ -25,6 +25,7 @@
 #include <xen/irq.h>
 #include <xen/sched.h>
 #include <xen/perfc.h>
+#include <xen/acpi.h>
 
 #include <asm/current.h>
 

xen/arch/arm/vgic.c void vgic_disable_irqs(struct vcpu *v, uint32_t r, int n) · line 314

Quoted 4 lines
xen/arch/arm/vgic.c +1 -0
@@ -310,6 +311,8 @@ void vgic_disable_irqs(struct vcpu *v, uint32_t r, int n)
     }
 }
 
+#define VGIC_ICFG_MASK(intr) ( 1 << ( ( 2 * ( intr % 16 ) ) + 1 ) )

Coding style.

xen/arch/arm/vgic.c void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) · line 328

Quoted 9 lines
xen/arch/arm/vgic.c +2 -0
 void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n)
 {
     struct domain *d = v->domain;
@@ -321,7 +324,23 @@ void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n)
     struct vcpu *v_target;
 
     while ( (i = find_next_bit(&mask, 32, i)) < 32 ) {
+#ifdef CONFIG_ACPI
+        struct vgic_irq_rank *vr = vgic_get_rank(v, n);

The rank is always the same, you can move this out of the while loop.

xen/arch/arm/vgic.c void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) · line 332

Quoted 4 lines
xen/arch/arm/vgic.c +3 -0
+        uint32_t tr;
+
         irq = i + (32 * n);
+        if( ( !acpi_disabled ) && ( n != 0 ) && is_hardware_domain(d) )

Instead of n != 0, I would prefer a more obvious irq >= 32 check

xen/arch/arm/vgic.c void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) · line 336

Quoted 4 lines
xen/arch/arm/vgic.c +4 -0
+        {
+            tr = vr->icfg[i >> 4] ;
+
+            if( ( tr & VGIC_ICFG_MASK(i) ) )

Coding style.

xen/arch/arm/vgic.c void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) · line 339

Quoted 3 lines
xen/arch/arm/vgic.c +3 -0
+                irq_set_type(irq, ACPI_IRQ_TYPE_EDGE_BOTH);
+            else
+                irq_set_type(irq, ACPI_IRQ_TYPE_LEVEL_MASK);

Instead of this ad-hoc ACPI code, I would prefer if we get the irq type and, if it is set to NONE or INVALID, we set it to what is in the r->icfg (only for the hardware_domain of course). If it is set to something other than NONE or INVALID, and it doesn't match what is on r->icfg, then we could print out a warning.

xen/arch/arm/vgic.c void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) · line 343

Quoted 4 lines
xen/arch/arm/vgic.c +4 -0
+        }
+#else
+        irq = i + (32 * n);
+#endif

Please leave the irq = i + (32 * n) out of the #ifdef.

Quoted 6 lines
xen/arch/arm/vgic.c +0 -0
         v_target = d->arch.vgic.handler->get_target_vcpu(v, irq);
         p = irq_to_pending(v_target, irq);
         set_bit(GIC_IRQ_GUEST_ENABLED, &p->status);
Signature · 1 line
2.1.0
#324 lore raw

Re: [PATCH v3 60/62] arm/acpi: Configure interrupts dynamically

In reply to shannon.zhao at linaro.org
Quoted 25 lines · On Tue, 17 Nov 2015, [email protected] wrote:

From: Parth Dixit <[email protected]>

Interrupt information is described in DSDT and is not available at the time of booting. Configure the interrupts dynamically when requested by Dom0

---
 xen/arch/arm/vgic.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
xen/arch/arm/vgic.c +1 -0
index 7bb4570..d05abde 100644
@@ -25,6 +25,7 @@
 #include <xen/irq.h>
 #include <xen/sched.h>
 #include <xen/perfc.h>
+#include <xen/acpi.h>
 
 #include <asm/current.h>
 

xen/arch/arm/vgic.c void vgic_disable_irqs(struct vcpu *v, uint32_t r, int n) · line 314

Quoted 4 lines
xen/arch/arm/vgic.c +1 -0
@@ -310,6 +311,8 @@ void vgic_disable_irqs(struct vcpu *v, uint32_t r, int n)
     }
 }
 
+#define VGIC_ICFG_MASK(intr) ( 1 << ( ( 2 * ( intr % 16 ) ) + 1 ) )

Coding style.

xen/arch/arm/vgic.c void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) · line 328

Quoted 9 lines
xen/arch/arm/vgic.c +2 -0
 void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n)
 {
     struct domain *d = v->domain;
@@ -321,7 +324,23 @@ void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n)
     struct vcpu *v_target;
 
     while ( (i = find_next_bit(&mask, 32, i)) < 32 ) {
+#ifdef CONFIG_ACPI
+        struct vgic_irq_rank *vr = vgic_get_rank(v, n);

The rank is always the same, you can move this out of the while loop.

xen/arch/arm/vgic.c void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) · line 332

Quoted 4 lines
xen/arch/arm/vgic.c +3 -0
+        uint32_t tr;
+
         irq = i + (32 * n);
+        if( ( !acpi_disabled ) && ( n != 0 ) && is_hardware_domain(d) )

Instead of n != 0, I would prefer a more obvious irq >= 32 check

xen/arch/arm/vgic.c void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) · line 336

Quoted 4 lines
xen/arch/arm/vgic.c +4 -0
+        {
+            tr = vr->icfg[i >> 4] ;
+
+            if( ( tr & VGIC_ICFG_MASK(i) ) )

Coding style.

xen/arch/arm/vgic.c void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) · line 339

Quoted 3 lines
xen/arch/arm/vgic.c +3 -0
+                irq_set_type(irq, ACPI_IRQ_TYPE_EDGE_BOTH);
+            else
+                irq_set_type(irq, ACPI_IRQ_TYPE_LEVEL_MASK);

Instead of this ad-hoc ACPI code, I would prefer if we get the irq type and, if it is set to NONE or INVALID, we set it to what is in the r->icfg (only for the hardware_domain of course). If it is set to something other than NONE or INVALID, and it doesn't match what is on r->icfg, then we could print out a warning.

xen/arch/arm/vgic.c void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) · line 343

Quoted 4 lines
xen/arch/arm/vgic.c +4 -0
+        }
+#else
+        irq = i + (32 * n);
+#endif

Please leave the irq = i + (32 * n) out of the #ifdef.

Quoted 6 lines
xen/arch/arm/vgic.c +0 -0
         v_target = d->arch.vgic.handler->get_target_vcpu(v, irq);
         p = irq_to_pending(v_target, irq);
         set_bit(GIC_IRQ_GUEST_ENABLED, &p->status);
Signature · 1 line
2.1.0
#325 lore raw

PATCH v3 60/62 arm/acpi: Configure interrupts dynamically

In reply to shannon.zhao at linaro.org

Hi Shannon,

Quoted 5 lines · shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

Interrupt information is described in DSDT and is not available at the time of booting. Configure the interrupts dynamically when requested by Dom0

Missing ".".

As said on a previous version of this patch [1], I'd like to keep the ACPI changes very contained to Xen boot. Your change is not ACPI specific and could be used for DT.

Quoted 29 lines
---
 xen/arch/arm/vgic.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
xen/arch/arm/vgic.c +3 -0
index 7bb4570..d05abde 100644
@@ -25,6 +25,7 @@
 #include <xen/irq.h>
 #include <xen/sched.h>
 #include <xen/perfc.h>
+#include <xen/acpi.h>
 
 #include <asm/current.h>
 
@@ -310,6 +311,8 @@ void vgic_disable_irqs(struct vcpu *v, uint32_t r, int n)
     }
 }
 
+#define VGIC_ICFG_MASK(intr) ( 1 << ( ( 2 * ( intr % 16 ) ) + 1 ) )
+
 void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n)
 {
     struct domain *d = v->domain;

xen/arch/arm/vgic.c void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) · line 332

Quoted 9 lines
xen/arch/arm/vgic.c +5 -0
@@ -321,7 +324,23 @@ void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n)
     struct vcpu *v_target;
 
     while ( (i = find_next_bit(&mask, 32, i)) < 32 ) {
+#ifdef CONFIG_ACPI
+        struct vgic_irq_rank *vr = vgic_get_rank(v, n);
+        uint32_t tr;
+
         irq = i + (32 * n);
+        if( ( !acpi_disabled ) && ( n != 0 ) && is_hardware_domain(d) )

You need to add a comment explaining the ( n != 0 ) i.e we don't SGIs and PPIs are RO. It's implementation defined for PPI but it's preferable to let Xen take care of it.

Also, we should set the type only for IRQ assigned to DOM0 (i.e p->desc != NULL). With your current solution, DOM0 may change the configuration of the serial IRQ by mistake and take down Xen because the physical IRQ is enabled and the behavior will be unpredictable.

xen/arch/arm/vgic.c void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) · line 339

Quoted 7 lines
xen/arch/arm/vgic.c +7 -0
+        {
+            tr = vr->icfg[i >> 4] ;
+
+            if( ( tr & VGIC_ICFG_MASK(i) ) )
+                irq_set_type(irq, ACPI_IRQ_TYPE_EDGE_BOTH);
+            else
+                irq_set_type(irq, ACPI_IRQ_TYPE_LEVEL_MASK);

Given that only SPI can be configured it would have been better to call irq_set_type.

Although, those 2 functions don't do what you think. They are setting the type internally in Xen but don't change the GIC interrupt configuration register.

Lastly, they will fail because the configuration has been set earlier (as you did in patch #55)

xen/arch/arm/vgic.c void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) · line 346

Quoted 8 lines
xen/arch/arm/vgic.c +4 -0
+        }
+#else
+        irq = i + (32 * n);
+#endif
         v_target = d->arch.vgic.handler->get_target_vcpu(v, irq);
         p = irq_to_pending(v_target, irq);
         set_bit(GIC_IRQ_GUEST_ENABLED, &p->status);

Regards,

[1] http://lists.xen.org/archives/html/xen-devel/2015-06/msg01128.html

Signature · 1 line
Julien Grall
#326 lore raw

PATCH v3 60/62 arm/acpi: Configure interrupts dynamically

Hi,

Quoted 71 lines · Julien Grall

Hi Shannon,

Quoted 5 lines · shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

Interrupt information is described in DSDT and is not available at the time of booting. Configure the interrupts dynamically when requested by Dom0

Missing ".".

As said on a previous version of this patch [1], I'd like to keep the ACPI changes very contained to Xen boot. Your change is not ACPI specific and could be used for DT.

Quoted 29 lines
---
 xen/arch/arm/vgic.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
xen/arch/arm/vgic.c +3 -0
index 7bb4570..d05abde 100644
@@ -25,6 +25,7 @@
 #include <xen/irq.h>
 #include <xen/sched.h>
 #include <xen/perfc.h>
+#include <xen/acpi.h>
 
 #include <asm/current.h>
 
@@ -310,6 +311,8 @@ void vgic_disable_irqs(struct vcpu *v, uint32_t r, int n)
     }
 }
 
+#define VGIC_ICFG_MASK(intr) ( 1 << ( ( 2 * ( intr % 16 ) ) + 1 ) )
+
 void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n)
 {
     struct domain *d = v->domain;

xen/arch/arm/vgic.c void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) · line 332

Quoted 9 lines
xen/arch/arm/vgic.c +5 -0
@@ -321,7 +324,23 @@ void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n)
     struct vcpu *v_target;
 
     while ( (i = find_next_bit(&mask, 32, i)) < 32 ) {
+#ifdef CONFIG_ACPI
+        struct vgic_irq_rank *vr = vgic_get_rank(v, n);
+        uint32_t tr;
+
         irq = i + (32 * n);
+        if( ( !acpi_disabled ) && ( n != 0 ) && is_hardware_domain(d) )

You need to add a comment explaining the ( n != 0 ) i.e we don't SGIs and PPIs are RO. It's implementation defined for PPI but it's preferable to let Xen take care of it.

Also, we should set the type only for IRQ assigned to DOM0 (i.e p->desc != NULL). With your current solution, DOM0 may change the configuration of the serial IRQ by mistake and take down Xen because the physical IRQ is enabled and the behavior will be unpredictable.

xen/arch/arm/vgic.c void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) · line 339

Quoted 7 lines
xen/arch/arm/vgic.c +7 -0
+        {
+            tr = vr->icfg[i >> 4] ;
+
+            if( ( tr & VGIC_ICFG_MASK(i) ) )
+                irq_set_type(irq, ACPI_IRQ_TYPE_EDGE_BOTH);
+            else
+                irq_set_type(irq, ACPI_IRQ_TYPE_LEVEL_MASK);
Quoted 7 lines

Given that only SPI can be configured it would have been better to call irq_set_type.

Although, those 2 functions don't do what you think. They are setting the type internally in Xen but don't change the GIC interrupt configuration register.

Here it wants to set the type according to the value of GIC ICFG.

I don't know this well. Does it need to set the type here when Dom0 configures the interrupts since I have set them as ACPI_IRQ_TYPE_NONE in patch 55?

How about following way?
1) In patch 55, it only permit the access of Dom0 to those irqs, not set the type.
2) Then in this function or in the handler of writing GIC ICFG, check if the irq is permitted and set the irq type.

Quoted 16 lines

Lastly, they will fail because the configuration has been set earlier (as you did in patch #55)

xen/arch/arm/vgic.c void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) · line 346

Quoted 8 lines
xen/arch/arm/vgic.c +4 -0
+        }
+#else
+        irq = i + (32 * n);
+#endif
         v_target = d->arch.vgic.handler->get_target_vcpu(v, irq);
         p = irq_to_pending(v_target, irq);
         set_bit(GIC_IRQ_GUEST_ENABLED, &p->status);

Regards,

[1] http://lists.xen.org/archives/html/xen-devel/2015-06/msg01128.html

Signature · 1 line
Shannon
#327 lore raw

PATCH v3 60/62 arm/acpi: Configure interrupts dynamically

Quoted 87 lines · Shannon Zhao

Hi,

Quoted 71 lines · Julien Grall

Hi Shannon,

Quoted 5 lines · shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

Interrupt information is described in DSDT and is not available at the time of booting. Configure the interrupts dynamically when requested by Dom0

Missing ".".

As said on a previous version of this patch [1], I'd like to keep the ACPI changes very contained to Xen boot. Your change is not ACPI specific and could be used for DT.

Quoted 29 lines
---
 xen/arch/arm/vgic.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
xen/arch/arm/vgic.c +3 -0
index 7bb4570..d05abde 100644
@@ -25,6 +25,7 @@
 #include <xen/irq.h>
 #include <xen/sched.h>
 #include <xen/perfc.h>
+#include <xen/acpi.h>
 
 #include <asm/current.h>
 
@@ -310,6 +311,8 @@ void vgic_disable_irqs(struct vcpu *v, uint32_t r, int n)
     }
 }
 
+#define VGIC_ICFG_MASK(intr) ( 1 << ( ( 2 * ( intr % 16 ) ) + 1 ) )
+
 void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n)
 {
     struct domain *d = v->domain;

xen/arch/arm/vgic.c void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) · line 332

Quoted 9 lines
xen/arch/arm/vgic.c +5 -0
@@ -321,7 +324,23 @@ void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n)
     struct vcpu *v_target;
 
     while ( (i = find_next_bit(&mask, 32, i)) < 32 ) {
+#ifdef CONFIG_ACPI
+        struct vgic_irq_rank *vr = vgic_get_rank(v, n);
+        uint32_t tr;
+
         irq = i + (32 * n);
+        if( ( !acpi_disabled ) && ( n != 0 ) && is_hardware_domain(d) )

You need to add a comment explaining the ( n != 0 ) i.e we don't SGIs and PPIs are RO. It's implementation defined for PPI but it's preferable to let Xen take care of it.

Also, we should set the type only for IRQ assigned to DOM0 (i.e p->desc != NULL). With your current solution, DOM0 may change the configuration of the serial IRQ by mistake and take down Xen because the physical IRQ is enabled and the behavior will be unpredictable.

xen/arch/arm/vgic.c void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) · line 339

Quoted 7 lines
xen/arch/arm/vgic.c +7 -0
+        {
+            tr = vr->icfg[i >> 4] ;
+
+            if( ( tr & VGIC_ICFG_MASK(i) ) )
+                irq_set_type(irq, ACPI_IRQ_TYPE_EDGE_BOTH);
+            else
+                irq_set_type(irq, ACPI_IRQ_TYPE_LEVEL_MASK);
Quoted 7 lines

Given that only SPI can be configured it would have been better to call irq_set_type.

Although, those 2 functions don't do what you think. They are setting the type internally in Xen but don't change the GIC interrupt configuration register.

Here it wants to set the type according to the value of GIC ICFG.

I don't know this well. Does it need to set the type here when Dom0 configures the interrupts since I have set them as ACPI_IRQ_TYPE_NONE in patch 55?

Quoted 5 lines

How about following way?
1) In patch 55, it only permit the access of Dom0 to those irqs, not set the type.
2) Then in this function or in the handler of writing GIC ICFG, check if the irq is permitted and set the irq type.

Sounds good

Quoted 20 lines
Quoted 16 lines

Lastly, they will fail because the configuration has been set earlier (as you did in patch #55)

xen/arch/arm/vgic.c void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) · line 346

Quoted 8 lines
xen/arch/arm/vgic.c +4 -0
+        }
+#else
+        irq = i + (32 * n);
+#endif
         v_target = d->arch.vgic.handler->get_target_vcpu(v, irq);
         p = irq_to_pending(v_target, irq);
         set_bit(GIC_IRQ_GUEST_ENABLED, &p->status);

Regards,

[1] http://lists.xen.org/archives/html/xen-devel/2015-06/msg01128.html

Signature · 1 line
Shannon
#328 lore raw

Re: [PATCH v3 60/62] arm/acpi: Configure interrupts dynamically

In reply to Shannon Zhao
Quoted 87 lines · Shannon Zhao

Hi,

Quoted 71 lines · Julien Grall

Hi Shannon,

Quoted 5 lines · On 17/11/15 09:40, [email protected] wrote:

From: Parth Dixit <[email protected]>

Interrupt information is described in DSDT and is not available at the time of booting. Configure the interrupts dynamically when requested by Dom0

Missing ".".

As said on a previous version of this patch [1], I'd like to keep the ACPI changes very contained to Xen boot. Your change is not ACPI specific and could be used for DT.

Quoted 29 lines
---
 xen/arch/arm/vgic.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
xen/arch/arm/vgic.c +3 -0
index 7bb4570..d05abde 100644
@@ -25,6 +25,7 @@
 #include <xen/irq.h>
 #include <xen/sched.h>
 #include <xen/perfc.h>
+#include <xen/acpi.h>
 
 #include <asm/current.h>
 
@@ -310,6 +311,8 @@ void vgic_disable_irqs(struct vcpu *v, uint32_t r, int n)
     }
 }
 
+#define VGIC_ICFG_MASK(intr) ( 1 << ( ( 2 * ( intr % 16 ) ) + 1 ) )
+
 void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n)
 {
     struct domain *d = v->domain;

xen/arch/arm/vgic.c void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) · line 332

Quoted 9 lines
xen/arch/arm/vgic.c +5 -0
@@ -321,7 +324,23 @@ void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n)
     struct vcpu *v_target;
 
     while ( (i = find_next_bit(&mask, 32, i)) < 32 ) {
+#ifdef CONFIG_ACPI
+        struct vgic_irq_rank *vr = vgic_get_rank(v, n);
+        uint32_t tr;
+
         irq = i + (32 * n);
+        if( ( !acpi_disabled ) && ( n != 0 ) && is_hardware_domain(d) )

You need to add a comment explaining the ( n != 0 ) i.e we don't SGIs and PPIs are RO. It's implementation defined for PPI but it's preferable to let Xen take care of it.

Also, we should set the type only for IRQ assigned to DOM0 (i.e p->desc != NULL). With your current solution, DOM0 may change the configuration of the serial IRQ by mistake and take down Xen because the physical IRQ is enabled and the behavior will be unpredictable.

xen/arch/arm/vgic.c void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) · line 339

Quoted 7 lines
xen/arch/arm/vgic.c +7 -0
+        {
+            tr = vr->icfg[i >> 4] ;
+
+            if( ( tr & VGIC_ICFG_MASK(i) ) )
+                irq_set_type(irq, ACPI_IRQ_TYPE_EDGE_BOTH);
+            else
+                irq_set_type(irq, ACPI_IRQ_TYPE_LEVEL_MASK);
Quoted 7 lines

Given that only SPI can be configured it would have been better to call irq_set_type.

Although, those 2 functions don't do what you think. They are setting the type internally in Xen but don't change the GIC interrupt configuration register.

Here it wants to set the type according to the value of GIC ICFG.

I don't know this well. Does it need to set the type here when Dom0 configures the interrupts since I have set them as ACPI_IRQ_TYPE_NONE in patch 55?

Quoted 5 lines

How about following way?
1) In patch 55, it only permit the access of Dom0 to those irqs, not set the type.
2) Then in this function or in the handler of writing GIC ICFG, check if the irq is permitted and set the irq type.

Sounds good

Quoted 20 lines
Quoted 16 lines

Lastly, they will fail because the configuration has been set earlier (as you did in patch #55)

xen/arch/arm/vgic.c void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) · line 346

Quoted 8 lines
xen/arch/arm/vgic.c +4 -0
+        }
+#else
+        irq = i + (32 * n);
+#endif
         v_target = d->arch.vgic.handler->get_target_vcpu(v, irq);
         p = irq_to_pending(v_target, irq);
         set_bit(GIC_IRQ_GUEST_ENABLED, &p->status);

Regards,

[1] http://lists.xen.org/archives/html/xen-devel/2015-06/msg01128.html

Signature · 1 line
Shannon
#329 lore raw

Re: [PATCH v3 60/62] arm/acpi: Configure interrupts dynamically

In reply to Julien Grall

Hi,

Quoted 71 lines · Julien Grall

Hi Shannon,

Quoted 5 lines · On 17/11/15 09:40, [email protected] wrote:

From: Parth Dixit <[email protected]>

Interrupt information is described in DSDT and is not available at the time of booting. Configure the interrupts dynamically when requested by Dom0

Missing ".".

As said on a previous version of this patch [1], I'd like to keep the ACPI changes very contained to Xen boot. Your change is not ACPI specific and could be used for DT.

Quoted 29 lines
---
 xen/arch/arm/vgic.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
xen/arch/arm/vgic.c +3 -0
index 7bb4570..d05abde 100644
@@ -25,6 +25,7 @@
 #include <xen/irq.h>
 #include <xen/sched.h>
 #include <xen/perfc.h>
+#include <xen/acpi.h>
 
 #include <asm/current.h>
 
@@ -310,6 +311,8 @@ void vgic_disable_irqs(struct vcpu *v, uint32_t r, int n)
     }
 }
 
+#define VGIC_ICFG_MASK(intr) ( 1 << ( ( 2 * ( intr % 16 ) ) + 1 ) )
+
 void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n)
 {
     struct domain *d = v->domain;

xen/arch/arm/vgic.c void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) · line 332

Quoted 9 lines
xen/arch/arm/vgic.c +5 -0
@@ -321,7 +324,23 @@ void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n)
     struct vcpu *v_target;
 
     while ( (i = find_next_bit(&mask, 32, i)) < 32 ) {
+#ifdef CONFIG_ACPI
+        struct vgic_irq_rank *vr = vgic_get_rank(v, n);
+        uint32_t tr;
+
         irq = i + (32 * n);
+        if( ( !acpi_disabled ) && ( n != 0 ) && is_hardware_domain(d) )

You need to add a comment explaining the ( n != 0 ) i.e we don't SGIs and PPIs are RO. It's implementation defined for PPI but it's preferable to let Xen take care of it.

Also, we should set the type only for IRQ assigned to DOM0 (i.e p->desc != NULL). With your current solution, DOM0 may change the configuration of the serial IRQ by mistake and take down Xen because the physical IRQ is enabled and the behavior will be unpredictable.

xen/arch/arm/vgic.c void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) · line 339

Quoted 7 lines
xen/arch/arm/vgic.c +7 -0
+        {
+            tr = vr->icfg[i >> 4] ;
+
+            if( ( tr & VGIC_ICFG_MASK(i) ) )
+                irq_set_type(irq, ACPI_IRQ_TYPE_EDGE_BOTH);
+            else
+                irq_set_type(irq, ACPI_IRQ_TYPE_LEVEL_MASK);
Quoted 7 lines

Given that only SPI can be configured it would have been better to call irq_set_type.

Although, those 2 functions don't do what you think. They are setting the type internally in Xen but don't change the GIC interrupt configuration register.

Here it wants to set the type according to the value of GIC ICFG.

I don't know this well. Does it need to set the type here when Dom0 configures the interrupts since I have set them as ACPI_IRQ_TYPE_NONE in patch 55?

How about following way?
1) In patch 55, it only permit the access of Dom0 to those irqs, not set the type.
2) Then in this function or in the handler of writing GIC ICFG, check if the irq is permitted and set the irq type.

Quoted 16 lines

Lastly, they will fail because the configuration has been set earlier (as you did in patch #55)

xen/arch/arm/vgic.c void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) · line 346

Quoted 8 lines
xen/arch/arm/vgic.c +4 -0
+        }
+#else
+        irq = i + (32 * n);
+#endif
         v_target = d->arch.vgic.handler->get_target_vcpu(v, irq);
         p = irq_to_pending(v_target, irq);
         set_bit(GIC_IRQ_GUEST_ENABLED, &p->status);

Regards,

[1] http://lists.xen.org/archives/html/xen-devel/2015-06/msg01128.html

Signature · 1 line
Shannon
#330 lore raw

PATCH v3 61/62 arm/acpi: Add acpi parameter to enable/disable acpi

In reply to shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

ACPI will be disabled by default. Define new command line parameter "acpi" for enabling it.

---
 xen/arch/arm/setup.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
xen/arch/arm/setup.c +22 -0
index 63feadf..1a40323 100644
@@ -59,6 +59,10 @@ static unsigned long opt_xenheap_megabytes __initdata;
 integer_param("xenheap_megabytes", opt_xenheap_megabytes);
 #endif
 
+/* "acpi=force" : Enables acpi */
+static void parse_acpi_param(char *s);
+custom_param("acpi", parse_acpi_param);
+
 static __used void init_done(void)
 {
     free_init_memory();
@@ -84,6 +88,23 @@ static const char * __initdata processor_implementers[] = {
     ['i'] = "Intel Corporation",
 };
 
+static char __initdata acpi_param[10] = "";
+static void __init parse_acpi_param(char *s)
+{
+    /* Save the parameter so it can be propagated to domain0. */
+    safe_strcpy(acpi_param, s);
+
+    /* Interpret the parameter for use within Xen. */
+    if ( !parse_bool(s) )
+    {
+        disable_acpi();
+    }
+    else if ( !strcmp(s, "force") )
+    {
+        acpi_disabled = 0;
+    }
+}
+
 static void __init processor_id(void)
 {
     const char *implementer = "Unknown";
@@ -729,6 +750,7 @@ void __init start_xen(unsigned long boot_phys_offset,
         + (fdt_paddr & ((1 << SECOND_SHIFT) - 1));
     fdt_size = boot_fdt_info(device_tree_flattened, fdt_paddr);
 
+    disable_acpi();
     cmdline = boot_fdt_cmdline(device_tree_flattened);
     printk("Command line: %s\n", cmdline);
     cmdline_parse(cmdline);
Signature · 1 line
2.1.0
#331 lore raw

PATCH v3 61/62 arm/acpi: Add acpi parameter to enable/disable acpi

Hi Shannon,

I would have appreciate if you I had looked on comments made on the series sent by Parth.

Quoted 4 lines · shannon.zhao at linaro.org

From: Parth Dixit <[email protected]>

ACPI will be disabled by default. Define new command line parameter "acpi" for enabling it.

I don't think this is right. We have to be able to boot platform where there is only ACPI provided without adding a command line option.

Overall, it would be better if we follow the same behavior as Linux i.e ACPI is enabled instead of DT unless:
- ACPI has been disabled (acpi=off)
- the DT is not empty (it has more than just a /chosen node) and
ACPI has not been forced to be enabled (acpi=force).

Quoted 23 lines
---
 xen/arch/arm/setup.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
xen/arch/arm/setup.c +4 -0
index 63feadf..1a40323 100644
@@ -59,6 +59,10 @@ static unsigned long opt_xenheap_megabytes __initdata;
 integer_param("xenheap_megabytes", opt_xenheap_megabytes);
 #endif
 
+/* "acpi=force" : Enables acpi */
+static void parse_acpi_param(char *s);
+custom_param("acpi", parse_acpi_param);
+
 static __used void init_done(void)
 {
     free_init_memory();

xen/arch/arm/setup.c static const char * __initdata processor_implementers[] = { · line 95

Quoted 8 lines
xen/arch/arm/setup.c +5 -0
@@ -84,6 +88,23 @@ static const char * __initdata processor_implementers[] = {
     ['i'] = "Intel Corporation",
 };
 
+static char __initdata acpi_param[10] = "";
+static void __init parse_acpi_param(char *s)
+{
+    /* Save the parameter so it can be propagated to domain0. */
+    safe_strcpy(acpi_param, s);

This acpi_param is never used within this series. Please drop it or either implement what the comment claim.

Quoted 17 lines
xen/arch/arm/setup.c +12 -0
+
+    /* Interpret the parameter for use within Xen. */
+    if ( !parse_bool(s) )
+    {
+        disable_acpi();
+    }
+    else if ( !strcmp(s, "force") )
+    {
+        acpi_disabled = 0;
+    }
+}
+
 static void __init processor_id(void)
 {
     const char *implementer = "Unknown";

xen/arch/arm/setup.c void __init start_xen(unsigned long boot_phys_offset, · line 756

Quoted 7 lines
xen/arch/arm/setup.c +1 -0
@@ -729,6 +750,7 @@ void __init start_xen(unsigned long boot_phys_offset,
         + (fdt_paddr & ((1 << SECOND_SHIFT) - 1));
     fdt_size = boot_fdt_info(device_tree_flattened, fdt_paddr);
 
+    disable_acpi();
     cmdline = boot_fdt_cmdline(device_tree_flattened);
     printk("Command line: %s\n", cmdline);
     cmdline_parse(cmdline);

Regards,

Signature · 1 line
Julien Grall
#332 lore raw

PATCH v3 61/62 arm/acpi: Add acpi parameter to enable/disable acpi

Hi,

Quoted 5 lines · Julien Grall

Hi Shannon,

I would have appreciate if you I had looked on comments made on the series sent by Parth.

I do look. But I didn't find "Follow-Ups" ones at [1]. And among the mails which Parth forwarded to me there is no [PATCH v2 37/41]. This is werid.

[1]http://lists.xenproject.org/archives/html/xen-devel/2015-05/msg02227.html

Quoted 6 lines · shannon.zhao at linaro.org
Quoted 4 lines

From: Parth Dixit <[email protected]>

ACPI will be disabled by default. Define new command line parameter "acpi" for enabling it.

Quoted 9 lines

I don't think this is right. We have to be able to boot platform where there is only ACPI provided without adding a command line option.

Overall, it would be better if we follow the same behavior as Linux i.e ACPI is enabled instead of DT unless:
- ACPI has been disabled (acpi=off)
- the DT is not empty (it has more than just a /chosen node) and
ACPI has not been forced to be enabled (acpi=force).

Ok, will add this.

Quoted 62 lines
Quoted 23 lines
---
 xen/arch/arm/setup.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
xen/arch/arm/setup.c +4 -0
index 63feadf..1a40323 100644
@@ -59,6 +59,10 @@ static unsigned long opt_xenheap_megabytes __initdata;
 integer_param("xenheap_megabytes", opt_xenheap_megabytes);
 #endif
 
+/* "acpi=force" : Enables acpi */
+static void parse_acpi_param(char *s);
+custom_param("acpi", parse_acpi_param);
+
 static __used void init_done(void)
 {
     free_init_memory();

xen/arch/arm/setup.c static const char * __initdata processor_implementers[] = { · line 95

Quoted 8 lines
xen/arch/arm/setup.c +5 -0
@@ -84,6 +88,23 @@ static const char * __initdata processor_implementers[] = {
     ['i'] = "Intel Corporation",
 };
 
+static char __initdata acpi_param[10] = "";
+static void __init parse_acpi_param(char *s)
+{
+    /* Save the parameter so it can be propagated to domain0. */
+    safe_strcpy(acpi_param, s);

This acpi_param is never used within this series. Please drop it or either implement what the comment claim.

Quoted 17 lines
xen/arch/arm/setup.c +12 -0
+
+    /* Interpret the parameter for use within Xen. */
+    if ( !parse_bool(s) )
+    {
+        disable_acpi();
+    }
+    else if ( !strcmp(s, "force") )
+    {
+        acpi_disabled = 0;
+    }
+}
+
 static void __init processor_id(void)
 {
     const char *implementer = "Unknown";

xen/arch/arm/setup.c void __init start_xen(unsigned long boot_phys_offset, · line 756

Quoted 7 lines
xen/arch/arm/setup.c +1 -0
@@ -729,6 +750,7 @@ void __init start_xen(unsigned long boot_phys_offset,
         + (fdt_paddr & ((1 << SECOND_SHIFT) - 1));
     fdt_size = boot_fdt_info(device_tree_flattened, fdt_paddr);
 
+    disable_acpi();
     cmdline = boot_fdt_cmdline(device_tree_flattened);
     printk("Command line: %s\n", cmdline);
     cmdline_parse(cmdline);

Regards,

Signature · 1 line
Shannon
#333 lore raw

PATCH v3 61/62 arm/acpi: Add acpi parameter to enable/disable acpi

Quoted 11 lines · Shannon Zhao

Hi,

Quoted 5 lines · Julien Grall

Hi Shannon,

I would have appreciate if you I had looked on comments made on the series sent by Parth.

I do look. But I didn't find "Follow-Ups" ones at [1]. And among the mails which Parth forwarded to me there is no [PATCH v2 37/41]. This is werid.

Sorry, it looks like the xen-devel archive didn't record it. I know that some mails are missing time to time.

Give a look to:

http://www.gossamer-threads.com/lists/xen/devel/406613

Signature · 1 line
Julien Grall
#334 lore raw

Re: [PATCH v3 61/62] arm/acpi: Add acpi parameter to enable/disable acpi

In reply to Shannon Zhao
Quoted 11 lines · Shannon Zhao

Hi,

Quoted 5 lines · Julien Grall

Hi Shannon,

I would have appreciate if you I had looked on comments made on the series sent by Parth.

I do look. But I didn't find "Follow-Ups" ones at [1]. And among the mails which Parth forwarded to me there is no [PATCH v2 37/41]. This is werid.

Sorry, it looks like the xen-devel archive didn't record it. I know that some mails are missing time to time.

Give a look to:

http://www.gossamer-threads.com/lists/xen/devel/406613

Signature · 1 line
Julien Grall
#335 lore raw

Re: [PATCH v3 61/62] arm/acpi: Add acpi parameter to enable/disable acpi

In reply to Julien Grall

Hi,

Quoted 5 lines · Julien Grall

Hi Shannon,

I would have appreciate if you I had looked on comments made on the series sent by Parth.

I do look. But I didn't find "Follow-Ups" ones at [1]. And among the mails which Parth forwarded to me there is no [PATCH v2 37/41]. This is werid.

[1]http://lists.xenproject.org/archives/html/xen-devel/2015-05/msg02227.html

Quoted 6 lines · On 17/11/15 09:41, [email protected] wrote:
Quoted 4 lines

From: Parth Dixit <[email protected]>

ACPI will be disabled by default. Define new command line parameter "acpi" for enabling it.

Quoted 9 lines

I don't think this is right. We have to be able to boot platform where there is only ACPI provided without adding a command line option.

Overall, it would be better if we follow the same behavior as Linux i.e ACPI is enabled instead of DT unless:
- ACPI has been disabled (acpi=off)
- the DT is not empty (it has more than just a /chosen node) and
ACPI has not been forced to be enabled (acpi=force).

Ok, will add this.

Quoted 62 lines
Quoted 23 lines
---
 xen/arch/arm/setup.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
xen/arch/arm/setup.c +4 -0
index 63feadf..1a40323 100644
@@ -59,6 +59,10 @@ static unsigned long opt_xenheap_megabytes __initdata;
 integer_param("xenheap_megabytes", opt_xenheap_megabytes);
 #endif
 
+/* "acpi=force" : Enables acpi */
+static void parse_acpi_param(char *s);
+custom_param("acpi", parse_acpi_param);
+
 static __used void init_done(void)
 {
     free_init_memory();

xen/arch/arm/setup.c static const char * __initdata processor_implementers[] = { · line 95

Quoted 8 lines
xen/arch/arm/setup.c +5 -0
@@ -84,6 +88,23 @@ static const char * __initdata processor_implementers[] = {
     ['i'] = "Intel Corporation",
 };
 
+static char __initdata acpi_param[10] = "";
+static void __init parse_acpi_param(char *s)
+{
+    /* Save the parameter so it can be propagated to domain0. */
+    safe_strcpy(acpi_param, s);

This acpi_param is never used within this series. Please drop it or either implement what the comment claim.

Quoted 17 lines
xen/arch/arm/setup.c +12 -0
+
+    /* Interpret the parameter for use within Xen. */
+    if ( !parse_bool(s) )
+    {
+        disable_acpi();
+    }
+    else if ( !strcmp(s, "force") )
+    {
+        acpi_disabled = 0;
+    }
+}
+
 static void __init processor_id(void)
 {
     const char *implementer = "Unknown";

xen/arch/arm/setup.c void __init start_xen(unsigned long boot_phys_offset, · line 756

Quoted 7 lines
xen/arch/arm/setup.c +1 -0
@@ -729,6 +750,7 @@ void __init start_xen(unsigned long boot_phys_offset,
         + (fdt_paddr & ((1 << SECOND_SHIFT) - 1));
     fdt_size = boot_fdt_info(device_tree_flattened, fdt_paddr);
 
+    disable_acpi();
     cmdline = boot_fdt_cmdline(device_tree_flattened);
     printk("Command line: %s\n", cmdline);
     cmdline_parse(cmdline);

Regards,

Signature · 1 line
Shannon
#336 lore raw

Re: [PATCH v3 61/62] arm/acpi: Add acpi parameter to enable/disable acpi

In reply to shannon.zhao at linaro.org

Hi Shannon,

I would have appreciate if you I had looked on comments made on the series sent by Parth.

Quoted 4 lines · On 17/11/15 09:41, [email protected] wrote:

From: Parth Dixit <[email protected]>

ACPI will be disabled by default. Define new command line parameter "acpi" for enabling it.

I don't think this is right. We have to be able to boot platform where there is only ACPI provided without adding a command line option.

Overall, it would be better if we follow the same behavior as Linux i.e ACPI is enabled instead of DT unless:
- ACPI has been disabled (acpi=off)
- the DT is not empty (it has more than just a /chosen node) and
ACPI has not been forced to be enabled (acpi=force).

Quoted 23 lines
---
 xen/arch/arm/setup.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
xen/arch/arm/setup.c +4 -0
index 63feadf..1a40323 100644
@@ -59,6 +59,10 @@ static unsigned long opt_xenheap_megabytes __initdata;
 integer_param("xenheap_megabytes", opt_xenheap_megabytes);
 #endif
 
+/* "acpi=force" : Enables acpi */
+static void parse_acpi_param(char *s);
+custom_param("acpi", parse_acpi_param);
+
 static __used void init_done(void)
 {
     free_init_memory();

xen/arch/arm/setup.c static const char * __initdata processor_implementers[] = { · line 95

Quoted 8 lines
xen/arch/arm/setup.c +5 -0
@@ -84,6 +88,23 @@ static const char * __initdata processor_implementers[] = {
     ['i'] = "Intel Corporation",
 };
 
+static char __initdata acpi_param[10] = "";
+static void __init parse_acpi_param(char *s)
+{
+    /* Save the parameter so it can be propagated to domain0. */
+    safe_strcpy(acpi_param, s);

This acpi_param is never used within this series. Please drop it or either implement what the comment claim.

Quoted 17 lines
xen/arch/arm/setup.c +12 -0
+
+    /* Interpret the parameter for use within Xen. */
+    if ( !parse_bool(s) )
+    {
+        disable_acpi();
+    }
+    else if ( !strcmp(s, "force") )
+    {
+        acpi_disabled = 0;
+    }
+}
+
 static void __init processor_id(void)
 {
     const char *implementer = "Unknown";

xen/arch/arm/setup.c void __init start_xen(unsigned long boot_phys_offset, · line 756

Quoted 7 lines
xen/arch/arm/setup.c +1 -0
@@ -729,6 +750,7 @@ void __init start_xen(unsigned long boot_phys_offset,
         + (fdt_paddr & ((1 << SECOND_SHIFT) - 1));
     fdt_size = boot_fdt_info(device_tree_flattened, fdt_paddr);
 
+    disable_acpi();
     cmdline = boot_fdt_cmdline(device_tree_flattened);
     printk("Command line: %s\n", cmdline);
     cmdline_parse(cmdline);

Regards,

Signature · 1 line
Julien Grall
#337 lore raw

PATCH v3 62/62 xen/arm64: Add ACPI support

In reply to shannon.zhao at linaro.org

From: Naresh Bhat <[email protected]>

Add ACPI support on arm64 xen hypervisor. Enable EFI support on ARM.

---
 config/arm64.mk              | 1 +
 xen/common/efi/runtime.c     | 2 +-
 xen/include/asm-arm/config.h | 5 +++++
 3 files changed, 7 insertions(+), 1 deletion(-)
config/arm64.mk +1 -0
index c5deb4e..c6a040b 100644
@@ -11,6 +11,7 @@ HAS_CADENCE_UART := y
 HAS_NS16550 := y
 HAS_MEM_ACCESS := y
 HAS_GICV3 := y
+HAS_ACPI := y
 
 # Use only if calling $(LD) directly.
 LDFLAGS_DIRECT += -EL
xen/common/efi/runtime.c +1 -1
index ae87557..7748056 100644
@@ -11,7 +11,7 @@ DEFINE_XEN_GUEST_HANDLE(CHAR16);
 #ifndef COMPAT
 
 #ifdef CONFIG_ARM  /* Disabled until runtime services implemented */
-const bool_t efi_enabled = 0;
+const bool_t efi_enabled = 1;
 #else
 # include <asm/i387.h>
 # include <asm/xstate.h>
xen/include/asm-arm/config.h +5 -0
index 817c216..e87fd27 100644
@@ -33,6 +33,11 @@
 
 #define CONFIG_ARM_L1_CACHE_SHIFT 7 /* XXX */
 
+#if defined(CONFIG_ARM_64)
+#define CONFIG_ACPI 1
+#define CONFIG_ACPI_BOOT 1
+#endif
+
 #define CONFIG_SMP 1
 
 #define CONFIG_VIDEO 1
Signature · 1 line
2.1.0