From: Auger Eric <eric.auger@redhat.com>
To: Ricardo Koller <ricarkol@google.com>
Cc: Marc Zyngier <maz@kernel.org>,
kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu,
pbonzini@redhat.com, drjones@redhat.com,
alexandru.elisei@arm.com
Subject: Re: [PATCH v2 4/5] KVM: selftests: Add exception handling support for aarch64
Date: Fri, 7 May 2021 16:08:07 +0200 [thread overview]
Message-ID: <8a99d57b-0513-557c-79e0-98084799812f@redhat.com> (raw)
In-Reply-To: <YJRADhU4CcTE7bdm@google.com>
Hi Ricardo,
On 5/6/21 9:14 PM, Ricardo Koller wrote:
> On Thu, May 06, 2021 at 02:30:17PM +0200, Auger Eric wrote:
>> Hi Ricardo,
>>
>
> Hi Eric,
>
> Thank you very much for the test.
>
>> On 5/3/21 9:12 PM, Ricardo Koller wrote:
>>> On Mon, May 03, 2021 at 11:32:39AM +0100, Marc Zyngier wrote:
>>>> On Sat, 01 May 2021 00:24:06 +0100,
>>>> Ricardo Koller <ricarkol@google.com> wrote:
>>>>>
>>>>> Add the infrastructure needed to enable exception handling in aarch64
>>>>> selftests. The exception handling defaults to an unhandled-exception
>>>>> handler which aborts the test, just like x86. These handlers can be
>>>>> overridden by calling vm_install_vector_handler(vector) or
>>>>> vm_install_exception_handler(vector, ec). The unhandled exception
>>>>> reporting from the guest is done using the ucall type introduced in a
>>>>> previous commit, UCALL_UNHANDLED.
>>>>>
>>>>> The exception handling code is heavily inspired on kvm-unit-tests.
>>
>> running the test on 5.12 I get
>>
>> ==== Test Assertion Failure ====
>> aarch64/debug-exceptions.c:232: false
>> pid=6477 tid=6477 errno=4 - Interrupted system call
>> 1 0x000000000040147b: main at debug-exceptions.c:230
>> 2 0x000003ff8aa60de3: ?? ??:0
>> 3 0x0000000000401517: _start at :?
>> Failed guest assert: hw_bp_addr == PC(hw_bp) at
>> aarch64/debug-exceptions.c:105
>> values: 0, 0x401794
>>
>>
>> I guess it is not an expected result. Any known bug waiting on the list?
>>
>
> Not expected. That should work, or at least abort early because there is
> no HW breakpoints support.
>
> I'm trying to reproduce the failure; can you help me with some
> questions, please?
sure, please find the answers below.
>
> - does your setup have support for hardware breakpoints? Can you try a
> 'dmesg | grep break'? I'm looking for something like 'hw-breakpoint:
> found ...'. If there is no such line it's very likely that the check
> for "debug_ver >= 6" is not enough and the test should check for
> "num_breakpoints > 0".
[ 25.640418] hw-breakpoint: found 6 breakpoint and 4 watchpoint registers.
> - does it fail consistently (every single attempt)?
yes it does.
I will try to find some time to investigate too
Thanks
Eric
>
> Thanks!
> Ricardo
>
>>
>> Thanks
>>
>> Eric
>
>
>>>>>
>>>>> Signed-off-by: Ricardo Koller <ricarkol@google.com>
>>>>> ---
>>>>> tools/testing/selftests/kvm/Makefile | 2 +-
>>>>> .../selftests/kvm/include/aarch64/processor.h | 78 +++++++++++
>>>>> .../selftests/kvm/lib/aarch64/handlers.S | 130 ++++++++++++++++++
>>>>> .../selftests/kvm/lib/aarch64/processor.c | 124 +++++++++++++++++
>>>>> 4 files changed, 333 insertions(+), 1 deletion(-)
>>>>> create mode 100644 tools/testing/selftests/kvm/lib/aarch64/handlers.S
>>>>>
>>>>> diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
>>>>> index 4e548d7ab0ab..618c5903f478 100644
>>>>> --- a/tools/testing/selftests/kvm/Makefile
>>>>> +++ b/tools/testing/selftests/kvm/Makefile
>>>>> @@ -35,7 +35,7 @@ endif
>>>>>
>>>>> LIBKVM = lib/assert.c lib/elf.c lib/io.c lib/kvm_util.c lib/sparsebit.c lib/test_util.c lib/guest_modes.c lib/perf_test_util.c
>>>>> LIBKVM_x86_64 = lib/x86_64/processor.c lib/x86_64/vmx.c lib/x86_64/svm.c lib/x86_64/ucall.c lib/x86_64/handlers.S
>>>>> -LIBKVM_aarch64 = lib/aarch64/processor.c lib/aarch64/ucall.c
>>>>> +LIBKVM_aarch64 = lib/aarch64/processor.c lib/aarch64/ucall.c lib/aarch64/handlers.S
>>>>> LIBKVM_s390x = lib/s390x/processor.c lib/s390x/ucall.c lib/s390x/diag318_test_handler.c
>>>>>
>>>>> TEST_GEN_PROGS_x86_64 = x86_64/cr4_cpuid_sync_test
>>>>> diff --git a/tools/testing/selftests/kvm/include/aarch64/processor.h b/tools/testing/selftests/kvm/include/aarch64/processor.h
>>>>> index b7fa0c8551db..40aae31b4afc 100644
>>>>> --- a/tools/testing/selftests/kvm/include/aarch64/processor.h
>>>>> +++ b/tools/testing/selftests/kvm/include/aarch64/processor.h
>>>>> @@ -8,6 +8,7 @@
>>>>> #define SELFTEST_KVM_PROCESSOR_H
>>>>>
>>>>> #include "kvm_util.h"
>>>>> +#include <linux/stringify.h>
>>>>>
>>>>>
>>>>> #define ARM64_CORE_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \
>>>>> @@ -18,6 +19,7 @@
>>>>> #define MAIR_EL1 3, 0, 10, 2, 0
>>>>> #define TTBR0_EL1 3, 0, 2, 0, 0
>>>>> #define SCTLR_EL1 3, 0, 1, 0, 0
>>>>> +#define VBAR_EL1 3, 0, 12, 0, 0
>>>>>
>>>>> /*
>>>>> * Default MAIR
>>>>> @@ -56,4 +58,80 @@ void aarch64_vcpu_setup(struct kvm_vm *vm, int vcpuid, struct kvm_vcpu_init *ini
>>>>> void aarch64_vcpu_add_default(struct kvm_vm *vm, uint32_t vcpuid,
>>>>> struct kvm_vcpu_init *init, void *guest_code);
>>>>>
>>>>> +struct ex_regs {
>>>>> + u64 regs[31];
>>>>> + u64 sp;
>>>>> + u64 pc;
>>>>> + u64 pstate;
>>>>> +};
>>>>> +
>>>>> +#define VECTOR_NUM 16
>>>>> +
>>>>> +enum {
>>>>> + VECTOR_SYNC_CURRENT_SP0,
>>>>> + VECTOR_IRQ_CURRENT_SP0,
>>>>> + VECTOR_FIQ_CURRENT_SP0,
>>>>> + VECTOR_ERROR_CURRENT_SP0,
>>>>> +
>>>>> + VECTOR_SYNC_CURRENT,
>>>>> + VECTOR_IRQ_CURRENT,
>>>>> + VECTOR_FIQ_CURRENT,
>>>>> + VECTOR_ERROR_CURRENT,
>>>>> +
>>>>> + VECTOR_SYNC_LOWER_64,
>>>>> + VECTOR_IRQ_LOWER_64,
>>>>> + VECTOR_FIQ_LOWER_64,
>>>>> + VECTOR_ERROR_LOWER_64,
>>>>> +
>>>>> + VECTOR_SYNC_LOWER_32,
>>>>> + VECTOR_IRQ_LOWER_32,
>>>>> + VECTOR_FIQ_LOWER_32,
>>>>> + VECTOR_ERROR_LOWER_32,
>>>>> +};
>>>>> +
>>>>> +#define VECTOR_IS_SYNC(v) ((v) == VECTOR_SYNC_CURRENT_SP0 || \
>>>>> + (v) == VECTOR_SYNC_CURRENT || \
>>>>> + (v) == VECTOR_SYNC_LOWER_64 || \
>>>>> + (v) == VECTOR_SYNC_LOWER_32)
>>>>> +
>>>>> +/* Some common EC (Exception classes) */
>>>>> +#define ESR_EC_ILLEGAL_INS 0x0e
>>>>> +#define ESR_EC_SVC64 0x15
>>>>> +#define ESR_EC_IABORT_CURRENT 0x21
>>>>> +#define ESR_EC_DABORT_CURRENT 0x25
>>>>> +#define ESR_EC_SERROR 0x2f
>>>>> +#define ESR_EC_HW_BP_CURRENT 0x31
>>>>> +#define ESR_EC_SSTEP_CURRENT 0x33
>>>>> +#define ESR_EC_WP_CURRENT 0x35
>>>>> +#define ESR_EC_BRK_INS 0x3C
>>>>> +
>>>>> +#define ESR_EC_NUM 64
>>>>> +
>>>>> +#define ESR_EC_SHIFT 26
>>>>> +#define ESR_EC_MASK (ESR_EC_NUM - 1)
>>>>> +
>>>>> +void vm_init_descriptor_tables(struct kvm_vm *vm);
>>>>> +void vcpu_init_descriptor_tables(struct kvm_vm *vm, uint32_t vcpuid);
>>>>> +
>>>>> +typedef void(*handler_fn)(struct ex_regs *);
>>>>> +void vm_install_exception_handler(struct kvm_vm *vm,
>>>>> + int vector, int ec, handler_fn handler);
>>>>> +void vm_install_vector_handler(struct kvm_vm *vm,
>>>>> + int vector, handler_fn handler);
>>>>> +
>>>>> +#define SPSR_D (1 << 9)
>>>>> +#define SPSR_SS (1 << 21)
>>>>> +
>>>>> +#define write_sysreg(reg, val) \
>>>>> +({ \
>>>>> + u64 __val = (u64)(val); \
>>>>> + asm volatile("msr " __stringify(reg) ", %x0" : : "rZ" (__val)); \
>>>>> +})
>>>>> +
>>>>> +#define read_sysreg(reg) \
>>>>> +({ u64 val; \
>>>>> + asm volatile("mrs %0, "__stringify(reg) : "=r"(val) : : "memory");\
>>>>> + val; \
>>>>> +})
>>>>> +
>>>>> #endif /* SELFTEST_KVM_PROCESSOR_H */
>>>>> diff --git a/tools/testing/selftests/kvm/lib/aarch64/handlers.S b/tools/testing/selftests/kvm/lib/aarch64/handlers.S
>>>>> new file mode 100644
>>>>> index 000000000000..8a560021892b
>>>>> --- /dev/null
>>>>> +++ b/tools/testing/selftests/kvm/lib/aarch64/handlers.S
>>>>> @@ -0,0 +1,130 @@
>>>>> +/* SPDX-License-Identifier: GPL-2.0 */
>>>>> +.macro save_registers, vector
>>>>> + add sp, sp, #-16 * 17
>>>>> +
>>>>> + stp x0, x1, [sp, #16 * 0]
>>>>> + stp x2, x3, [sp, #16 * 1]
>>>>> + stp x4, x5, [sp, #16 * 2]
>>>>> + stp x6, x7, [sp, #16 * 3]
>>>>> + stp x8, x9, [sp, #16 * 4]
>>>>> + stp x10, x11, [sp, #16 * 5]
>>>>> + stp x12, x13, [sp, #16 * 6]
>>>>> + stp x14, x15, [sp, #16 * 7]
>>>>> + stp x16, x17, [sp, #16 * 8]
>>>>> + stp x18, x19, [sp, #16 * 9]
>>>>> + stp x20, x21, [sp, #16 * 10]
>>>>> + stp x22, x23, [sp, #16 * 11]
>>>>> + stp x24, x25, [sp, #16 * 12]
>>>>> + stp x26, x27, [sp, #16 * 13]
>>>>> + stp x28, x29, [sp, #16 * 14]
>>>>> +
>>>>> + .if \vector >= 8
>>>>> + mrs x1, sp_el0
>>>>
>>>> I'm still a bit perplexed by this. SP_EL0 is never changed, since you
>>>> always run in handler mode. Therefore, saving/restoring it is only
>>>> overhead. If an exception handler wants to introspect it, it is
>>>> already available in the relevant system register.
>>>>
>>>> Or did you have something else in mind for it?
>>>>
>>>
>>> Not really. The reason for saving sp_el0 in there was just for
>>> consistency, so that handlers for both el0 and el1 exceptions could get
>>> the sp at regs->sp.
>>>
>>> Restoring sp_el0 might be too much. So, what do you think of this v3: we
>>> keep the saving of sp_el0 into regs->sp (to keep things the same between
>>> el0 and el1) and delete the restoring of sp_el0?
>>>
>>> Thanks,
>>> Ricardo
>>>
>>>>> + .else
>>>>> + /*
>>>>> + * This stores sp_el1 into ex_regs.sp so exception handlers can
>>>>> + * "look" at it. It will _not_ be used to restore the sp_el1 on
>>>>> + * return from the exception so handlers can not update it.
>>>>> + */
>>>>> + mov x1, sp
>>>>> + .endif
>>>>> + stp x30, x1, [sp, #16 * 15] /* x30, SP */
>>>>> +
>>>>> + mrs x1, elr_el1
>>>>> + mrs x2, spsr_el1
>>>>> + stp x1, x2, [sp, #16 * 16] /* PC, PSTATE */
>>>>> +.endm
>>>>> +
>>>>> +.macro restore_registers, vector
>>>>> + ldp x1, x2, [sp, #16 * 16] /* PC, PSTATE */
>>>>> + msr elr_el1, x1
>>>>> + msr spsr_el1, x2
>>>>> +
>>>>> + ldp x30, x1, [sp, #16 * 15] /* x30, SP */
>>>>> + .if \vector >= 8
>>>>> + msr sp_el0, x1
>>>>> + .endif
>>>>> +
>>>>> + ldp x28, x29, [sp, #16 * 14]
>>>>> + ldp x26, x27, [sp, #16 * 13]
>>>>> + ldp x24, x25, [sp, #16 * 12]
>>>>> + ldp x22, x23, [sp, #16 * 11]
>>>>> + ldp x20, x21, [sp, #16 * 10]
>>>>> + ldp x18, x19, [sp, #16 * 9]
>>>>> + ldp x16, x17, [sp, #16 * 8]
>>>>> + ldp x14, x15, [sp, #16 * 7]
>>>>> + ldp x12, x13, [sp, #16 * 6]
>>>>> + ldp x10, x11, [sp, #16 * 5]
>>>>> + ldp x8, x9, [sp, #16 * 4]
>>>>> + ldp x6, x7, [sp, #16 * 3]
>>>>> + ldp x4, x5, [sp, #16 * 2]
>>>>> + ldp x2, x3, [sp, #16 * 1]
>>>>> + ldp x0, x1, [sp, #16 * 0]
>>>>> +
>>>>> + add sp, sp, #16 * 17
>>>>> +
>>>>> + eret
>>>>> +.endm
>>>>> +
>>>>> +.pushsection ".entry.text", "ax"
>>>>> +.balign 0x800
>>>>> +.global vectors
>>>>> +vectors:
>>>>> +.popsection
>>>>> +
>>>>> +.set vector, 0
>>>>> +
>>>>> +/*
>>>>> + * Build an exception handler for vector and append a jump to it into
>>>>> + * vectors (while making sure that it's 0x80 aligned).
>>>>> + */
>>>>> +.macro HANDLER, label
>>>>> +handler_\()\label:
>>>>> + save_registers vector
>>>>> + mov x0, sp
>>>>> + mov x1, #vector
>>>>> + bl route_exception
>>>>> + restore_registers vector
>>>>> +
>>>>> +.pushsection ".entry.text", "ax"
>>>>> +.balign 0x80
>>>>> + b handler_\()\label
>>>>> +.popsection
>>>>> +
>>>>> +.set vector, vector + 1
>>>>> +.endm
>>>>> +
>>>>> +.macro HANDLER_INVALID
>>>>> +.pushsection ".entry.text", "ax"
>>>>> +.balign 0x80
>>>>> +/* This will abort so no need to save and restore registers. */
>>>>> + mov x0, #vector
>>>>> + b kvm_exit_unexpected_vector
>>>>> +.popsection
>>>>> +
>>>>> +.set vector, vector + 1
>>>>> +.endm
>>>>> +
>>>>> +/*
>>>>> + * Caution: be sure to not add anything between the declaration of vectors
>>>>> + * above and these macro calls that will build the vectors table below it.
>>>>> + */
>>>>> + HANDLER_INVALID // Synchronous EL1t
>>>>> + HANDLER_INVALID // IRQ EL1t
>>>>> + HANDLER_INVALID // FIQ EL1t
>>>>> + HANDLER_INVALID // Error EL1t
>>>>> +
>>>>> + HANDLER el1h_sync // Synchronous EL1h
>>>>> + HANDLER el1h_irq // IRQ EL1h
>>>>> + HANDLER el1h_fiq // FIQ EL1h
>>>>> + HANDLER el1h_error // Error EL1h
>>>>> +
>>>>> + HANDLER el0_sync_64 // Synchronous 64-bit EL0
>>>>> + HANDLER el0_irq_64 // IRQ 64-bit EL0
>>>>> + HANDLER el0_fiq_64 // FIQ 64-bit EL0
>>>>> + HANDLER el0_error_64 // Error 64-bit EL0
>>>>> +
>>>>> + HANDLER el0_sync_32 // Synchronous 32-bit EL0
>>>>> + HANDLER el0_irq_32 // IRQ 32-bit EL0
>>>>> + HANDLER el0_fiq_32 // FIQ 32-bit EL0
>>>>> + HANDLER el0_error_32 // Error 32-bit EL0
>>>>> diff --git a/tools/testing/selftests/kvm/lib/aarch64/processor.c b/tools/testing/selftests/kvm/lib/aarch64/processor.c
>>>>> index cee92d477dc0..25be71ec88be 100644
>>>>> --- a/tools/testing/selftests/kvm/lib/aarch64/processor.c
>>>>> +++ b/tools/testing/selftests/kvm/lib/aarch64/processor.c
>>>>> @@ -6,6 +6,7 @@
>>>>> */
>>>>>
>>>>> #include <linux/compiler.h>
>>>>> +#include <assert.h>
>>>>>
>>>>> #include "kvm_util.h"
>>>>> #include "../kvm_util_internal.h"
>>>>> @@ -14,6 +15,8 @@
>>>>> #define KVM_GUEST_PAGE_TABLE_MIN_PADDR 0x180000
>>>>> #define DEFAULT_ARM64_GUEST_STACK_VADDR_MIN 0xac0000
>>>>>
>>>>> +vm_vaddr_t exception_handlers;
>>>>> +
>>>>> static uint64_t page_align(struct kvm_vm *vm, uint64_t v)
>>>>> {
>>>>> return (v + vm->page_size) & ~(vm->page_size - 1);
>>>>> @@ -334,6 +337,127 @@ void vcpu_args_set(struct kvm_vm *vm, uint32_t vcpuid, unsigned int num, ...)
>>>>> va_end(ap);
>>>>> }
>>>>>
>>>>> +void kvm_exit_unexpected_vector(int vector)
>>>>> +{
>>>>> + ucall(UCALL_UNHANDLED, 3, vector, 0, false /* !valid_ec */);
>>>>> +}
>>>>> +
>>>>> +void kvm_exit_unexpected_exception(int vector, uint64_t ec)
>>>>> +{
>>>>> + ucall(UCALL_UNHANDLED, 3, vector, ec, true /* valid_ec */);
>>>>> +}
>>>>> +
>>>>> void assert_on_unhandled_exception(struct kvm_vm *vm, uint32_t vcpuid)
>>>>> {
>>>>> + struct ucall uc;
>>>>> +
>>>>> + if (get_ucall(vm, vcpuid, &uc) != UCALL_UNHANDLED)
>>>>> + return;
>>>>> +
>>>>> + if (uc.args[2]) /* valid_ec */ {
>>>>> + assert(VECTOR_IS_SYNC(uc.args[0]));
>>>>> + TEST_ASSERT(false,
>>>>> + "Unexpected exception (vector:0x%lx, ec:0x%lx)",
>>>>> + uc.args[0], uc.args[1]);
>>>>> + } else {
>>>>> + assert(!VECTOR_IS_SYNC(uc.args[0]));
>>>>> + TEST_ASSERT(false,
>>>>> + "Unexpected exception (vector:0x%lx)",
>>>>> + uc.args[0]);
>>>>> + }
>>>>> +}
>>>>> +
>>>>> +/*
>>>>> + * This exception handling code was heavily inspired on kvm-unit-tests. There
>>>>> + * is a set of default vector handlers stored in vector_handlers. These default
>>>>> + * vector handlers call user-installed handlers stored in exception_handlers.
>>>>> + * Synchronous handlers are indexed by (vector, ec), and irq handlers by
>>>>> + * (vector, ec=0).
>>>>> + */
>>>>> +
>>>>> +typedef void(*vector_fn)(struct ex_regs *, int vector);
>>>>> +
>>>>> +struct handlers {
>>>>> + vector_fn vector_handlers[VECTOR_NUM];
>>>>> + handler_fn exception_handlers[VECTOR_NUM][ESR_EC_NUM];
>>>>> +};
>>>>> +
>>>>> +void vcpu_init_descriptor_tables(struct kvm_vm *vm, uint32_t vcpuid)
>>>>> +{
>>>>> + extern char vectors;
>>>>> +
>>>>> + set_reg(vm, vcpuid, ARM64_SYS_REG(VBAR_EL1), (uint64_t)&vectors);
>>>>> +}
>>>>> +
>>>>> +void default_sync_handler(struct ex_regs *regs, int vector)
>>>>> +{
>>>>> + struct handlers *handlers = (struct handlers *)exception_handlers;
>>>>> + uint64_t esr = read_sysreg(esr_el1);
>>>>> + uint64_t ec = (esr >> ESR_EC_SHIFT) & ESR_EC_MASK;
>>>>> +
>>>>> + GUEST_ASSERT(VECTOR_IS_SYNC(vector));
>>>>> +
>>>>> + if (handlers && handlers->exception_handlers[vector][ec])
>>>>> + handlers->exception_handlers[vector][ec](regs);
>>>>> + else
>>>>> + kvm_exit_unexpected_exception(vector, ec);
>>>>> +}
>>>>> +
>>>>> +void default_irq_handler(struct ex_regs *regs, int vector)
>>>>> +{
>>>>> + struct handlers *handlers = (struct handlers *)exception_handlers;
>>>>> +
>>>>> + GUEST_ASSERT(!VECTOR_IS_SYNC(vector));
>>>>> +
>>>>> + if (handlers && handlers->exception_handlers[vector][0])
>>>>> + handlers->exception_handlers[vector][0](regs);
>>>>> + else
>>>>> + kvm_exit_unexpected_vector(vector);
>>>>> +}
>>>>> +
>>>>> +void route_exception(struct ex_regs *regs, int vector)
>>>>> +{
>>>>> + struct handlers *handlers = (struct handlers *)exception_handlers;
>>>>> +
>>>>> + if (handlers && handlers->vector_handlers[vector])
>>>>> + handlers->vector_handlers[vector](regs, vector);
>>>>> + else
>>>>> + kvm_exit_unexpected_vector(vector);
>>>>> +}
>>>>> +
>>>>> +void vm_init_descriptor_tables(struct kvm_vm *vm)
>>>>> +{
>>>>> + struct handlers *handlers;
>>>>> +
>>>>> + vm->handlers = vm_vaddr_alloc(vm, sizeof(struct handlers),
>>>>> + vm->page_size, 0, 0);
>>>>> +
>>>>> + handlers = (struct handlers *)addr_gva2hva(vm, vm->handlers);
>>>>> + handlers->vector_handlers[VECTOR_SYNC_CURRENT] = default_sync_handler;
>>>>> + handlers->vector_handlers[VECTOR_IRQ_CURRENT] = default_irq_handler;
>>>>> + handlers->vector_handlers[VECTOR_SYNC_LOWER_64] = default_sync_handler;
>>>>> + handlers->vector_handlers[VECTOR_IRQ_LOWER_64] = default_irq_handler;
>>>>
>>>> How about FIQ, Error? Although they are unlikely, they are valid
>>>> exceptions.
>>>>
>>>>> +
>>>>> + *(vm_vaddr_t *)addr_gva2hva(vm, (vm_vaddr_t)(&exception_handlers)) = vm->handlers;
>>>>> +}
>>>>> +
>>>>> +void vm_install_exception_handler(struct kvm_vm *vm, int vector, int ec,
>>>>> + void (*handler)(struct ex_regs *))
>>>>> +{
>>>>> + struct handlers *handlers = (struct handlers *)addr_gva2hva(vm, vm->handlers);
>>>>> +
>>>>> + assert(VECTOR_IS_SYNC(vector));
>>>>> + assert(vector < VECTOR_NUM);
>>>>> + assert(ec < ESR_EC_NUM);
>>>>> + handlers->exception_handlers[vector][ec] = handler;
>>>>> +}
>>>>> +
>>>>> +void vm_install_vector_handler(struct kvm_vm *vm, int vector,
>>>>> + void (*handler)(struct ex_regs *))
>>>>> +{
>>>>> + struct handlers *handlers = (struct handlers *)addr_gva2hva(vm, vm->handlers);
>>>>> +
>>>>> + assert(!VECTOR_IS_SYNC(vector));
>>>>> + assert(vector < VECTOR_NUM);
>>>>> + handlers->exception_handlers[vector][0] = handler;
>>>>> }
>>>>
>>>> Thanks,
>>>>
>>>> M.
>>>>
>>>> --
>>>> Without deviation from the norm, progress is not possible.
>>>
>>
>
next prev parent reply other threads:[~2021-05-07 14:08 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-04-30 23:24 [PATCH v2 0/5] KVM: selftests: arm64 exception handling and debug test Ricardo Koller
2021-04-30 23:24 ` [PATCH v2 1/5] KVM: selftests: Rename vm_handle_exception Ricardo Koller
2021-05-03 11:02 ` Andrew Jones
2021-05-06 12:27 ` Auger Eric
2021-04-30 23:24 ` [PATCH v2 2/5] KVM: selftests: Introduce UCALL_UNHANDLED for unhandled vector reporting Ricardo Koller
2021-05-03 11:09 ` Andrew Jones
2021-05-06 12:27 ` Auger Eric
2021-04-30 23:24 ` [PATCH v2 3/5] KVM: selftests: Move GUEST_ASSERT_EQ to utils header Ricardo Koller
2021-05-03 11:31 ` Andrew Jones
2021-04-30 23:24 ` [PATCH v2 4/5] KVM: selftests: Add exception handling support for aarch64 Ricardo Koller
2021-05-03 10:32 ` Marc Zyngier
2021-05-03 19:12 ` Ricardo Koller
2021-05-06 12:30 ` Auger Eric
2021-05-06 19:14 ` Ricardo Koller
2021-05-07 14:08 ` Auger Eric [this message]
2021-05-07 17:54 ` Ricardo Koller
2021-05-12 7:27 ` Ricardo Koller
2021-05-12 8:19 ` Auger Eric
2021-05-12 8:33 ` Marc Zyngier
2021-05-12 8:52 ` Auger Eric
2021-05-12 16:06 ` Ricardo Koller
2021-05-12 12:59 ` Zenghui Yu
2021-05-12 13:43 ` Marc Zyngier
2021-05-12 16:03 ` Ricardo Koller
2021-05-12 16:18 ` Marc Zyngier
2021-05-12 21:39 ` Ricardo Koller
2021-05-07 14:31 ` Marc Zyngier
2021-05-07 18:02 ` Ricardo Koller
2021-05-03 12:39 ` Andrew Jones
2021-04-30 23:24 ` [PATCH v2 5/5] KVM: selftests: Add aarch64/debug-exceptions test Ricardo Koller
2021-05-03 12:49 ` Andrew Jones
2021-05-24 12:14 ` [PATCH v2 0/5] KVM: selftests: arm64 exception handling and debug test Paolo Bonzini
2021-05-24 12:59 ` Marc Zyngier
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=8a99d57b-0513-557c-79e0-98084799812f@redhat.com \
--to=eric.auger@redhat.com \
--cc=alexandru.elisei@arm.com \
--cc=drjones@redhat.com \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.cs.columbia.edu \
--cc=maz@kernel.org \
--cc=pbonzini@redhat.com \
--cc=ricarkol@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).