[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Minios-devel] [UNIKRAFT PATCH 2/3] plat/kvm: Add KVM (x86_64) interrupts support


  • To: Simon Kuenzer <simon.kuenzer@xxxxxxxxx>, minios-devel@xxxxxxxxxxxxx
  • From: Costin Lupu <costin.lupu@xxxxxxxxx>
  • Date: Tue, 1 May 2018 02:40:16 +0300
  • Delivery-date: Mon, 30 Apr 2018 23:40:31 +0000
  • Ironport-phdr: 9a23:Y+R5zxJZt05fO5KtFNmcpTZWNBhigK39O0sv0rFitYgfLf7xwZ3uMQTl6Ol3ixeRBMOHs6kC07KempujcFRI2YyGvnEGfc4EfD4+ouJSoTYdBtWYA1bwNv/gYn9yNs1DUFh44yPzahANS47xaFLIv3K98yMZFAnhOgppPOT1HZPZg9iq2+yo9JDffwtFiCChbb9uMR67sRjfus4KjIV4N60/0AHJonxGe+RXwWNnO1eelAvi68mz4ZBu7T1et+ou+MBcX6r6eb84TaFDAzQ9L281/szrugLdQgaJ+3ART38ZkhtMAwjC8RH6QpL8uTb0u+ZhxCWXO9D9QKsqUjq+8ahkVB7oiD8GNzEn9mHXltdwh79frB64uhBz35LYbISTOfFjfK3SYMkaSHJcUMhPWSxPAoCyYYUBAOUOP+lXs4bzqkASrRunHwSgGP/jxzFKi3LwwKY00/4hEQbD3AE4Ad8Ot2/UrMn0NKcUTOu7yrTIzS3eb/hL3jry9I/Icgs9ofGNW7J8a87RyVQ3FwPYlViftZflMymN1uQQqGeX9fBgVeW2hmMhtgp/rD+vxsI2hYnIgIIY0l/F+jt/wIYtP924T0x7bsC4H5tMrS2aMJF2Qsw6T2xptys20KYGtoWjcCcUzpQn2wTfavyGfoWH+B7jT/2eLDFlj3xmYLKynwu+/Ee9xuHmVcS50ExGojRbntTOrHwA2QTf5tWER/Z+5EutxzaC2xrO5uxGIU04j7fXJp8nz7UtjJQcq17DETXzmEjuia+WcVgr9faw5uT8Z7XmuoecN4hpigHiKqgumtKwAeA/MgUWQWib/P6z1Lzn/UHjXLpKlec6krHEsJ/BP8gbvKm5DxdU0oYl9Rm/Ey+r3MkXkHUaNl5IexKKg5L3N13QIv30F/myj0ypkDhxxvDGOrPhAo/KLnjGiLruYbF961VAyAoyy9BT/ZZUCqwZIPLuQUL+qMfYAgUhMwyp2OnrEs991oQGVWKVHqCZKL/SsUOP5u83JumMZYkVuDf6K/g+/vLhkGE2mUEDcqmtxpYXbHG4Hu96I0WCe3btjckOEWEQsgo5Vuzqh0WIUSRPaHaqQ6I8+jY7BZq9DYfCQ4Cth7qB0D24Hp1LeG9GDFGNHmnyd4ifXfcDdj6dIst7nTMfT7SuVZIhhlmSs1rByr9gKKL35yAep5/5nIxu5ujUk1cx6DFyHcmH+2eARGV9lCUFWmlylKV+p0160RKP3LZ1h9RcFMdP/LVZXwF8MoTTnMJgDNWncQXaYtaPAHK7WsjuVTo2Vc4wxZkKfl5gM965yAje1WywBOlGxPSwGJUo//eEjDDKLMFnxiODjfF5gg==
  • List-id: Mini-os development list <minios-devel.lists.xenproject.org>

On 04/30/2018 03:44 PM, Simon Kuenzer wrote:
> See my comments inline.
> 
> On 05.04.2018 17:21, Costin Lupu wrote:
>> 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 *);
>> +
> 
> Since you worked on interrupts for all platforms. Do you think it makes
> sense to introduce an UKPLAT API for interrupts, like
> ukplat_irq_register()? If not, then I would prefix those functions with
> "libkvmplat_".

It's clear that the implementations on all platforms (Xen, KVM and
linuxu in the next patch series) show that they converge to a common
API. This should be implemented when we'll add more variables into
equation, such as more drivers, a different interrupt controller (APIC)
and a full ARM porting.

>> +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);
> 
> I would actually return an error value (-ENOMEM) instead of failing with
> an assertion.

My opinion is that the IRQ registering is pretty critical for the system
and if memory isn't available then it's clearly an issue with how the
system is designed or configured or both. At this stage of Unikraft we
shouldn't complicate the error handling too much since it's not a
general purpose OS. I'd rather make it fail fast than let it generate
weird side effects that can be difficult to debug. Also, the IRQ API
implementation should shed some light on which way would be better.

>> +
>> +    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);
>> +}
>> +
> 
> We should prefix these funcitons, too.

I don't understand which prefix that would be. AFAIK, PIC can be used on
Xen as well in an HVM. Please correct if I'm wrong. Again, when
revisiting the IRQ handling, the interrupt controllers implementation
may be moved outside the platform specific code, in a common
module/area/etc.

>> +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));
>> +}
>> +
> 
> Can you prefix these functions, too?

Although this would make sense now, I expect the trap handling on KVM to
be very similar, if not the same, with the trap handling on Xen/HVM.
Which doesn't make it very KVM specific. The names here were chosen on
purpose to reflect the similarity with the implementation for Xen/HVM.

>> +void traps_init(void)
>> +{
>> +    gdt_init();
>> +    tss_init();
>> +    idt_init();
>> +}
>> +
>> +void traps_fini(void)
>> +{
>> +}
>>
> 
> _______________________________________________
> Minios-devel mailing list
> Minios-devel@xxxxxxxxxxxxxxxxxxxx
> https://lists.xenproject.org/mailman/listinfo/minios-devel

_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.