This patch contains a few general comments in the source code of the
arch subsystem.

Signed-off-by: Claudio Scordino <[email protected]>
---
 hypervisor/arch/arm/entry.S              |  8 +++++++-
 hypervisor/arch/arm/include/asm/percpu.h |  3 +++
 hypervisor/arch/x86/apic.c               | 30 +++++++++++++++++++++++++++++-
 hypervisor/arch/x86/control.c            | 13 +++++++++++++
 hypervisor/arch/x86/entry.S              |  8 +++++++-
 hypervisor/arch/x86/include/asm/cell.h   |  2 +-
 hypervisor/arch/x86/setup.c              |  4 ++++
 hypervisor/arch/x86/vmx.c                |  8 ++++++++
 8 files changed, 72 insertions(+), 4 deletions(-)

diff --git a/hypervisor/arch/arm/entry.S b/hypervisor/arch/arm/entry.S
index 8c53edc..c990e0a 100644
--- a/hypervisor/arch/arm/entry.S
+++ b/hypervisor/arch/arm/entry.S
@@ -15,7 +15,13 @@
 #include <asm/percpu.h>
 #include <asm/processor.h>
 
-/* Entry point for Linux loader module on JAILHOUSE_ENABLE */
+/**
+ * Entry point for Linux loader module on JAILHOUSE_ENABLE.
+ *
+ * This code locates the per_cpu region for a given cpu_id, stores the Linux
+ * stack pointer and cpu_id in it, sets the Jailhouse stack, and calls the
+ * architecture-independent entry() function, passing it a pointer to cpu_data.
+ */
        .text
        .globl arch_entry
 arch_entry:
