Hello,
Damien Zammit, le jeu. 02 juil. 2026 10:30:25 +0000, a ecrit:
> UNTESTED: Needs gdt and idt fixed for vcpus
Have you tested that this does not break uni-processor execution?
Samuel
>
> (See warning in code compilation)
> ---
> i386/Makefrag.am | 6 +++
> i386/Makefrag_x86.am | 2 -
> i386/i386/ast_check.c | 5 ++
> i386/i386/i386asm.sym | 15 +++---
> i386/i386/locore.S | 5 +-
> i386/i386/mp_desc.c | 114 +++++++++++++++++++++++++++++++++++++++-
> i386/i386/percpu.c | 39 +++++++++++---
> i386/i386/percpu.h | 6 +++
> i386/i386/spl.S | 10 ++--
> i386/i386/xen.h | 52 +++++++++++++++++-
> i386/i386at/model_dep.h | 1 +
> i386/xen/xen.c | 12 +++++
> i386/xen/xen_locore.S | 29 ++++++++--
> x86_64/Makefrag.am | 6 +++
> x86_64/locore.S | 5 +-
> x86_64/spl.S | 10 ++--
> x86_64/xen_locore.S | 29 ++++++++--
> 17 files changed, 311 insertions(+), 35 deletions(-)
>
> diff --git a/i386/Makefrag.am b/i386/Makefrag.am
> index 85333d1e..f54efeee 100644
> --- a/i386/Makefrag.am
> +++ b/i386/Makefrag.am
> @@ -112,6 +112,12 @@ libkernel_a_SOURCES += \
> i386/i386/pit.c \
> i386/i386/pit.h
>
> +if enable_smp
> +libkernel_a_SOURCES += \
> + i386/i386/smp.c \
> + i386/i386/smp.h
> +endif
> +
> if enable_apic
> libkernel_a_SOURCES += \
> i386/i386at/ioapic.c
> diff --git a/i386/Makefrag_x86.am b/i386/Makefrag_x86.am
> index 56bcf2a8..583d47b4 100644
> --- a/i386/Makefrag_x86.am
> +++ b/i386/Makefrag_x86.am
> @@ -61,8 +61,6 @@ libkernel_a_SOURCES += \
> i386/i386/sched_param.h \
> i386/i386/seg.h \
> i386/i386/setjmp.h \
> - i386/i386/smp.c \
> - i386/i386/smp.h \
> i386/i386/spl.h \
> i386/i386/strings.c \
> i386/i386/task.h \
> diff --git a/i386/i386/ast_check.c b/i386/i386/ast_check.c
> index 8bf69a68..9d6c1fbe 100644
> --- a/i386/i386/ast_check.c
> +++ b/i386/i386/ast_check.c
> @@ -37,6 +37,7 @@
> #include <kern/smp.h>
> #include <machine/cpu_number.h>
> #include <machine/apic.h>
> +#include <machine/xen.h>
>
> /*
> * Initialize for remote invocation of ast_check.
> @@ -50,7 +51,11 @@ void init_ast_check(const processor_t processor)
> */
> void cause_ast_check(const processor_t processor)
> {
> +#ifndef MACH_XEN
> smp_remote_ast(APIC_LOGICAL_ID(processor->slot_num));
> +#else
> + hypsmp_remote_ast(processor->slot_num);
> +#endif
> }
>
> #endif /* NCPUS > 1 */
> diff --git a/i386/i386/i386asm.sym b/i386/i386/i386asm.sym
> index e1f5c6bb..709375d1 100644
> --- a/i386/i386/i386asm.sym
> +++ b/i386/i386/i386asm.sym
> @@ -181,13 +181,16 @@ offset thread th user_timer
> #endif
>
> #ifdef MACH_XEN
> -offset shared_info si vcpu_info[0].evtchn_upcall_mask
> CPU_CLI
> -offset shared_info si
> vcpu_info[0].evtchn_upcall_pending CPU_PENDING
> -offset shared_info si vcpu_info[0].evtchn_pending_sel
> CPU_PENDING_SEL
> -offset shared_info si evtchn_pending PENDING
> -offset shared_info si evtchn_mask EVTMASK
> +expr sizeof(vcpu_info_t) VI_SIZE
> +
> +offset shared_info si vcpu_info[0] VI_START
> +offset vcpu_info vi evtchn_upcall_mask CPUX_CLI
> +offset vcpu_info vi evtchn_upcall_pending
> CPUX_PENDING
> +offset vcpu_info vi evtchn_pending_sel
> CPUX_PENDING_SEL
> +offset shared_info si evtchn_pending PENDING
> +offset shared_info si evtchn_mask EVTMASK
> #ifdef MACH_PV_PAGETABLES
> -offset shared_info si vcpu_info[0].arch.cr2 CR2
> +offset vcpu_info vi arch.cr2 CPUX_CR2
> #endif /* MACH_PV_PAGETABLES */
> #endif /* MACH_XEN */
>
> diff --git a/i386/i386/locore.S b/i386/i386/locore.S
> index dc761991..b6b1d739 100644
> --- a/i386/i386/locore.S
> +++ b/i386/i386/locore.S
> @@ -492,7 +492,10 @@ ENTRY(t_page_fault)
> pushl $(T_PAGE_FAULT) /* mark a page fault trap */
> pusha /* save the general registers */
> #ifdef MACH_PV_PAGETABLES
> - movl %ss:hyp_shared_info+CR2,%eax
> + pushl %ebx
> + SET_VCPUX_INFO(%ebx, CPUX_CR2)
> + movl %ss:(%ebx),%eax
> + popl %ebx
> #else /* MACH_PV_PAGETABLES */
> movl %cr2,%eax /* get the faulting address */
> #endif /* MACH_PV_PAGETABLES */
> diff --git a/i386/i386/mp_desc.c b/i386/i386/mp_desc.c
> index 1343861c..873256db 100644
> --- a/i386/i386/mp_desc.c
> +++ b/i386/i386/mp_desc.c
> @@ -24,6 +24,7 @@
> * the rights to redistribute these changes.
> */
>
> +#include <kern/ast.h>
> #include <kern/assert.h>
> #include <kern/cpu_number.h>
> #include <kern/debug.h>
> @@ -45,6 +46,7 @@
> #include <i386at/int_init.h>
> #include <i386/cpu.h>
> #include <i386/smp.h>
> +#include <intel/pmap.h>
>
> #include <i386at/model_dep.h>
> #include <machine/ktss.h>
> @@ -95,9 +97,11 @@ interrupt_stack_alloc(void)
> }
>
> #if NCPUS > 1
> +#ifndef MACH_XEN
> phys_addr_t apboot_addr;
> extern void *apboot, *apbootend;
> extern volatile ApicLocalUnit* lapic;
> +#endif
>
> /*
> * Multiprocessor i386/i486 systems use a separate copy of the
> @@ -205,7 +209,11 @@ cpu_control(int cpu, const int *info, unsigned int count)
> void
> interrupt_processor(int cpu)
> {
> +#ifndef MACH_XEN
> smp_pmap_update(APIC_LOGICAL_ID(cpu));
> +#else
> + hypsmp_pmap_update(cpu);
> +#endif
> }
>
> static void
> @@ -225,6 +233,7 @@ paging_enable(void)
> #endif /* MACH_HYP */
> }
>
> +#ifndef MACH_XEN
> static __attribute__((noreturn)) void
> cpu_setup(int cpu)
> {
> @@ -341,4 +350,107 @@ start_other_cpus(void)
> /* Re-enable IOAPIC interrupts as per setup */
> lapic_enable();
> }
> -#endif /* NCPUS > 1 */
> +
> +#else /* !MACH_XEN */
> +
> +#include <xen/public/vcpu.h>
> +#include <xen/evt.h>
> +
> +void start_other_cpus(void) {
> + int vcpu;
> + int vcpus;
> + int err;
> + struct vcpu_register_vcpu_info info;
> + volatile struct vcpu_info *vcpui;
> +
> + for (vcpus = 0; vcpus < NCPUS; vcpus++) {
> + if (hyp_vcpu_is_up(vcpus) < 0)
> + break;
> + }
> + printf("Xen: Detected %d vCPUS\n", vcpus);
> +
> + if (vcpus == 1)
> + return;
> +
> + for (vcpu = 1; vcpu < vcpus; vcpu++) {
> + machine_slot[vcpu].running = FALSE;
> + }
> +
> + for (vcpu = 1; vcpu < vcpus; vcpu++) {
> +
> + init_percpu(vcpu);
> +
> + err = hyp_vcpu_initialise(vcpu, &percpu_array[vcpu].vcpu_gc);
> + if (err) {
> + printf("Cannot initialise xen vcpu=%d\n", vcpu);
> + continue;
> + }
> +
> + vcpui = &hyp_shared_info.vcpu_info[vcpu];
> + info.mfn = kv_to_mfn(vcpui);
> + info.offset = (uint32_t)((uintptr_t)vcpui & ~PAGE_MASK);
> +
> + err = hyp_vcpu_register(vcpu, &info);
> + if (err) {
> + printf("Cannot register xen vcpu=%d\n", vcpu);
> + continue;
> + }
> + percpu_array[vcpu].cpu_id = vcpu;
> +
> + err = hyp_vcpu_up(vcpu);
> + if (err) {
> + printf("Cannot bring up xen vcpu=%d\n", vcpu);
> + percpu_array[vcpu].cpu_id = 0;
> + continue;
> + }
> +
> + /* Register IPI events per vcpu */
> + percpu_array[vcpu].ast_evt = hyp_event_channel_bind_ipi(vcpu);
> + hyp_evt_handler(percpu_array[vcpu].ast_evt,
> (interrupt_handler_fn)ast_check, 0, SPLHI);
> +
> + percpu_array[vcpu].pmap_evt = hyp_event_channel_bind_ipi(vcpu);
> + hyp_evt_handler(percpu_array[vcpu].pmap_evt,
> (interrupt_handler_fn)pmap_update_interrupt, 0, SPLHI);
> + }
> +
> + for (vcpu = 1; vcpu < vcpus; vcpu++) {
> + printf("Waiting for vCPU %d\n", vcpu);
> +
> + do {
> + cpu_pause();
> + } while (machine_slot[vcpu].running == FALSE);
> + }
> + printf("Xen vCPU bringup complete\n");
> +}
> +
> +void cpu_ap_main(void) {
> + int vcpu = cpu_number();
> +
> + assert (vcpu > 0);
> +
> + mp_desc_init(vcpu);
> + printf("vCPU=(%u) mpdesc done\n", vcpu);
> +
> +#warning Fix xen smp gdt/idt, see percpu.c and mp_desc.c
> +#if 0
> + ap_gdt_init(vcpu);
> + printf("vCPU=(%u) gdt done\n", vcpu);
> +
> + ap_idt_init(vcpu);
> + printf("vCPU=(%u) idt done\n", vcpu);
> +
> + ap_ldt_init(vcpu);
> + printf("vCPU=(%u) ldt done\n", vcpu);
> +
> + ap_ktss_init(vcpu);
> + printf("vCPU=(%u) ktss done\n", vcpu);
> +#endif
> + /* Initialize machine_slot fields with the cpu data */
> + machine_slot[vcpu].cpu_subtype = CPU_SUBTYPE_AT386;
> + machine_slot[vcpu].cpu_type = machine_slot[0].cpu_type;
> + machine_slot[vcpu].running = TRUE;
> +
> + cpu_launch_first_thread(THREAD_NULL);
> +}
> +
> +#endif /* !MACH_XEN */
> +#endif /* NCPUS > 1 */
> diff --git a/i386/i386/percpu.c b/i386/i386/percpu.c
> index c6b728b6..f4c83e6a 100644
> --- a/i386/i386/percpu.c
> +++ b/i386/i386/percpu.c
> @@ -14,20 +14,47 @@
> * You should have received a copy of the GNU General Public License
> * along with this program. If not, see <http://www.gnu.org/licenses/>.
> */
> -#include <i386/smp.h>
> +#ifdef APIC
> #include <i386/apic.h>
> +#endif
> +#include <i386/gdt.h>
> +#include <i386/ldt.h>
> +#include <i386/smp.h>
> #include <kern/cpu_number.h>
> #include <i386/percpu.h>
> +#include <i386at/model_dep.h>
> +
> +extern void cpu_ap_main(void);
> +extern void hyp_callback(void);
> +extern void hyp_failsafe_callback(void);
>
> struct percpu percpu_array[NCPUS] = {0};
>
> -#ifndef MACH_XEN
> void init_percpu(int cpu)
> {
> - int apic_id = apic_get_current_cpu();
> -
> percpu_array[cpu].self = &percpu_array[cpu];
> - percpu_array[cpu].apic_id = apic_id;
> +#ifdef APIC
> + percpu_array[cpu].apic_id = apic_get_current_cpu();
> +#endif
> percpu_array[cpu].cpu_id = cpu;
> -}
> +#if NCPUS > 1 && defined(MACH_XEN)
> + percpu_array[cpu].vcpu_gc.user_regs.eip = (unsigned long)cpu_ap_main;
> + percpu_array[cpu].vcpu_gc.flags = VGCF_IN_KERNEL;
> + percpu_array[cpu].vcpu_gc.user_regs.eflags = 0x1000; /* IOPL_RING1 */
> + percpu_array[cpu].vcpu_gc.user_regs.ds = USER_DS;
> + percpu_array[cpu].vcpu_gc.user_regs.es = USER_DS;
> + percpu_array[cpu].vcpu_gc.user_regs.ss = KERNEL_DS;
> + percpu_array[cpu].vcpu_gc.user_regs.cs = KERNEL_CS;
> + percpu_array[cpu].vcpu_gc.user_regs.esp = (unsigned
> long)int_stack_top[cpu];
> + //XXX gdt_{frames,ents} ?
> + //XXX trap_ctxt (idt)?
> + percpu_array[cpu].vcpu_gc.kernel_ss = KERNEL_DS;
> + percpu_array[cpu].vcpu_gc.kernel_sp = (unsigned long)int_stack_top[cpu];
> +#ifdef __x86_64__
> + percpu_array[cpu].vcpu_gc.gs_base_kernel = (unsigned
> long)percpu_array[cpu].self;
> #endif
> + percpu_array[cpu].vcpu_gc.event_callback_eip = (unsigned
> long)hyp_callback;
> + percpu_array[cpu].vcpu_gc.failsafe_callback_eip = (unsigned
> long)hyp_failsafe_callback;
> + percpu_array[cpu].vcpu_gc.ctrlreg[3] = (unsigned long)kernel_page_dir;
> +#endif
> +}
> diff --git a/i386/i386/percpu.h b/i386/i386/percpu.h
> index 637d2ca6..52556835 100644
> --- a/i386/i386/percpu.h
> +++ b/i386/i386/percpu.h
> @@ -67,11 +67,17 @@ MACRO_END
>
> #include <kern/processor.h>
> #include <mach/mach_types.h>
> +#include <i386/xen.h>
>
> struct percpu {
> struct percpu *self;
> int apic_id;
> int cpu_id;
> +#ifdef MACH_XEN
> + struct vcpu_guest_context vcpu_gc;
> + evtchn_port_t ast_evt;
> + evtchn_port_t pmap_evt;
> +#endif
> struct processor processor;
> thread_t active_thread;
> vm_offset_t active_stack;
> diff --git a/i386/i386/spl.S b/i386/i386/spl.S
> index 1a831edb..5ae2589e 100644
> --- a/i386/i386/spl.S
> +++ b/i386/i386/spl.S
> @@ -40,11 +40,13 @@
> notl %ebx; \
> andl %eax,%ebx; /* Get unmasked events */ \
> testl hyp_shared_info+PENDING, %ebx; \
> - popl %ebx; \
> jz 9f; /* Check whether there was some
> pending */ \
> -lock orl $1,hyp_shared_info+CPU_PENDING_SEL; /* Yes, activate it */ \
> - movb $1,hyp_shared_info+CPU_PENDING; \
> -9:
> + SET_VCPUX_INFO(%ebx, CPUX_PENDING_SEL); \
> +lock orl $1, (%ebx); /* Yes, activate it */ \
> + SET_VCPUX_INFO(%ebx, CPUX_PENDING); \
> + movb $1, (%ebx); \
> +9: \
> + popl %ebx;
>
> ENTRY(spl0)
> mb;
> diff --git a/i386/i386/xen.h b/i386/i386/xen.h
> index 2cd81be8..5001fc42 100644
> --- a/i386/i386/xen.h
> +++ b/i386/i386/xen.h
> @@ -351,6 +351,12 @@ static inline evtchn_port_t
> hyp_event_channel_bind_virq(uint32_t virq, uint32_t
> panic("can't bind virq %d\n",virq);
> return op.u.bind_virq.port;
> }
> +static inline evtchn_port_t hyp_event_channel_bind_ipi(uint32_t vcpu) {
> + evtchn_op_t op = { .cmd = EVTCHNOP_bind_ipi, .u.bind_ipi = { .vcpu =
> vcpu }};
> + if (hyp_event_channel_op(kvtolin(&op)))
> + panic("can't bind ipi to vcpu %d\n",vcpu);
> + return op.u.bind_ipi.port;
> +}
>
> _hypcall3(int, console_io, int, cmd, int, count, vm_offset_t /* const char *
> */, buffer);
>
> @@ -360,6 +366,14 @@ _hypcall2(long, vm_assist, unsigned int, cmd, unsigned
> int, type);
>
> _hypcall0(long, iret);
>
> +#include <xen/public/vcpu.h>
> +_hypcall3(int, vcpu_op, int, cmd, int, vcpu, vm_offset_t /* void* */, arg)
> +#define hyp_vcpu_initialise(vcpu, gc) hyp_vcpu_op(VCPUOP_initialise, vcpu,
> (vm_offset_t)gc)
> +#define hyp_vcpu_register(vcpu, info) hyp_vcpu_op(VCPUOP_register_vcpu_info,
> vcpu, (vm_offset_t)info)
> +#define hyp_vcpu_is_up(vcpu) hyp_vcpu_op(VCPUOP_is_up, vcpu, 0)
> +#define hyp_vcpu_up(vcpu) hyp_vcpu_op(VCPUOP_up, vcpu, 0)
> +#define hyp_vcpu_down(vcpu) hyp_vcpu_op(VCPUOP_down, vcpu, 0)
> +
> #include <xen/public/sched.h>
> _hypcall2(long, sched_op, int, cmd, vm_offset_t /* void* */, arg)
> #define hyp_yield() hyp_sched_op(SCHEDOP_yield, 0)
> @@ -401,9 +415,43 @@ static inline uint64_t hyp_cpu_clock(void) {
> return (((uint64_t) hi) << 32) | lo;
> }
>
> +void hypsmp_remote_ast(int vcpu);
> +void hypsmp_pmap_update(int vcpu);
> +
> #else /* __ASSEMBLER__ */
> -/* TODO: SMP */
> -#define cli movb $0xff,hyp_shared_info+CPU_CLI
> +#include <i386/i386/i386asm.h>
> +
> +#ifdef __i386__
> +/* Don't call this with %eax */
> +#define SET_VCPUX_INFO(reg, offset) \
> + pushl %eax; \
> + pushl %ebx; \
> + pushl %edx; \
> + CPU_NUMBER(%ebx); \
> + movl $VI_SIZE, %eax; \
> + mull %ebx; \
> + movl $(hyp_shared_info+VI_START), reg; \
> + movl offset(reg, %eax, 1), reg; \
> + popl %edx; \
> + popl %ebx; \
> + popl %eax;
> +#endif
> +#ifdef __x86_64__
> +/* Don't call this with %rax */
> +#define SET_VCPUX_INFO(reg, offset) \
> + pushq %rax; \
> + pushq %rbx; \
> + pushq %rdx; \
> + CPU_NUMBER(%ebx); \
> + movq $VI_SIZE, %rax; \
> + mulq %rbx; \
> + movq $(hyp_shared_info+VI_START), reg; \
> + movq offset(reg, %rax, 1), reg; \
> + popq %rdx; \
> + popq %rbx; \
> + popq %rax;
> +#endif
> +#define cli call hyp_cli
> #define sti call hyp_sti
> #define iretq jmp hyp_iretq
> #endif /* ASSEMBLER */
> diff --git a/i386/i386at/model_dep.h b/i386/i386at/model_dep.h
> index 3d5b6645..85a37e47 100644
> --- a/i386/i386at/model_dep.h
> +++ b/i386/i386at/model_dep.h
> @@ -21,6 +21,7 @@
>
> #include <i386/vm_param.h>
> #include <mach/vm_prot.h>
> +#include <sys/types.h>
>
> /*
> * Interrupt stack.
> diff --git a/i386/xen/xen.c b/i386/xen/xen.c
> index 1cc3fcab..d86d80c2 100644
> --- a/i386/xen/xen.c
> +++ b/i386/xen/xen.c
> @@ -20,6 +20,7 @@
> #include <kern/debug.h>
> #include <kern/mach_clock.h>
>
> +#include <mach/vm_param.h>
> #include <mach/machine/eflags.h>
> #include <machine/thread.h>
> #include <machine/ipl.h>
> @@ -28,6 +29,7 @@
> #include <vm/pmap.h>
>
> #include <xen/xen.h>
> +#include <i386/percpu.h>
>
> unsigned long cr3;
>
> @@ -69,3 +71,13 @@ void hyp_p2m_init(void) {
> #endif
> hyp_shared_info.arch.max_pfn = nb_pfns;
> }
> +
> +void hypsmp_remote_ast(int vcpu)
> +{
> + hyp_event_channel_send(percpu_array[vcpu].ast_evt);
> +}
> +
> +void hypsmp_pmap_update(int vcpu)
> +{
> + hyp_event_channel_send(percpu_array[vcpu].pmap_evt);
> +}
> diff --git a/i386/xen/xen_locore.S b/i386/xen/xen_locore.S
> index 1468ef80..b642440a 100644
> --- a/i386/xen/xen_locore.S
> +++ b/i386/xen/xen_locore.S
> @@ -56,20 +56,26 @@ ENTRY(hyp_sti)
> pushl %ebp
> movl %esp, %ebp
> _hyp_sti:
> - movb $0,hyp_shared_info+CPU_CLI /* Enable interrupts */
> + pushl %ebx
> + SET_VCPUX_INFO(%ebx, CPUX_CLI)
> + movb $0,(%ebx) /* Enable interrupts */
> cmpl $0,int_active /* Check whether we were already
> checking pending interrupts */
> jz 0f
> + popl %ebx
> popl %ebp
> ret /* Already active, just return */
> 0:
> /* Not active, check pending interrupts by hand */
> /* no memory barrier needed on x86 */
> - cmpb $0,hyp_shared_info+CPU_PENDING
> + SET_VCPUX_INFO(%ebx, CPUX_PENDING)
> + cmpb $0,(%ebx)
> jne 0f
> + popl %ebx
> popl %ebp
> ret
> 0:
> - movb $0xff,hyp_shared_info+CPU_CLI
> + popl %ebx
> + cli
> 1:
> pushl %eax
> pushl %ecx
> @@ -86,10 +92,25 @@ _hyp_sti:
> popl %ecx
> popl %eax
> decl int_active /* stopped handling interrupts */
> - cmpb $0,hyp_shared_info+CPU_PENDING
> + pushl %ebx
> + SET_VCPUX_INFO(%ebx, CPUX_PENDING)
> + cmpb $0,(%ebx)
> + popl %ebx
> jne 1b
> jmp _hyp_sti
>
> +ENTRY(hyp_cli)
> + pushl %ebp
> + movl %esp, %ebp
> +
> + pushl %ebx
> + SET_VCPUX_INFO(%ebx, CPUX_CLI)
> + movb $0xff,(%ebx)
> + popl %ebx
> +
> + popl %ebp
> + ret
> +
> /* Hypervisor failed to reload segments. Dump them. */
> hyp_failsafe_callback:
> #if 1
> diff --git a/x86_64/Makefrag.am b/x86_64/Makefrag.am
> index 36b5fa38..bc82cec9 100644
> --- a/x86_64/Makefrag.am
> +++ b/x86_64/Makefrag.am
> @@ -110,6 +110,12 @@ libkernel_a_SOURCES += \
> i386/i386/pit.c \
> i386/i386/pit.h
>
> +if enable_smp
> +libkernel_a_SOURCES += \
> + i386/i386/smp.c \
> + i386/i386/smp.h
> +endif
> +
> if enable_apic
> libkernel_a_SOURCES += \
> i386/i386at/ioapic.c
> diff --git a/x86_64/locore.S b/x86_64/locore.S
> index dd35d2f8..0b2853ca 100644
> --- a/x86_64/locore.S
> +++ b/x86_64/locore.S
> @@ -632,7 +632,10 @@ ENTRY(t_page_fault)
> pushq $(T_PAGE_FAULT) /* mark a page fault trap */
> pusha /* save the general registers */
> #ifdef MACH_XEN
> - movq %ss:hyp_shared_info+CR2,%rax
> + pushq %rbx
> + SET_VCPUX_INFO(%rbx, CPUX_CR2)
> + movq %ss:(%rbx),%rax
> + popq %rbx
> #else /* MACH_XEN */
> movq %cr2,%rax /* get the faulting address */
> #endif /* MACH_XEN */
> diff --git a/x86_64/spl.S b/x86_64/spl.S
> index 5fdf977c..28c2b971 100644
> --- a/x86_64/spl.S
> +++ b/x86_64/spl.S
> @@ -39,11 +39,13 @@
> notl %ebx; \
> andl %eax,%ebx; /* Get unmasked events */ \
> testl hyp_shared_info+PENDING, %ebx; \
> - popq %rbx; \
> jz 9f; /* Check whether there was some
> pending */ \
> -lock orl $1,hyp_shared_info+CPU_PENDING_SEL; /* Yes, activate it */ \
> - movb $1,hyp_shared_info+CPU_PENDING; \
> -9:
> + SET_VCPUX_INFO(%rbx, CPUX_PENDING_SEL); \
> +lock orl $1,(%rbx); /* Yes, activate it */ \
> + SET_VCPUX_INFO(%rbx, CPUX_PENDING); \
> + movb $1,(%rbx); \
> +9: \
> + popq %rbx;
>
> ENTRY(spl0)
> mb;
> diff --git a/x86_64/xen_locore.S b/x86_64/xen_locore.S
> index 967c8904..2b2a3ff3 100644
> --- a/x86_64/xen_locore.S
> +++ b/x86_64/xen_locore.S
> @@ -58,20 +58,26 @@ ENTRY(hyp_sti)
> pushq %rbp
> movq %rsp, %rbp
> _hyp_sti:
> - movb $0,hyp_shared_info+CPU_CLI /* Enable interrupts */
> + pushq %rdx
> + SET_VCPUX_INFO(%rdx, CPUX_CLI)
> + movb $0,(%rdx) /* Enable interrupts */
> cmpl $0,int_active /* Check whether we were already
> checking pending interrupts */
> jz 0f
> + popq %rdx
> popq %rbp
> ret /* Already active, just return */
> 0:
> /* Not active, check pending interrupts by hand */
> /* no memory barrier needed on x86 */
> - cmpb $0,hyp_shared_info+CPU_PENDING
> + SET_VCPUX_INFO(%rdx, CPUX_PENDING)
> + cmpb $0,(%rdx)
> jne 0f
> + popq %rdx
> popq %rbp
> ret
> 0:
> - movb $0xff,hyp_shared_info+CPU_CLI
> + popq %rdx
> + cli
> 1:
> pushq %rax
> pushq %rcx
> @@ -98,10 +104,25 @@ _hyp_sti:
> popq %rcx
> popq %rax
> decl int_active /* stopped handling interrupts */
> - cmpb $0,hyp_shared_info+CPU_PENDING
> + pushq %rdx
> + SET_VCPUX_INFO(%rdx, CPUX_PENDING)
> + cmpb $0,(%rdx)
> + popq %rdx
> jne 1b
> jmp _hyp_sti
>
> +ENTRY(hyp_cli)
> + pushq %rbp
> + movq %rsp, %rbp
> +
> + pushq %rdx
> + SET_VCPUX_INFO(%rdx, CPUX_CLI)
> + movb $0xff,(%rdx)
> + popq %rdx
> +
> + popq %rbp
> + ret
> +
> /* Hypervisor failed to reload segments. Dump them. */
> hyp_failsafe_callback:
> ud2
> --
> 2.51.0
>
>
>
--
Samuel
<P> moo
<N> moo ?
<D> P: keski t'arrive? :))
<P> moooo
<N> moooooo ?
<P> rien le net marche je suis content :)
-+- #ens-mim - accro du net -+-