diff mbox series

[v1,06/14] xen/riscv: introduce exception context

Message ID 00ecc26833738377003ad21603c198ae4278cfd3.1674226563.git.oleksii.kurochko@gmail.com (mailing list archive)
State Superseded
Headers show
Series RISCV basic exception handling implementation | expand

Commit Message

Oleksii Kurochko Jan. 20, 2023, 2:59 p.m. UTC
The patch introduces a set of registers which should be saved to and
restored from a stack after an exception occurs and a set of defines
which will be used during exception context saving/restoring.

Originally <asm/processor.h> header was introduced in the patch series
from Bobby so mostly it was re-used and removed unneeded things from
it now.

Signed-off-by: Bobby Eshleman <bobby.eshleman@gmail.com>
Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
 xen/arch/riscv/include/asm/processor.h | 114 +++++++++++++++++++++++++
 1 file changed, 114 insertions(+)
 create mode 100644 xen/arch/riscv/include/asm/processor.h

Comments

Andrew Cooper Jan. 20, 2023, 3:54 p.m. UTC | #1
On 20/01/2023 2:59 pm, Oleksii Kurochko wrote:
> diff --git a/xen/arch/riscv/include/asm/processor.h b/xen/arch/riscv/include/asm/processor.h
> new file mode 100644
> index 0000000000..5898a09ce6
> --- /dev/null
> +++ b/xen/arch/riscv/include/asm/processor.h
> @@ -0,0 +1,114 @@
> +/* SPDX-License-Identifier: MIT */
> +/******************************************************************************
> + *
> + * Copyright 2019 (C) Alistair Francis <alistair.francis@wdc.com>
> + * Copyright 2021 (C) Bobby Eshleman <bobby.eshleman@gmail.com>
> + * Copyright 2023 (C) Vates
> + *
> + */
> +
> +#ifndef _ASM_RISCV_PROCESSOR_H
> +#define _ASM_RISCV_PROCESSOR_H
> +
> +#include <asm/types.h>
> +
> +#define RISCV_CPU_USER_REGS_zero        0
> +#define RISCV_CPU_USER_REGS_ra          1
> +#define RISCV_CPU_USER_REGS_sp          2
> +#define RISCV_CPU_USER_REGS_gp          3
> +#define RISCV_CPU_USER_REGS_tp          4
> +#define RISCV_CPU_USER_REGS_t0          5
> +#define RISCV_CPU_USER_REGS_t1          6
> +#define RISCV_CPU_USER_REGS_t2          7
> +#define RISCV_CPU_USER_REGS_s0          8
> +#define RISCV_CPU_USER_REGS_s1          9
> +#define RISCV_CPU_USER_REGS_a0          10
> +#define RISCV_CPU_USER_REGS_a1          11
> +#define RISCV_CPU_USER_REGS_a2          12
> +#define RISCV_CPU_USER_REGS_a3          13
> +#define RISCV_CPU_USER_REGS_a4          14
> +#define RISCV_CPU_USER_REGS_a5          15
> +#define RISCV_CPU_USER_REGS_a6          16
> +#define RISCV_CPU_USER_REGS_a7          17
> +#define RISCV_CPU_USER_REGS_s2          18
> +#define RISCV_CPU_USER_REGS_s3          19
> +#define RISCV_CPU_USER_REGS_s4          20
> +#define RISCV_CPU_USER_REGS_s5          21
> +#define RISCV_CPU_USER_REGS_s6          22
> +#define RISCV_CPU_USER_REGS_s7          23
> +#define RISCV_CPU_USER_REGS_s8          24
> +#define RISCV_CPU_USER_REGS_s9          25
> +#define RISCV_CPU_USER_REGS_s10         26
> +#define RISCV_CPU_USER_REGS_s11         27
> +#define RISCV_CPU_USER_REGS_t3          28
> +#define RISCV_CPU_USER_REGS_t4          29
> +#define RISCV_CPU_USER_REGS_t5          30
> +#define RISCV_CPU_USER_REGS_t6          31
> +#define RISCV_CPU_USER_REGS_sepc        32
> +#define RISCV_CPU_USER_REGS_sstatus     33
> +#define RISCV_CPU_USER_REGS_pregs       34
> +#define RISCV_CPU_USER_REGS_last        35

