* [kvm-unit-tests PATCH 1/4] arm64: irq handlers don't use esr
2016-01-15 17:41 [kvm-unit-tests PATCH 0/4] arm/arm64: fixes and convenience Andrew Jones
@ 2016-01-15 17:41 ` Andrew Jones
2016-01-15 17:41 ` [kvm-unit-tests PATCH 2/4] arm64: start_usr: no default vectors Andrew Jones
` (3 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Andrew Jones @ 2016-01-15 17:41 UTC (permalink / raw)
To: kvm; +Cc: pbonzini
irq handlers need to be run from a different default vector
handler, and have a different "install" API, than sync
exception handlers.
Signed-off-by: Andrew Jones <drjones@redhat.com>
---
lib/arm64/asm/processor.h | 8 ++++++--
lib/arm64/processor.c | 50 +++++++++++++++++++++++++++++++++++++----------
2 files changed, 46 insertions(+), 12 deletions(-)
diff --git a/lib/arm64/asm/processor.h b/lib/arm64/asm/processor.h
index 228a21c7f8856..30615c5946011 100644
--- a/lib/arm64/asm/processor.h
+++ b/lib/arm64/asm/processor.h
@@ -44,11 +44,15 @@ enum vector {
typedef void (*vector_fn)(enum vector v, struct pt_regs *regs,
unsigned int esr);
typedef void (*exception_fn)(struct pt_regs *regs, unsigned int esr);
+typedef void (*irq_handler_fn)(struct pt_regs *regs);
extern void install_vector_handler(enum vector v, vector_fn fn);
extern void install_exception_handler(enum vector v, unsigned int ec,
exception_fn fn);
-extern void default_vector_handler(enum vector v, struct pt_regs *regs,
- unsigned int esr);
+extern void install_irq_handler(enum vector v, irq_handler_fn fn);
+extern void default_vector_sync_handler(enum vector v, struct pt_regs *regs,
+ unsigned int esr);
+extern void default_vector_irq_handler(enum vector v, struct pt_regs *regs,
+ unsigned int esr);
extern void vector_handlers_default_init(vector_fn *handlers);
extern void show_regs(struct pt_regs *regs);
diff --git a/lib/arm64/processor.c b/lib/arm64/processor.c
index c240ce33c3d0c..f0ce882527262 100644
--- a/lib/arm64/processor.c
+++ b/lib/arm64/processor.c
@@ -101,7 +101,7 @@ bool get_far(unsigned int esr, unsigned long *far)
}
static void bad_exception(enum vector v, struct pt_regs *regs,
- unsigned int esr, bool bad_vector)
+ unsigned int esr, bool esr_valid, bool bad_vector)
{
unsigned long far;
bool far_valid = get_far(esr, &far);
@@ -113,7 +113,7 @@ static void bad_exception(enum vector v, struct pt_regs *regs,
vector_names[v]);
else
printf("Got bad vector=%d\n", v);
- } else {
+ } else if (esr_valid) {
if (ec_names[ec])
printf("Unhandled exception ec=0x%x (%s)\n", ec,
ec_names[ec]);
@@ -137,8 +137,16 @@ void install_exception_handler(enum vector v, unsigned int ec, exception_fn fn)
ti->exception_handlers[v][ec] = fn;
}
-void default_vector_handler(enum vector v, struct pt_regs *regs,
- unsigned int esr)
+void install_irq_handler(enum vector v, irq_handler_fn fn)
+{
+ struct thread_info *ti = current_thread_info();
+
+ if (v < VECTOR_MAX)
+ ti->exception_handlers[v][0] = (exception_fn)fn;
+}
+
+void default_vector_sync_handler(enum vector v, struct pt_regs *regs,
+ unsigned int esr)
{
struct thread_info *ti = thread_info_sp(regs->sp);
unsigned int ec = esr >> ESR_EL1_EC_SHIFT;
@@ -154,15 +162,37 @@ void default_vector_handler(enum vector v, struct pt_regs *regs,
if (ec < EC_MAX && ti->exception_handlers[v][ec])
ti->exception_handlers[v][ec](regs, esr);
else
- bad_exception(v, regs, esr, false);
+ bad_exception(v, regs, esr, true, false);
+}
+
+void default_vector_irq_handler(enum vector v, struct pt_regs *regs,
+ unsigned int esr)
+{
+ struct thread_info *ti = thread_info_sp(regs->sp);
+ irq_handler_fn irq_handler =
+ (irq_handler_fn)ti->exception_handlers[v][0];
+
+ if (ti->flags & TIF_USER_MODE) {
+ if (irq_handler) {
+ irq_handler(regs);
+ return;
+ }
+ ti = current_thread_info();
+ irq_handler = (irq_handler_fn)ti->exception_handlers[v][0];
+ }
+
+ if (irq_handler)
+ irq_handler(regs);
+ else
+ bad_exception(v, regs, esr, false, false);
}
void vector_handlers_default_init(vector_fn *handlers)
{
- handlers[EL1H_SYNC] = default_vector_handler;
- handlers[EL1H_IRQ] = default_vector_handler;
- handlers[EL0_SYNC_64] = default_vector_handler;
- handlers[EL0_IRQ_64] = default_vector_handler;
+ handlers[EL1H_SYNC] = default_vector_sync_handler;
+ handlers[EL1H_IRQ] = default_vector_irq_handler;
+ handlers[EL0_SYNC_64] = default_vector_sync_handler;
+ handlers[EL0_IRQ_64] = default_vector_irq_handler;
}
void do_handle_exception(enum vector v, struct pt_regs *regs, unsigned int esr)
@@ -180,7 +210,7 @@ void do_handle_exception(enum vector v, struct pt_regs *regs, unsigned int esr)
if (v < VECTOR_MAX && ti->vector_handlers[v])
ti->vector_handlers[v](v, regs, esr);
else
- bad_exception(v, regs, esr, true);
+ bad_exception(v, regs, esr, true, true);
}
void install_vector_handler(enum vector v, vector_fn fn)
--
2.4.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [kvm-unit-tests PATCH 2/4] arm64: start_usr: no default vectors
2016-01-15 17:41 [kvm-unit-tests PATCH 0/4] arm/arm64: fixes and convenience Andrew Jones
2016-01-15 17:41 ` [kvm-unit-tests PATCH 1/4] arm64: irq handlers don't use esr Andrew Jones
@ 2016-01-15 17:41 ` Andrew Jones
2016-01-15 17:41 ` [kvm-unit-tests PATCH 3/4] arm64: include esr.h from processor.h Andrew Jones
` (2 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Andrew Jones @ 2016-01-15 17:41 UTC (permalink / raw)
To: kvm; +Cc: pbonzini
Don't install default vector handlers on the usermode stack, as
they'll override handlers installed on the kernel stack.
Signed-off-by: Andrew Jones <drjones@redhat.com>
---
lib/arm64/processor.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/lib/arm64/processor.c b/lib/arm64/processor.c
index f0ce882527262..7f84fe3a09fb1 100644
--- a/lib/arm64/processor.c
+++ b/lib/arm64/processor.c
@@ -221,11 +221,16 @@ void install_vector_handler(enum vector v, vector_fn fn)
ti->vector_handlers[v] = fn;
}
-void thread_info_init(struct thread_info *ti, unsigned int flags)
+static void __thread_info_init(struct thread_info *ti, unsigned int flags)
{
memset(ti, 0, sizeof(struct thread_info));
ti->cpu = mpidr_to_cpu(get_mpidr());
ti->flags = flags;
+}
+
+void thread_info_init(struct thread_info *ti, unsigned int flags)
+{
+ __thread_info_init(ti, flags);
vector_handlers_default_init(ti->vector_handlers);
}
@@ -233,7 +238,7 @@ void start_usr(void (*func)(void *arg), void *arg, unsigned long sp_usr)
{
sp_usr &= (~15UL); /* stack ptr needs 16-byte alignment */
- thread_info_init(thread_info_sp(sp_usr), TIF_USER_MODE);
+ __thread_info_init(thread_info_sp(sp_usr), TIF_USER_MODE);
asm volatile(
"mov x0, %0\n"
--
2.4.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [kvm-unit-tests PATCH 4/4] arm/arm64: make stack creation user friendly
2016-01-15 17:41 [kvm-unit-tests PATCH 0/4] arm/arm64: fixes and convenience Andrew Jones
` (2 preceding siblings ...)
2016-01-15 17:41 ` [kvm-unit-tests PATCH 3/4] arm64: include esr.h from processor.h Andrew Jones
@ 2016-01-15 17:41 ` Andrew Jones
2016-01-19 14:29 ` Paolo Bonzini
2016-01-19 14:30 ` [kvm-unit-tests PATCH 0/4] arm/arm64: fixes and convenience Paolo Bonzini
4 siblings, 1 reply; 7+ messages in thread
From: Andrew Jones @ 2016-01-15 17:41 UTC (permalink / raw)
To: kvm; +Cc: pbonzini
Signed-off-by: Andrew Jones <drjones@redhat.com>
---
arm/selftest.c | 3 +--
lib/arm/asm/thread_info.h | 7 +++++++
lib/arm/smp.c | 4 +---
3 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/arm/selftest.c b/arm/selftest.c
index 3e13296410fc1..aad7eecd529ad 100644
--- a/arm/selftest.c
+++ b/arm/selftest.c
@@ -356,9 +356,8 @@ int main(int argc, char **argv)
} else if (strcmp(argv[0], "vectors-user") == 0) {
- void *sp = memalign(THREAD_SIZE, THREAD_SIZE);
start_usr(check_vectors, NULL,
- (unsigned long)sp + THREAD_START_SP);
+ (unsigned long)thread_stack_alloc());
} else if (strcmp(argv[0], "smp") == 0) {
diff --git a/lib/arm/asm/thread_info.h b/lib/arm/asm/thread_info.h
index 95058bff9d857..7eaac7c32953b 100644
--- a/lib/arm/asm/thread_info.h
+++ b/lib/arm/asm/thread_info.h
@@ -22,6 +22,7 @@
#ifndef __ASSEMBLY__
#include <asm/processor.h>
+#include <alloc.h>
#ifdef __arm__
#include <asm/ptrace.h>
@@ -35,6 +36,12 @@
#define THREAD_START_SP (THREAD_SIZE - 16)
#endif
+static inline void *thread_stack_alloc(void)
+{
+ void *sp = memalign(THREAD_SIZE, THREAD_SIZE);
+ return sp + THREAD_START_SP;
+}
+
#define TIF_USER_MODE (1U << 0)
struct thread_info {
diff --git a/lib/arm/smp.c b/lib/arm/smp.c
index 390c53b5d84c3..bbaf9e60e9506 100644
--- a/lib/arm/smp.c
+++ b/lib/arm/smp.c
@@ -6,7 +6,6 @@
* This work is licensed under the terms of the GNU LGPL, version 2.
*/
#include <libcflat.h>
-#include <alloc.h>
#include <asm/thread_info.h>
#include <asm/cpumask.h>
#include <asm/barrier.h>
@@ -43,10 +42,9 @@ secondary_entry_fn secondary_cinit(void)
void smp_boot_secondary(int cpu, secondary_entry_fn entry)
{
- void *stack_base = memalign(THREAD_SIZE, THREAD_SIZE);
int ret;
- secondary_data.stack = stack_base + THREAD_START_SP;
+ secondary_data.stack = thread_stack_alloc();
secondary_data.entry = entry;
mmu_mark_disabled(cpu);
ret = cpu_psci_cpu_boot(cpu);
--
2.4.3
^ permalink raw reply related [flat|nested] 7+ messages in thread