diff --git a/hypervisor/arch/arm/include/asm/percpu.h 
b/hypervisor/arch/arm/include/asm/percpu.h
index 97f902e..4d39ffa 100644
--- a/hypervisor/arch/arm/include/asm/percpu.h
+++ b/hypervisor/arch/arm/include/asm/percpu.h
@@ -31,7 +31,10 @@
        (BITS_PER_LONG - __builtin_clzl(sizeof(struct per_cpu) - 1))
 
 struct per_cpu {
+       /** Stack used while in hypervisor mode. */
        u8 stack[PAGE_SIZE];
+
+       /** Linux stack pointer, used for handover to hypervisor. */
        unsigned long linux_sp;
        unsigned long linux_ret;
        unsigned long linux_flags;
diff --git a/hypervisor/arch/x86/apic.c b/hypervisor/arch/x86/apic.c
index e37ecda..c1439f0 100644
--- a/hypervisor/arch/x86/apic.c
+++ b/hypervisor/arch/x86/apic.c
@@ -23,7 +23,29 @@
 
 #define XAPIC_REG(x2apic_reg)          ((x2apic_reg) << 4)
 
+ /**
+  * Modern x86 processors are equipped with a "local advanced programmable
+  * interrupt controller" (LAPIC) that handles delivery of inter-processor
+  * interrupts (IPIs) as well as external interrupts that the I/O APIC, which
+  * is part of the system's chipset, generates.
+  *
+  * The LAPIC can work in two modes
+  * - xAPIC: programmed via memory mapped I/O (MMIO)
+  * - x2APIC: programmed throughs model-specific registers (MSRs) and
+  *   backward-compatible with xAPIC.
+  *
+  * Currently, Jailhouse virtualizes the LAPIC only, while moderates access to
+  * the I/O APIC.
+  */
+
 bool using_x2apic;
+
+/**
+ * Mapping from the apic_id to the cpu_id.
+ * Used to enforce isolation by preventing a CPU from sending an IPI to a CPU
+ * which is not in its own CPU set.
+ * @note See apic_send_ipi()
+ */
 u8 apic_to_cpu_id[] = { [0 ... APIC_MAX_PHYS_ID] = CPU_ID_INVALID };
 
 /* Initialized for x2APIC, adjusted for xAPIC during init */
@@ -54,7 +76,7 @@ static struct {
        u32 (*read)(unsigned int reg);
        u32 (*read_id)(void);
        void (*write)(unsigned int reg, u32 val);
-       void (*send_ipi)(u32 apic_id, u32 icr_lo);
+       void (*send_ipi)(u32 apic_id, u32 icr_lo); /* send_x*apic_ipi() */
 } apic_ops;
 
 static u32 read_xapic(unsigned int reg)
@@ -163,13 +185,16 @@ int apic_init(void)
        unsigned long apicbase = read_msr(MSR_IA32_APICBASE);
        int err;
 
+       /* Check if x2APIC mode of LAPIC is enabled: */
        if (apicbase & APIC_BASE_EXTD) {
+               /* x2APIC mode: */
                apic_ops.read = read_x2apic;
                apic_ops.read_id = read_x2apic_id;
                apic_ops.write = write_x2apic;
                apic_ops.send_ipi = send_x2apic_ipi;
                using_x2apic = true;
        } else if (apicbase & APIC_BASE_EN) {
+               /* xAPIC mode: */
                xapic_page = page_alloc(&remap_pool, 1);
                if (!xapic_page)
                        return trace_error(-ENOMEM);
@@ -359,6 +384,9 @@ static bool apic_valid_ipi_mode(u32 lo_val)
        return true;
 }
 
+/**
+ * Send an IPI only if the recipient is in the sender's CPU set.
+ */
 static void apic_send_ipi(unsigned int target_cpu_id, u32 orig_icr_hi,
                          u32 icr_lo)
 {
diff --git a/hypervisor/arch/x86/control.c b/hypervisor/arch/x86/control.c
index 46bf2cb..376b8be 100644
--- a/hypervisor/arch/x86/control.c
+++ b/hypervisor/arch/x86/control.c
@@ -148,6 +148,17 @@ void arch_shutdown(void)
        ioapic_shutdown();
 }
 
+/**
+ * CPU suspension is used during maintenance operations on one of the
+ * cells. In that case, a specific CPU of the root cell issues a request to
+ * suspend all CPUs of some cell, the root cell or some non-root cell.
+ * Suspension works by sending those CPUs (in case of the root cell, the
+ * caller CPU is excluded) a maintenance signal (NMI on x86, SGI_EVENT on
+ * ARM) and sets a per-CPU flag to trigger the suspension. The target CPU
+ * will leave the guest and handle that request in the event loop
+ * (x86_check_events, check_events). Suspension is a simple busy-wait loop
+ * in hypervisor mode, because it usually doesn't take very long.
+ */
 void arch_suspend_cpu(unsigned int cpu_id)
 {
        struct per_cpu *target_data = per_cpu(cpu_id);
@@ -161,8 +172,10 @@ void arch_suspend_cpu(unsigned int cpu_id)
        spin_unlock(&target_data->control_lock);
 
        if (!target_suspended) {
+               /* Signal a NMI to each CPU */
                apic_send_nmi_ipi(target_data);
 
+               /* Wait for target_data->cpu_suspend...*/
                while (!target_data->cpu_suspended)
                        cpu_relax();
        }
diff --git a/hypervisor/arch/x86/entry.S b/hypervisor/arch/x86/entry.S
index 986bfee..08a1029 100644
--- a/hypervisor/arch/x86/entry.S
+++ b/hypervisor/arch/x86/entry.S
@@ -12,7 +12,13 @@
 
 #include <asm/asm-defines.h>
 
-/* Entry point for Linux loader module on JAILHOUSE_ENABLE */
+/**
+ * Entry point for Linux loader module on JAILHOUSE_ENABLE.
+ *
+ * This code locates the per_cpu region for a given cpu_id, stores the Linux
+ * stack pointer and cpu_id in it, sets the Jailhouse stack, and calls the
+ * architecture-independent entry() function, passing it a pointer to cpu_data.
+ */
        .text
        .globl arch_entry
 arch_entry:
diff --git a/hypervisor/arch/x86/include/asm/cell.h 
b/hypervisor/arch/x86/include/asm/cell.h
index 2223532..ba38121 100644
--- a/hypervisor/arch/x86/include/asm/cell.h
+++ b/hypervisor/arch/x86/include/asm/cell.h
@@ -54,7 +54,7 @@ struct arch_cell {
        /** Shadow value of PCI config space address port register. */
        u32 pci_addr_port_val;
 
-       /** List of IOAPICs assigned to this cell. */
+       /** List of IOAPICs assigned to this cell (Jailhouse only virtualizes 
LAPICs). */
        struct cell_ioapic *ioapics;
        /** Number of assigned IOAPICs. */
        unsigned int num_ioapics;
diff --git a/hypervisor/arch/x86/setup.c b/hypervisor/arch/x86/setup.c
index 8234167..0e13c8a 100644
--- a/hypervisor/arch/x86/setup.c
+++ b/hypervisor/arch/x86/setup.c
@@ -50,6 +50,9 @@ static void set_idt_int_gate(unsigned int vector, unsigned 
long entry)
        idt[vector * 4 + 2] = entry >> 32;
 }
 
+/*
+ * Initialize APIC and create Jailhouse's Interrupt Descriptor Table (IDT)
+ */
 int arch_init_early(void)
 {
        unsigned long entry;
@@ -203,6 +206,7 @@ int arch_cpu_init(struct per_cpu *cpu_data)
        if (err)
                goto error_out;
 
+       /* Configure Virtual Machine Extensions (VMX) for the CPU */
        err = vcpu_init(cpu_data);
        if (err)
                goto error_out;
diff --git a/hypervisor/arch/x86/vmx.c b/hypervisor/arch/x86/vmx.c
index f832612..f8fa704 100644
--- a/hypervisor/arch/x86/vmx.c
+++ b/hypervisor/arch/x86/vmx.c
@@ -78,7 +78,10 @@ static u8 __attribute__((aligned(PAGE_SIZE))) 
msr_bitmap[][0x2000/8] = {
                [      0/8 ... 0x1fff/8 ] = 0,
        },
 };
+
+/* Special access page to trap guest's attempts of accessing LAPIC in xAPIC 
mode */
 static u8 __attribute__((aligned(PAGE_SIZE))) apic_access_page[PAGE_SIZE];
+
 static struct paging ept_paging[EPT_PAGE_DIR_LEVELS];
 static u32 secondary_exec_addon;
 static unsigned long cr_maybe1[2], cr_required1[2];
@@ -339,6 +342,8 @@ int vcpu_vendor_cell_init(struct cell *cell)
        cell->arch.vmx.ept_structs.root_table =
                (page_table_t)cell->arch.root_table_page;
 
+       /* Map the special LAPIC access page into the guest's physical address
+        * space at XAPIC_BASE */
        err = paging_create(&cell->arch.vmx.ept_structs,
                            paging_hvirt2phys(apic_access_page),
                            PAGE_SIZE, XAPIC_BASE,
@@ -511,6 +516,8 @@ static bool vmcs_setup(struct per_cpu *cpu_data)
 
        ok &= vmcs_write64(HOST_RSP, (unsigned long)cpu_data->stack +
                           sizeof(cpu_data->stack));
+
+       /* Function executed when trapping to the hypervisor */
        ok &= vmcs_write64(HOST_RIP, (unsigned long)vmx_vmexit);
 
        ok &= vmx_set_guest_cr(CR0_IDX, cpu_data->linux_cr0);
@@ -672,6 +679,7 @@ int vcpu_init(struct per_cpu *cpu_data)
 
        cpu_data->vmx_state = VMXON;
 
+       /* Prepare the Virtual Machine Control Structure (VMCS) */
        if (!vmcs_clear(cpu_data) ||
            !vmcs_load(cpu_data) ||
            !vmcs_setup(cpu_data))
-- 
2.7.4

-- 
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].
For more options, visit https://groups.google.com/d/optout.

Reply via email to