This block wants moving into the asm-offsets infrastructure, but I
suspect they won't want to survive in this form.

edit: yeah, definitely not this form.  RISCV_CPU_USER_REGS_OFFSET is a
recipe for bugs.

> +
> +#define RISCV_CPU_USER_REGS_OFFSET(x)   ((RISCV_CPU_USER_REGS_##x) * __SIZEOF_POINTER__)
> +#define RISCV_CPU_USER_REGS_SIZE        RISCV_CPU_USER_REGS_OFFSET(last)
> +
> +#ifndef __ASSEMBLY__
> +
> +/* On stack VCPU state */
> +struct cpu_user_regs
> +{
> +    register_t zero;

unsigned long.

> +    register_t ra;
> +    register_t sp;
> +    register_t gp;
> +    register_t tp;
> +    register_t t0;
> +    register_t t1;
> +    register_t t2;
> +    register_t s0;
> +    register_t s1;
> +    register_t a0;
> +    register_t a1;
> +    register_t a2;
> +    register_t a3;
> +    register_t a4;
> +    register_t a5;
> +    register_t a6;
> +    register_t a7;
> +    register_t s2;
> +    register_t s3;
> +    register_t s4;
> +    register_t s5;
> +    register_t s6;
> +    register_t s7;
> +    register_t s8;
> +    register_t s9;
> +    register_t s10;
> +    register_t s11;
> +    register_t t3;
> +    register_t t4;
> +    register_t t5;
> +    register_t t6;
> +    register_t sepc;
> +    register_t sstatus;
> +    /* pointer to previous stack_cpu_regs */
> +    register_t pregs;

Stale comment?  Also, surely this wants to be cpu_user_regs *pregs; ?

> +};
> +
> +static inline void wait_for_interrupt(void)

There's no point writing out the name in longhand for a wrapper around a
single instruction.

~Andrew
Jan Beulich Jan. 23, 2023, 11:13 a.m. UTC | #2
On 20.01.2023 15:59, Oleksii Kurochko wrote:
> +/* On stack VCPU state */
> +struct cpu_user_regs
> +{
> +    register_t zero;
> +    register_t ra;
> +    register_t sp;
> +    register_t gp;
> +    register_t tp;
> +    register_t t0;
> +    register_t t1;
> +    register_t t2;
> +    register_t s0;
> +    register_t s1;
> +    register_t a0;
> +    register_t a1;
> +    register_t a2;
> +    register_t a3;
> +    register_t a4;
> +    register_t a5;
> +    register_t a6;
> +    register_t a7;
> +    register_t s2;
> +    register_t s3;
> +    register_t s4;
> +    register_t s5;
> +    register_t s6;
> +    register_t s7;
> +    register_t s8;
> +    register_t s9;
> +    register_t s10;
> +    register_t s11;
> +    register_t t3;
> +    register_t t4;
> +    register_t t5;
> +    register_t t6;
> +    register_t sepc;
> +    register_t sstatus;
> +    /* pointer to previous stack_cpu_regs */
> +    register_t pregs;
> +};

What is the planned correlation of this to what x86 a Arm have in their
public headers (under the same name)? I think the public header want
spelling out first, and if a different internal structure is intended to
be used, the interaction between the two would then want outlining in
the description here.

