[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [UNIKRAFT PATCH 2/3] plat/kvm: Add KVM (x86_64) interrupts support
Changes: * PIC support * KVM specific traps * traps and interrupt assembly stubs * shared IRQ handlers Signed-off-by: Costin Lupu <costin.lupu@xxxxxxxxx> --- plat/kvm/Makefile.uk | 9 +- plat/kvm/include/kvm-x86/cpu_x86_64.h | 42 ------- plat/kvm/include/kvm-x86/cpu_x86_64_defs.h | 42 ------- plat/kvm/include/kvm-x86/traps.h | 45 +++++++ plat/kvm/include/kvm/intctrl.h | 38 ++++++ plat/kvm/include/kvm/irq.h | 45 +++++++ plat/kvm/irq.c | 97 +++++++++++++++ plat/kvm/shutdown.c | 9 ++ plat/kvm/x86/cpu_vectors_x86_64.S | 142 ++++++++++++++++++++++ plat/kvm/x86/cpu_x86_64.c | 71 ----------- plat/kvm/x86/entry64.S | 1 + plat/kvm/x86/intctrl.c | 111 +++++++++++++++++ plat/kvm/x86/lcpu.c | 37 ++++++ plat/kvm/x86/setup.c | 6 +- plat/kvm/x86/traps.c | 186 +++++++++++++++++++++++++++++ 15 files changed, 722 insertions(+), 159 deletions(-) delete mode 100644 plat/kvm/include/kvm-x86/cpu_x86_64.h delete mode 100644 plat/kvm/include/kvm-x86/cpu_x86_64_defs.h create mode 100644 plat/kvm/include/kvm-x86/traps.h create mode 100644 plat/kvm/include/kvm/intctrl.h create mode 100644 plat/kvm/include/kvm/irq.h create mode 100644 plat/kvm/irq.c create mode 100644 plat/kvm/x86/cpu_vectors_x86_64.S delete mode 100644 plat/kvm/x86/cpu_x86_64.c create mode 100644 plat/kvm/x86/intctrl.c create mode 100644 plat/kvm/x86/traps.c diff --git a/plat/kvm/Makefile.uk b/plat/kvm/Makefile.uk index 823e785..46258ff 100644 --- a/plat/kvm/Makefile.uk +++ b/plat/kvm/Makefile.uk @@ -16,17 +16,22 @@ LIBKVMPLAT_ASINCLUDES-y += -I$(UK_PLAT_COMMON_BASE)/include LIBKVMPLAT_CINCLUDES-y += -I$(LIBKVMPLAT_BASE)/include LIBKVMPLAT_CINCLUDES-y += -I$(UK_PLAT_COMMON_BASE)/include +LIBKVMPLAT_SRCS-$(ARCH_X86_64) += $(UK_PLAT_COMMON_BASE)/x86/trace.c|common +LIBKVMPLAT_SRCS-$(ARCH_X86_64) += $(UK_PLAT_COMMON_BASE)/x86/traps.c|common +LIBKVMPLAT_SRCS-$(ARCH_X86_64) += $(UK_PLAT_COMMON_BASE)/x86/cpu_native.c|common ifeq ($(HAVE_SCHED),y) LIBKVMPLAT_SRCS-$(ARCH_X86_64) += $(UK_PLAT_COMMON_BASE)/x86/thread_start.S|common LIBKVMPLAT_SRCS-$(ARCH_X86_64) += $(UK_PLAT_COMMON_BASE)/thread.c|common LIBKVMPLAT_SRCS-$(ARCH_X86_64) += $(UK_PLAT_COMMON_BASE)/sw_ctx.c|common endif LIBKVMPLAT_SRCS-$(ARCH_X86_64) += $(LIBKVMPLAT_BASE)/x86/entry64.S -LIBKVMPLAT_SRCS-$(ARCH_X86_64) += $(LIBKVMPLAT_BASE)/x86/cpu_x86_64.c +LIBKVMPLAT_SRCS-$(ARCH_X86_64) += $(LIBKVMPLAT_BASE)/x86/traps.c +LIBKVMPLAT_SRCS-$(ARCH_X86_64) += $(LIBKVMPLAT_BASE)/x86/cpu_vectors_x86_64.S LIBKVMPLAT_SRCS-$(ARCH_X86_64) += $(LIBKVMPLAT_BASE)/x86/setup.c LIBKVMPLAT_SRCS-$(ARCH_X86_64) += $(LIBKVMPLAT_BASE)/x86/console.c LIBKVMPLAT_SRCS-$(ARCH_X86_64) += $(LIBKVMPLAT_BASE)/x86/lcpu.c -LIBKVMPLAT_SRCS-$(ARCH_X86_64) += $(LIBKVMPLAT_BASE)/x86/time.c +LIBKVMPLAT_SRCS-$(ARCH_X86_64) += $(LIBKVMPLAT_BASE)/x86/intctrl.c LIBKVMPLAT_SRCS-y += $(LIBKVMPLAT_BASE)/shutdown.c LIBKVMPLAT_SRCS-y += $(LIBKVMPLAT_BASE)/memory.c +LIBKVMPLAT_SRCS-y += $(LIBKVMPLAT_BASE)/irq.c LIBKVMPLAT_SRCS-y += $(UK_PLAT_COMMON_BASE)/lcpu.c|common diff --git a/plat/kvm/include/kvm-x86/cpu_x86_64.h b/plat/kvm/include/kvm-x86/cpu_x86_64.h deleted file mode 100644 index 427c705..0000000 --- a/plat/kvm/include/kvm-x86/cpu_x86_64.h +++ /dev/null @@ -1,42 +0,0 @@ -/* SPDX-License-Identifier: ISC */ -/* - * Authors: Martin Lucina - * - * Copyright (c) 2016-2017 Docker, Inc. - * - * Permission to use, copy, modify, and/or distribute this software - * for any purpose with or without fee is hereby granted, provided - * that the above copyright notice and this permission notice appear - * in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE - * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#include <inttypes.h> - -/* accessing devices via port space */ -static inline void outb(uint16_t port, uint8_t v) -{ - __asm__ __volatile__("outb %0,%1" : : "a"(v), "dN"(port)); -} - -static inline void outw(uint16_t port, uint16_t v) -{ - __asm__ __volatile__("outw %0,%1" : : "a"(v), "dN"(port)); -} -static inline uint8_t inb(uint16_t port) -{ - uint8_t v; - - __asm__ __volatile__("inb %1,%0" : "=a"(v) : "dN"(port)); - return v; -} - -void cpu_halt(void) __attribute__((noreturn)); -void cpu_init(void); diff --git a/plat/kvm/include/kvm-x86/cpu_x86_64_defs.h b/plat/kvm/include/kvm-x86/cpu_x86_64_defs.h deleted file mode 100644 index 985f8d3..0000000 --- a/plat/kvm/include/kvm-x86/cpu_x86_64_defs.h +++ /dev/null @@ -1,42 +0,0 @@ -/* SPDX-License-Identifier: ISC */ -/* - * Authors: Martin Lucina - * - * Copyright (c) 2016-2017 Docker, Inc. - * - * Permission to use, copy, modify, and/or distribute this software - * for any purpose with or without fee is hereby granted, provided - * that the above copyright notice and this permission notice appear - * in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE - * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <x86/cpu_defs.h> - -/* - * GDT layout - * - * This should be kept consistent with the layout used by the ukvm target (as - * defined in ukvm/ukvm_cpu_x86_64.h. - */ -#define GDT_DESC_NULL 0 -#define GDT_DESC_CODE 1 -#define GDT_DESC_CODE32 2 /* Used by boot.S on virtio targets */ -#define GDT_DESC_DATA 3 -#define GDT_DESC_TSS_LO 4 -#define GDT_DESC_TSS_HI 5 -#define GDT_DESC_TSS GDT_DESC_TSS_LO - -#define GDT_DESC_OFFSET(n) ((n) * 0x8) -#define GDT_NUM_ENTRIES 6 - -#define GDT_DESC_CODE_VAL 0x00af99000000ffff -#define GDT_DESC_DATA_VAL 0x00cf93000000ffff diff --git a/plat/kvm/include/kvm-x86/traps.h b/plat/kvm/include/kvm-x86/traps.h new file mode 100644 index 0000000..8210613 --- /dev/null +++ b/plat/kvm/include/kvm-x86/traps.h @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: ISC */ +/* + * Authors: Martin Lucina + * + * Copyright (c) 2016-2017 Docker, Inc. + * + * Permission to use, copy, modify, and/or distribute this software + * for any purpose with or without fee is hereby granted, provided + * that the above copyright notice and this permission notice appear + * in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <x86/traps.h> + +/* + * GDT layout + * + * This should be kept consistent with the layout used by the ukvm target (as + * defined in ukvm/ukvm_cpu_x86_64.h. + */ +#define GDT_DESC_NULL 0 +#define GDT_DESC_CODE 1 +#define GDT_DESC_CODE32 2 /* Used by boot.S on virtio targets */ +#define GDT_DESC_DATA 3 +#define GDT_DESC_TSS_LO 4 +#define GDT_DESC_TSS_HI 5 +#define GDT_DESC_TSS GDT_DESC_TSS_LO + +#define GDT_DESC_OFFSET(n) ((n) * 0x8) +#define GDT_NUM_ENTRIES 6 + +#define GDT_DESC_CODE_VAL 0x00af99000000ffff +#define GDT_DESC_DATA_VAL 0x00cf93000000ffff + + +#define IDT_NUM_ENTRIES 48 diff --git a/plat/kvm/include/kvm/intctrl.h b/plat/kvm/include/kvm/intctrl.h new file mode 100644 index 0000000..a6ce307 --- /dev/null +++ b/plat/kvm/include/kvm/intctrl.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Authors: Costin Lupu <costin.lupu@xxxxxxxxx> + * + * Copyright (c) 2018, NEC Europe Ltd., NEC Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY. + */ + +void intctrl_init(void); +void intctrl_clear_irq(unsigned int irq); +void intctrl_mask_irq(unsigned int irq); +void intctrl_ack_irq(unsigned int irq); diff --git a/plat/kvm/include/kvm/irq.h b/plat/kvm/include/kvm/irq.h new file mode 100644 index 0000000..606acf2 --- /dev/null +++ b/plat/kvm/include/kvm/irq.h @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Authors: Costin Lupu <costin.lupu@xxxxxxxxx> + * + * Copyright (c) 2018, NEC Europe Ltd., NEC Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY. + */ + +#ifndef __KVM_IRQ_H_ +#define __KVM_IRQ_H_ + +#include <sys/types.h> + +typedef int (*irq_handler_func_t)(void *); + +void irq_register(unsigned long irq, irq_handler_func_t func, void *arg); +void irq_handle(unsigned long irq); + +#endif /* __KVM_IRQ_H_ */ diff --git a/plat/kvm/irq.c b/plat/kvm/irq.c new file mode 100644 index 0000000..55f8e67 --- /dev/null +++ b/plat/kvm/irq.c @@ -0,0 +1,97 @@ +/* SPDX-License-Identifier: ISC */ +/* + * Authors: Dan Williams + * Martin Lucina + * Ricardo Koller + * Costin Lupu <costin.lupu@xxxxxxxxx> + * + * Copyright (c) 2015-2017 IBM + * Copyright (c) 2016-2017 Docker, Inc. + * Copyright (c) 2018, NEC Europe Ltd., NEC Corporation + * + * Permission to use, copy, modify, and/or distribute this software + * for any purpose with or without fee is hereby granted, provided + * that the above copyright notice and this permission notice appear + * in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* Taken from solo5 intr.c */ + +#include <stdlib.h> +#include <uk/alloc.h> +#include <uk/list.h> +#include <uk/plat/lcpu.h> +#include <x86/cpu.h> +#include <kvm/irq.h> +#include <kvm/intctrl.h> +#include <uk/assert.h> + + +static struct uk_alloc *allocator; + +struct irq_handler { + irq_handler_func_t func; + void *arg; + + UK_SLIST_ENTRY(struct irq_handler) entries; +}; + +UK_SLIST_HEAD(irq_handler_head, struct irq_handler); +static struct irq_handler_head irq_handlers[16]; + +void irq_register(unsigned long irq, irq_handler_func_t func, void *arg) +{ + struct irq_handler *h; + unsigned long flags; + + UK_ASSERT(irq < 16); + UK_ASSERT(allocator != NULL); + + h = uk_malloc(allocator, sizeof(struct irq_handler)); + UK_ASSERT(h != NULL); + + h->func = func; + h->arg = arg; + + flags = ukplat_lcpu_save_irqf(); + UK_SLIST_INSERT_HEAD(&irq_handlers[irq], h, entries); + ukplat_lcpu_restore_irqf(flags); + + intctrl_clear_irq(irq); +} + +void irq_handle(unsigned long irq) +{ + struct irq_handler *h; + int handled = 0; + + UK_SLIST_FOREACH(h, &irq_handlers[irq], entries) { + if (h->func(h->arg) == 1) { + handled = 1; + break; + } + } + + if (!handled) + UK_CRASH("Unhandled irq=%lu\n", irq); + else + /* Only ACK the IRQ if handled; we only need to know + * about an unhandled IRQ the first time round. + */ + intctrl_ack_irq(irq); +} + +int ukplat_irq_init(struct uk_alloc *a) +{ + UK_ASSERT(allocator == NULL); + allocator = a; + return 0; +} diff --git a/plat/kvm/shutdown.c b/plat/kvm/shutdown.c index 673d065..a513df9 100644 --- a/plat/kvm/shutdown.c +++ b/plat/kvm/shutdown.c @@ -26,6 +26,8 @@ #include <uk/print.h> #include <uk/plat/bootstrap.h> +static void cpu_halt(void) __noreturn; + /* TODO: implement CPU reset */ void ukplat_terminate(enum ukplat_gstate request __unused) { @@ -45,6 +47,13 @@ void ukplat_terminate(enum ukplat_gstate request __unused) cpu_halt(); } +static void cpu_halt(void) +{ + __asm__ __volatile__("cli; hlt"); + for (;;) + ; +} + int ukplat_suspend(void) { return -EBUSY; diff --git a/plat/kvm/x86/cpu_vectors_x86_64.S b/plat/kvm/x86/cpu_vectors_x86_64.S new file mode 100644 index 0000000..c30f2ee --- /dev/null +++ b/plat/kvm/x86/cpu_vectors_x86_64.S @@ -0,0 +1,142 @@ +/* SPDX-License-Identifier: ISC */ +/* + * Authors: Dan Williams + * Martin Lucina + * Costin Lupu <costin.lupu@xxxxxxxxx> + * + * Copyright (c) 2015-2017 IBM + * Copyright (c) 2016-2017 Docker, Inc. + * Copyright (c) 2018, NEC Europe Ltd., NEC Corporation + * + * Permission to use, copy, modify, and/or distribute this software + * for any purpose with or without fee is hereby granted, provided + * that the above copyright notice and this permission notice appear + * in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* Taken from solo5 */ + +#include <x86/traps.h> +#include <x86/regs.h> + +#define ENTRY(X) .global X ; .type X, @function ; X: + +.macro PUSH_CALLER_SAVE + pushq %rdi + pushq %rsi + pushq %rdx + pushq %rcx + pushq %rax + pushq %r8 + pushq %r9 + pushq %r10 + pushq %r11 + pushq %rbx + pushq %rbp + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 +.endm + +.macro POP_CALLER_SAVE + popq %r15 + popq %r14 + popq %r13 + popq %r12 + popq %rbp + popq %rbx + popq %r11 + popq %r10 + popq %r9 + popq %r8 + popq %rax + popq %rcx + popq %rdx + popq %rsi + popq %rdi +.endm + +.macro TRAP_ENTRY trapname, has_ec +ENTRY(ASM_TRAP_SYM(\trapname)) + cld + +.if !\has_ec + pushq $0 /* no error code, pass 0 */ +.endif + PUSH_CALLER_SAVE + subq $REGS_PAD_SIZE, %rsp /* we have some padding */ + + movq %rsp, %rdi + movq OFFSETOF_REGS_ORIG_RAX(%rsp), %rsi + call do_\trapname + + addq $REGS_PAD_SIZE, %rsp /* we have some padding */ + POP_CALLER_SAVE + addq $8, %rsp /* discard error code */ + + iretq +.endm + +.macro IRQ_ENTRY irqno +ENTRY(cpu_irq_\irqno) + cld + + pushq $0 /* no error code */ + PUSH_CALLER_SAVE + subq $REGS_PAD_SIZE, %rsp /* we have some padding */ + + movq $\irqno, %rdi + call irq_handle + + addq $REGS_PAD_SIZE, %rsp /* we have some padding */ + POP_CALLER_SAVE + addq $8, %rsp + + iretq +.endm + +TRAP_ENTRY divide_error, 0 +TRAP_ENTRY debug, 0 +TRAP_ENTRY nmi, 0 +TRAP_ENTRY int3, 0 +TRAP_ENTRY overflow, 0 +TRAP_ENTRY bounds, 0 +TRAP_ENTRY invalid_op, 0 +TRAP_ENTRY no_device, 0 +TRAP_ENTRY double_fault, 1 +TRAP_ENTRY invalid_tss, 1 +TRAP_ENTRY no_segment, 1 +TRAP_ENTRY stack_error, 1 +TRAP_ENTRY gp_fault, 1 +TRAP_ENTRY page_fault, 1 +TRAP_ENTRY coproc_error, 0 +TRAP_ENTRY alignment_check, 1 +TRAP_ENTRY machine_check, 0 +TRAP_ENTRY simd_error, 0 +TRAP_ENTRY virt_error, 0 + +IRQ_ENTRY 0 +IRQ_ENTRY 1 +IRQ_ENTRY 2 +IRQ_ENTRY 3 +IRQ_ENTRY 4 +IRQ_ENTRY 5 +IRQ_ENTRY 6 +IRQ_ENTRY 7 +IRQ_ENTRY 8 +IRQ_ENTRY 9 +IRQ_ENTRY 10 +IRQ_ENTRY 11 +IRQ_ENTRY 12 +IRQ_ENTRY 13 +IRQ_ENTRY 14 +IRQ_ENTRY 15 diff --git a/plat/kvm/x86/cpu_x86_64.c b/plat/kvm/x86/cpu_x86_64.c deleted file mode 100644 index 2f98b95..0000000 --- a/plat/kvm/x86/cpu_x86_64.c +++ /dev/null @@ -1,71 +0,0 @@ -/* SPDX-License-Identifier: ISC */ -/* - * Authors: Dan Williams - * Martin Lucina - * Felipe Huici <felipe.huici@xxxxxxxxx> - * Florian Schmidt <florian.schmidt@xxxxxxxxx> - * - * Copyright (c) 2015-2017 IBM - * Copyright (c) 2016-2017 Docker, Inc. - * Copyright (c) 2017 NEC Europe Ltd., NEC Corporation - * - * Permission to use, copy, modify, and/or distribute this software - * for any purpose with or without fee is hereby granted, provided - * that the above copyright notice and this permission notice appear - * in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE - * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <string.h> -#include <x86/desc.h> -#include <kvm/setup.h> -#include <kvm-x86/cpu_x86_64_defs.h> -#include <kvm-x86/cpu_x86_64.h> - -static struct seg_desc32 cpu_gdt64[GDT_NUM_ENTRIES] ALIGN_64_BIT; - -/* - * The monitor (ukvm) or bootloader + bootstrap (virtio) starts us up with a - * bootstrap GDT which is "invisible" to the guest, init and switch to our own - * GDT. - * - * This is done primarily since we need to do LTR later in a predictable - * fashion. - */ -static void gdt_init(void) -{ - volatile struct desc_table_ptr64 gdtptr; - - memset(cpu_gdt64, 0, sizeof(cpu_gdt64)); - cpu_gdt64[GDT_DESC_CODE].raw = GDT_DESC_CODE_VAL; - cpu_gdt64[GDT_DESC_DATA].raw = GDT_DESC_DATA_VAL; - - gdtptr.limit = sizeof(cpu_gdt64) - 1; - gdtptr.base = (__u64) &cpu_gdt64; - __asm__ __volatile__("lgdt (%0)" ::"r"(&gdtptr)); - /* - * TODO: Technically we should reload all segment registers here, in - * practice this doesn't matter since the bootstrap GDT matches ours, - * for now. - */ -} - -void cpu_init(void) -{ - gdt_init(); -} - -void cpu_halt(void) -{ - __asm__ __volatile__("cli; hlt"); - for (;;) - ; -} diff --git a/plat/kvm/x86/entry64.S b/plat/kvm/x86/entry64.S index 6570c47..f034908 100644 --- a/plat/kvm/x86/entry64.S +++ b/plat/kvm/x86/entry64.S @@ -28,6 +28,7 @@ */ #include <x86/cpu_defs.h> +#include <kvm-x86/traps.h> #include <kvm-x86/multiboot_defs.h> #define ENTRY(x) .text; .globl x; .type x,%function; x: diff --git a/plat/kvm/x86/intctrl.c b/plat/kvm/x86/intctrl.c new file mode 100644 index 0000000..dc40555 --- /dev/null +++ b/plat/kvm/x86/intctrl.c @@ -0,0 +1,111 @@ +/* SPDX-License-Identifier: ISC */ +/* + * Authors: Dan Williams + * Martin Lucina + * + * Copyright (c) 2015-2017 IBM + * Copyright (c) 2016-2017 Docker, Inc. + * + * Permission to use, copy, modify, and/or distribute this software + * for any purpose with or without fee is hereby granted, provided + * that the above copyright notice and this permission notice appear + * in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* Taken from solo5 platform_intr.c */ + +#include <stdint.h> +#include <x86/cpu.h> +#include <kvm/intctrl.h> + +#define PIC1 0x20 /* IO base address for master PIC */ +#define PIC2 0xA0 /* IO base address for slave PIC */ +#define PIC1_COMMAND PIC1 +#define PIC1_DATA (PIC1 + 1) +#define PIC2_COMMAND PIC2 +#define PIC2_DATA (PIC2 + 1) +#define IRQ_ON_MASTER(n) ((n) < 8) +#define IRQ_PORT(n) (IRQ_ON_MASTER(n) ? PIC1_DATA : PIC2_DATA) +#define IRQ_OFFSET(n) (IRQ_ON_MASTER(n) ? (n) : ((n) - 8)) + +#define PIC_EOI 0x20 /* End-of-interrupt command code */ +#define ICW1_ICW4 0x01 /* ICW4 (not) needed */ +#define ICW1_SINGLE 0x02 /* Single (cascade) mode */ +#define ICW1_INTERVAL 0x04 /* Call address interval 4 (8) */ +#define ICW1_LEVEL 0x08 /* Level triggered (edge) mode */ +#define ICW1_INIT 0x10 /* Initialization - required! */ +#define ICW4_8086 0x01 /* 8086/88 (MCS-80/85) mode */ +#define ICW4_AUTO 0x02 /* Auto (normal) EOI */ +#define ICW4_BUF_SLAVE 0x08 /* Buffered mode/slave */ +#define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */ +#define ICW4_SFN 0x10 /* Special fully nested (not) */ + +/* + * arguments: + * offset1 - vector offset for master PIC vectors on the master become + * offset1..offset1+7 + * offset2 - same for slave PIC: offset2..offset2+7 + */ +static void PIC_remap(int offset1, int offset2) +{ + unsigned char a1, a2; + + /* save masks */ + a1 = inb(PIC1_DATA); + a2 = inb(PIC2_DATA); + + /* start init seq (cascade) */ + outb(PIC1_COMMAND, ICW1_INIT + ICW1_ICW4); + outb(PIC2_COMMAND, ICW1_INIT + ICW1_ICW4); + /* ICW2: Master PIC vector off */ + outb(PIC1_DATA, offset1); + /* ICW2: Slave PIC vector off */ + outb(PIC2_DATA, offset2); + /* ICW3: tell Master PIC there is a slave PIC at IRQ2 (0000 0100) */ + outb(PIC1_DATA, 4); + /* ICW3: tell Slave PIC its cascade identity (0000 0010) */ + outb(PIC2_DATA, 2); + + outb(PIC1_DATA, ICW4_8086); + outb(PIC2_DATA, ICW4_8086); + + outb(PIC1_DATA, a1); /* restore saved masks. */ + outb(PIC2_DATA, a2); +} + +void intctrl_init(void) +{ + PIC_remap(32, 40); +} + +void intctrl_ack_irq(unsigned int irq) +{ + if (!IRQ_ON_MASTER(irq)) + outb(PIC2_COMMAND, PIC_EOI); + + outb(PIC1_COMMAND, PIC_EOI); +} + +void intctrl_mask_irq(unsigned int irq) +{ + __u16 port; + + port = IRQ_PORT(irq); + outb(port, inb(port) | (1 << IRQ_OFFSET(irq))); +} + +void intctrl_clear_irq(unsigned int irq) +{ + __u16 port; + + port = IRQ_PORT(irq); + outb(port, inb(port) & ~(1 << IRQ_OFFSET(irq))); +} diff --git a/plat/kvm/x86/lcpu.c b/plat/kvm/x86/lcpu.c index 985c670..42e2faa 100644 --- a/plat/kvm/x86/lcpu.c +++ b/plat/kvm/x86/lcpu.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause */ /* * Authors: Simon Kuenzer <simon.kuenzer@xxxxxxxxx> + * Costin Lupu <costin.lupu@xxxxxxxxx> * * Copyright (c) 2017, NEC Europe Ltd., NEC Corporation. All rights reserved. * @@ -34,3 +35,39 @@ #include <stdint.h> #include <uk/plat/lcpu.h> +#include <x86/irq.h> + + +void ukplat_lcpu_enable_irq(void) +{ + local_irq_enable(); +} + +void ukplat_lcpu_disable_irq(void) +{ + local_irq_disable(); +} + +unsigned long ukplat_lcpu_save_irqf(void) +{ + unsigned long flags; + + local_irq_save(flags); + + return flags; +} + +void ukplat_lcpu_restore_irqf(unsigned long flags) +{ + local_irq_restore(flags); +} + +int ukplat_lcpu_irqs_disabled(void) +{ + return irqs_disabled(); +} + +void ukplat_lcpu_irqs_handle_pending(void) +{ + +} diff --git a/plat/kvm/x86/setup.c b/plat/kvm/x86/setup.c index 96d80e9..f56d07e 100644 --- a/plat/kvm/x86/setup.c +++ b/plat/kvm/x86/setup.c @@ -27,10 +27,11 @@ */ #include <string.h> +#include <x86/traps.h> #include <kvm/console.h> +#include <kvm/intctrl.h> #include <kvm-x86/multiboot.h> #include <kvm-x86/multiboot_defs.h> -#include <kvm-x86/cpu_x86_64.h> #include <uk/arch/limits.h> #include <uk/arch/types.h> #include <uk/plat/console.h> @@ -134,7 +135,8 @@ void _libkvmplat_entry(void *arg) _libkvmplat_init_console(); _init_cpufeatures(); - cpu_init(); + traps_init(); + intctrl_init(); uk_printd(DLVL_INFO, "Entering from KVM (x86)...\n"); uk_printd(DLVL_INFO, " multiboot: %p\n", mi); diff --git a/plat/kvm/x86/traps.c b/plat/kvm/x86/traps.c new file mode 100644 index 0000000..27ef6d9 --- /dev/null +++ b/plat/kvm/x86/traps.c @@ -0,0 +1,186 @@ +/* SPDX-License-Identifier: ISC */ +/* + * Authors: Dan Williams + * Martin Lucina + * Felipe Huici <felipe.huici@xxxxxxxxx> + * Florian Schmidt <florian.schmidt@xxxxxxxxx> + * + * Copyright (c) 2015-2017 IBM + * Copyright (c) 2016-2017 Docker, Inc. + * Copyright (c) 2017 NEC Europe Ltd., NEC Corporation + * + * Permission to use, copy, modify, and/or distribute this software + * for any purpose with or without fee is hereby granted, provided + * that the above copyright notice and this permission notice appear + * in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <string.h> +#include <uk/arch/lcpu.h> +#include <x86/desc.h> +#include <kvm-x86/traps.h> + +static struct seg_desc32 cpu_gdt64[GDT_NUM_ENTRIES] __align64b; + +/* + * The monitor (ukvm) or bootloader + bootstrap (virtio) starts us up with a + * bootstrap GDT which is "invisible" to the guest, init and switch to our own + * GDT. + * + * This is done primarily since we need to do LTR later in a predictable + * fashion. + */ +static void gdt_init(void) +{ + volatile struct desc_table_ptr64 gdtptr; + + memset(cpu_gdt64, 0, sizeof(cpu_gdt64)); + cpu_gdt64[GDT_DESC_CODE].raw = GDT_DESC_CODE_VAL; + cpu_gdt64[GDT_DESC_DATA].raw = GDT_DESC_DATA_VAL; + + gdtptr.limit = sizeof(cpu_gdt64) - 1; + gdtptr.base = (__u64) &cpu_gdt64; + __asm__ __volatile__("lgdt (%0)" ::"r"(&gdtptr)); + /* + * TODO: Technically we should reload all segment registers here, in + * practice this doesn't matter since the bootstrap GDT matches ours, + * for now. + */ +} + +static struct tss64 cpu_tss; + +static char cpu_intr_stack[4096]; /* IST1 */ +static char cpu_trap_stack[4096]; /* IST2 */ +static char cpu_nmi_stack[4096]; /* IST3 */ + +static void tss_init(void) +{ + struct seg_desc64 *td = (void *) &cpu_gdt64[GDT_DESC_TSS_LO]; + + cpu_tss.ist[0] = (__u64) &cpu_intr_stack[sizeof(cpu_intr_stack)]; + cpu_tss.ist[1] = (__u64) &cpu_trap_stack[sizeof(cpu_trap_stack)]; + cpu_tss.ist[2] = (__u64) &cpu_nmi_stack[sizeof(cpu_nmi_stack)]; + + td->limit_lo = sizeof(cpu_tss); + td->base_lo = (__u64) &cpu_tss; + td->type = 0x9; + td->zero = 0; + td->dpl = 0; + td->p = 1; + td->limit_hi = 0; + td->gran = 0; + td->base_hi = (__u64) &cpu_tss >> 24; + td->zero1 = 0; + + barrier(); + __asm__ __volatile__( + "ltr %0" + : + : "r" ((unsigned short) (GDT_DESC_TSS_LO * 8)) + ); +} + + +/* Declare the traps used only by this platform: */ +DECLARE_TRAP_EC(nmi, "NMI") +DECLARE_TRAP_EC(double_fault, "double fault") +DECLARE_TRAP_EC(virt_error, "virtualization error") + + +static struct seg_gate_desc64 cpu_idt[IDT_NUM_ENTRIES] __align64b; + +static void idt_fillgate(unsigned int num, void *fun, unsigned int ist) +{ + struct seg_gate_desc64 *desc = &cpu_idt[num]; + + /* + * All gates are interrupt gates, all handlers run with interrupts off. + */ + desc->offset_hi = (__u64) fun >> 16; + desc->offset_lo = (__u64) fun & 0xffff; + desc->selector = GDT_DESC_OFFSET(GDT_DESC_CODE); + desc->ist = ist; + desc->type = 14; /* == 0b1110 */ + desc->dpl = 0; + desc->p = 1; +} + +volatile struct desc_table_ptr64 idtptr; + +static void idt_init(void) +{ + /* + * Load trap vectors. All traps run on IST2 (cpu_trap_stack), except for + * the exceptions. + */ +#define FILL_TRAP_GATE(name, ist) extern void cpu_trap_##name(void); \ + idt_fillgate(TRAP_##name, ASM_TRAP_SYM(name), ist) + FILL_TRAP_GATE(divide_error, 2); + FILL_TRAP_GATE(debug, 2); + FILL_TRAP_GATE(nmi, 3); /* #NMI runs on IST3 (cpu_nmi_stack) */ + FILL_TRAP_GATE(int3, 2); + FILL_TRAP_GATE(overflow, 2); + FILL_TRAP_GATE(bounds, 2); + FILL_TRAP_GATE(invalid_op, 2); + FILL_TRAP_GATE(no_device, 2); + FILL_TRAP_GATE(double_fault, 3); /* #DF runs on IST3 (cpu_nmi_stack) */ + + FILL_TRAP_GATE(invalid_tss, 2); + FILL_TRAP_GATE(no_segment, 2); + FILL_TRAP_GATE(stack_error, 2); + FILL_TRAP_GATE(gp_fault, 2); + FILL_TRAP_GATE(page_fault, 2); + + FILL_TRAP_GATE(coproc_error, 2); + FILL_TRAP_GATE(alignment_check, 2); + FILL_TRAP_GATE(machine_check, 2); + FILL_TRAP_GATE(simd_error, 2); + FILL_TRAP_GATE(virt_error, 2); + + /* + * Load irq vectors. All irqs run on IST1 (cpu_intr_stack). + */ +#define FILL_IRQ_GATE(num, ist) extern void cpu_irq_##num(void); \ + idt_fillgate(32 + num, cpu_irq_##num, ist) + FILL_IRQ_GATE(0, 1); + FILL_IRQ_GATE(1, 1); + FILL_IRQ_GATE(2, 1); + FILL_IRQ_GATE(3, 1); + FILL_IRQ_GATE(4, 1); + FILL_IRQ_GATE(5, 1); + FILL_IRQ_GATE(6, 1); + FILL_IRQ_GATE(7, 1); + FILL_IRQ_GATE(8, 1); + FILL_IRQ_GATE(9, 1); + FILL_IRQ_GATE(10, 1); + FILL_IRQ_GATE(11, 1); + FILL_IRQ_GATE(12, 1); + FILL_IRQ_GATE(13, 1); + FILL_IRQ_GATE(14, 1); + FILL_IRQ_GATE(15, 1); + + idtptr.limit = sizeof(cpu_idt) - 1; + idtptr.base = (__u64) &cpu_idt; + __asm__ __volatile__("lidt (%0)" :: "r" (&idtptr)); +} + +void traps_init(void) +{ + gdt_init(); + tss_init(); + idt_init(); +} + +void traps_fini(void) +{ +} -- 2.1.4 _______________________________________________ Minios-devel mailing list Minios-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/minios-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |