From: Ulrich Wulff <[email protected]>

Clear HCR_EL2.FB if there are only single CPU cells.
Set HCR_EL2.FB once the hypervisor is disabled.

Signed-off-by: Ulrich wulff <[email protected]>
Signed-off-by: Sebastian Andrzej Siewior <[email protected]>
---
 hypervisor/control.c | 35 ++++++++++++++++++++++++++++-------
 1 file changed, 28 insertions(+), 7 deletions(-)

diff --git a/hypervisor/control.c b/hypervisor/control.c
index bb54b01fdead9..a7bcd060ab0ed 100644
--- a/hypervisor/control.c
+++ b/hypervisor/control.c
@@ -413,17 +413,11 @@ static int cell_create(struct per_cpu *cpu_data, unsigned 
long config_address)
        struct unit *unit;
        void *cfg_mapping;
        int err;
-       u64 hcr_el2;
 
        /* We do not support creation over non-root cells. */
        if (cpu_data->public.cell != &root_cell)
                return -EPERM;
 
-       /* reset the FB bit in HCR_EL2 */
-       arm_read_sysreg(HCR_EL2, hcr_el2);
-       hcr_el2 &= ~HCR_FB_BIT;
-       arm_write_sysreg(HCR_EL2, hcr_el2);
-
        cell_suspend(&root_cell);
 
        if (!cell_reconfig_ok(NULL)) {
@@ -629,7 +623,8 @@ static int cell_start(struct per_cpu *cpu_data, unsigned 
long id)
        const struct jailhouse_memory *mem;
        unsigned int cpu, n;
        struct cell *cell;
-       int err;
+       int err, nrrootcpus;
+       u64 hcr_el2;
 
        err = cell_management_prologue(CELL_START, cpu_data, id, &cell);
        if (err)
@@ -673,6 +668,25 @@ static int cell_start(struct per_cpu *cpu_data, unsigned 
long id)
        pci_cell_reset(cell);
        arch_cell_reset(cell);
 
+       /* count the number of root cell cpus */
+       nrrootcpus = 0;
+       for_each_cpu(cpu, root_cell.cpu_set) {
+               nrrootcpus ++;
+       }
+       if (nrrootcpus == 1) {
+               printk("Reset FB Bit in hcr_el2\n");
+
+               /* reset the FB bit in HCR_EL2 */
+               arm_read_sysreg(HCR_EL2, hcr_el2);
+               hcr_el2 &= ~HCR_FB_BIT;
+               arm_write_sysreg(HCR_EL2, hcr_el2);
+
+       } else {
+               printk("Number of cpus for root cell is %d.\n");
+               pritnk("FB bit in hcr_el2 can not be resetted in this case.\n");
+               printk("Create more cells to reduce the number of cpus for the 
root cell to 1.\n", nrrootcpus);
+       }
+
        for_each_cpu(cpu, cell->cpu_set) {
                public_per_cpu(cpu)->failed = false;
                arch_reset_cpu(cpu);
@@ -812,6 +826,7 @@ static int hypervisor_disable(struct per_cpu *cpu_data)
        unsigned int this_cpu = cpu_data->public.cpu_id;
        unsigned int cpu;
        int state, ret;
+       u64 hcr_el2;
 
        /* We do not support shutdown over non-root cells. */
        if (cpu_data->public.cell != &root_cell)
@@ -843,6 +858,12 @@ static int hypervisor_disable(struct per_cpu *cpu_data)
         */
        spin_lock(&shutdown_lock);
 
+       /* set the FB bit in HCR_EL2 */
+       arm_read_sysreg(HCR_EL2, hcr_el2);
+       hcr_el2 |= HCR_FB_BIT;
+       arm_write_sysreg(HCR_EL2, hcr_el2);
+       printk("Set the FB bit in HCR_EL2\n");
+
        if (cpu_data->public.shutdown_state == SHUTDOWN_NONE) {
                state = num_cells == 1 ? SHUTDOWN_STARTED : -EBUSY;
                for_each_cpu(cpu, root_cell.cpu_set)
-- 
2.40.1

-- 
You received this message because you are subscribed to the Google Groups 
"Jailhouse" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jailhouse-dev/20230602074808.1383333-3-bigeasy%40linutronix.de.

Reply via email to