Jan
Oleksii Kurochko Jan. 23, 2023, 12:03 p.m. UTC | #3
On Fri, 2023-01-20 at 15:54 +0000, Andrew Cooper wrote:
> On 20/01/2023 2:59 pm, Oleksii Kurochko wrote:
> > diff --git a/xen/arch/riscv/include/asm/processor.h
> > b/xen/arch/riscv/include/asm/processor.h
> > new file mode 100644
> > index 0000000000..5898a09ce6
> > --- /dev/null
> > +++ b/xen/arch/riscv/include/asm/processor.h
> > @@ -0,0 +1,114 @@
> > +/* SPDX-License-Identifier: MIT */
> > +/*****************************************************************
> > *************
> > + *
> > + * Copyright 2019 (C) Alistair Francis <alistair.francis@wdc.com>
> > + * Copyright 2021 (C) Bobby Eshleman <bobby.eshleman@gmail.com>
> > + * Copyright 2023 (C) Vates
> > + *
> > + */
> > +
> > +#ifndef _ASM_RISCV_PROCESSOR_H
> > +#define _ASM_RISCV_PROCESSOR_H
> > +
> > +#include <asm/types.h>
> > +
> > +#define RISCV_CPU_USER_REGS_zero        0
> > +#define RISCV_CPU_USER_REGS_ra          1
> > +#define RISCV_CPU_USER_REGS_sp          2
> > +#define RISCV_CPU_USER_REGS_gp          3
> > +#define RISCV_CPU_USER_REGS_tp          4
> > +#define RISCV_CPU_USER_REGS_t0          5
> > +#define RISCV_CPU_USER_REGS_t1          6
> > +#define RISCV_CPU_USER_REGS_t2          7
> > +#define RISCV_CPU_USER_REGS_s0          8
> > +#define RISCV_CPU_USER_REGS_s1          9
> > +#define RISCV_CPU_USER_REGS_a0          10
> > +#define RISCV_CPU_USER_REGS_a1          11
> > +#define RISCV_CPU_USER_REGS_a2          12
> > +#define RISCV_CPU_USER_REGS_a3          13
> > +#define RISCV_CPU_USER_REGS_a4          14
> > +#define RISCV_CPU_USER_REGS_a5          15
> > +#define RISCV_CPU_USER_REGS_a6          16
> > +#define RISCV_CPU_USER_REGS_a7          17
> > +#define RISCV_CPU_USER_REGS_s2          18
> > +#define RISCV_CPU_USER_REGS_s3          19
> > +#define RISCV_CPU_USER_REGS_s4          20
> > +#define RISCV_CPU_USER_REGS_s5          21
> > +#define RISCV_CPU_USER_REGS_s6          22
> > +#define RISCV_CPU_USER_REGS_s7          23
> > +#define RISCV_CPU_USER_REGS_s8          24
> > +#define RISCV_CPU_USER_REGS_s9          25
> > +#define RISCV_CPU_USER_REGS_s10         26
> > +#define RISCV_CPU_USER_REGS_s11         27
> > +#define RISCV_CPU_USER_REGS_t3          28
> > +#define RISCV_CPU_USER_REGS_t4          29
> > +#define RISCV_CPU_USER_REGS_t5          30
> > +#define RISCV_CPU_USER_REGS_t6          31
> > +#define RISCV_CPU_USER_REGS_sepc        32
> > +#define RISCV_CPU_USER_REGS_sstatus     33
> > +#define RISCV_CPU_USER_REGS_pregs       34
> > +#define RISCV_CPU_USER_REGS_last        35
> 
> This block wants moving into the asm-offsets infrastructure, but I
> suspect they won't want to survive in this form.
> 
> edit: yeah, definitely not this form.  RISCV_CPU_USER_REGS_OFFSET is
> a
> recipe for bugs.
> 
Thanks for the recommendation I'll take it into account during a work
on new version of the patch series.

