|
[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 |