> > +
> > +#define RISCV_CPU_USER_REGS_OFFSET(x)   ((RISCV_CPU_USER_REGS_##x)
> > * __SIZEOF_POINTER__)
> > +#define RISCV_CPU_USER_REGS_SIZE       
> > RISCV_CPU_USER_REGS_OFFSET(last)
> > +
> > +#ifndef __ASSEMBLY__
> > +
> > +/* On stack VCPU state */
> > +struct cpu_user_regs
> > +{
> > +    register_t zero;
> 
> unsigned long.
Why is it better to define them as \unsigned long' instead of
register_t?
> 
> > +    register_t ra;
> > +    register_t sp;
> > +    register_t gp;
> > +    register_t tp;
> > +    register_t t0;
> > +    register_t t1;
> > +    register_t t2;
> > +    register_t s0;
> > +    register_t s1;
> > +    register_t a0;
> > +    register_t a1;
> > +    register_t a2;
> > +    register_t a3;
> > +    register_t a4;
> > +    register_t a5;
> > +    register_t a6;
> > +    register_t a7;
> > +    register_t s2;
> > +    register_t s3;
> > +    register_t s4;
> > +    register_t s5;
> > +    register_t s6;
> > +    register_t s7;
> > +    register_t s8;
> > +    register_t s9;
> > +    register_t s10;
> > +    register_t s11;
> > +    register_t t3;
> > +    register_t t4;
> > +    register_t t5;
> > +    register_t t6;
> > +    register_t sepc;
> > +    register_t sstatus;
> > +    /* pointer to previous stack_cpu_regs */
> > +    register_t pregs;
> 
> Stale comment?  Also, surely this wants to be cpu_user_regs *pregs; ?
> 
Not really.
Later it would be introduced another one structure:
	struct pcpu_info {
	...
		struct cpu_user_regs *stack_cpu_regs;
	...
	};
And stack_cpu_regs will be updated during context saving before jump to
__handle_exception:

    	/* new_stack_cpu_regs.pregs = old_stack_cpu_res */
    	REG_L   t0, RISCV_PCPUINFO_OFFSET(stack_cpu_regs)(tp)
    	REG_S   t0, RISCV_CPU_USER_REGS_OFFSET(pregs)(sp)
    	/* Update stack_cpu_regs */
    	REG_S   sp, RISCV_PCPUINFO_OFFSET(stack_cpu_regs)(tp)
And I skipped this part as pcpu_info isn't used anywhere now but
reserve some place for pregs in advance.

> > +};
> > +
> > +static inline void wait_for_interrupt(void)
> 
> There's no point writing out the name in longhand for a wrapper
> around a
> single instruction.
> 
Will change it to "... wfi(void)"
> ~Andrew
Andrew Cooper Jan. 23, 2023, 12:25 p.m. UTC | #4
On 23/01/2023 12:03 pm, Oleksii wrote:
> On Fri, 2023-01-20 at 15:54 +0000, Andrew Cooper wrote:
>> On 20/01/2023 2:59 pm, Oleksii Kurochko wrote:
>>> +
>>> +#define RISCV_CPU_USER_REGS_OFFSET(x)   ((RISCV_CPU_USER_REGS_##x)
>>> * __SIZEOF_POINTER__)
>>> +#define RISCV_CPU_USER_REGS_SIZE       
>>> RISCV_CPU_USER_REGS_OFFSET(last)
>>> +
>>> +#ifndef __ASSEMBLY__
>>> +
>>> +/* On stack VCPU state */
>>> +struct cpu_user_regs
>>> +{
>>> +    register_t zero;
>> unsigned long.
> Why is it better to define them as \unsigned long' instead of
> register_t?

Because there is a material cost to deliberately hiding the type, in
terms of code clarity and legibility.

Things like register_t and vaddr_t are nonsense in a POSIX-y build
environment where these things are spelled "unsigned long", not to
mention that the associated infrastructure is longer than the
non-obfuscated form.

~Andrew
diff mbox series

Patch

diff --git a/xen/arch/riscv/include/asm/processor.h b/xen/arch/riscv/include/asm/processor.h
new file mode 100644
index 0000000000..5898a09ce6
--- /dev/null
+++ b/xen/arch/riscv/include/asm/processor.h
@@ -0,0 +1,114 @@ 
+/* SPDX-License-Identifier: MIT */
+/******************************************************************************
+ *
+ * Copyright 2019 (C) Alistair Francis <alistair.francis@wdc.com>
+ * Copyright 2021 (C) Bobby Eshleman <bobby.eshleman@gmail.com>
+ * Copyright 2023 (C) Vates
+ *
+ */
+
+#ifndef _ASM_RISCV_PROCESSOR_H
+#define _ASM_RISCV_PROCESSOR_H
+
+#include <asm/types.h>
+
+#define RISCV_CPU_USER_REGS_zero        0
+#define RISCV_CPU_USER_REGS_ra          1
+#define RISCV_CPU_USER_REGS_sp          2
+#define RISCV_CPU_USER_REGS_gp          3
+#define RISCV_CPU_USER_REGS_tp          4
+#define RISCV_CPU_USER_REGS_t0          5
+#define RISCV_CPU_USER_REGS_t1          6
+#define RISCV_CPU_USER_REGS_t2          7
+#define RISCV_CPU_USER_REGS_s0          8
+#define RISCV_CPU_USER_REGS_s1          9
+#define RISCV_CPU_USER_REGS_a0          10
+#define RISCV_CPU_USER_REGS_a1          11
+#define RISCV_CPU_USER_REGS_a2          12
+#define RISCV_CPU_USER_REGS_a3          13
+#define RISCV_CPU_USER_REGS_a4          14
+#define RISCV_CPU_USER_REGS_a5          15
+#define RISCV_CPU_USER_REGS_a6          16
+#define RISCV_CPU_USER_REGS_a7          17
+#define RISCV_CPU_USER_REGS_s2          18
+#define RISCV_CPU_USER_REGS_s3          19
+#define RISCV_CPU_USER_REGS_s4          20
+#define RISCV_CPU_USER_REGS_s5          21
+#define RISCV_CPU_USER_REGS_s6          22
+#define RISCV_CPU_USER_REGS_s7          23
+#define RISCV_CPU_USER_REGS_s8          24
+#define RISCV_CPU_USER_REGS_s9          25
+#define RISCV_CPU_USER_REGS_s10         26
+#define RISCV_CPU_USER_REGS_s11         27
+#define RISCV_CPU_USER_REGS_t3          28
+#define RISCV_CPU_USER_REGS_t4          29
+#define RISCV_CPU_USER_REGS_t5          30
+#define RISCV_CPU_USER_REGS_t6          31
+#define RISCV_CPU_USER_REGS_sepc        32
+#define RISCV_CPU_USER_REGS_sstatus     33
+#define RISCV_CPU_USER_REGS_pregs       34
+#define RISCV_CPU_USER_REGS_last        35
+
+#define RISCV_CPU_USER_REGS_OFFSET(x)   ((RISCV_CPU_USER_REGS_##x) * __SIZEOF_POINTER__)
+#define RISCV_CPU_USER_REGS_SIZE        RISCV_CPU_USER_REGS_OFFSET(last)
+
+#ifndef __ASSEMBLY__
+
+/* On stack VCPU state */
+struct cpu_user_regs
+{
+    register_t zero;
+    register_t ra;
+    register_t sp;
+    register_t gp;
+    register_t tp;
+    register_t t0;
+    register_t t1;
+    register_t t2;
+    register_t s0;
+    register_t s1;
+    register_t a0;
+    register_t a1;
+    register_t a2;
+    register_t a3;
+    register_t a4;
+    register_t a5;
+    register_t a6;
+    register_t a7;
+    register_t s2;
+    register_t s3;
+    register_t s4;
+    register_t s5;
+    register_t s6;
+    register_t s7;
+    register_t s8;
+    register_t s9;
+    register_t s10;
+    register_t s11;
+    register_t t3;
+    register_t t4;
+    register_t t5;
+    register_t t6;
+    register_t sepc;
+    register_t sstatus;
+    /* pointer to previous stack_cpu_regs */
+    register_t pregs;
+};
+
+static inline void wait_for_interrupt(void)
+{
+    __asm__ __volatile__ ("wfi");
+}
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_RISCV_PROCESSOR_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */