Re: [PATCH 05/17] xen: Port Xen hypervizor related code from mini-os
Hello Julien, On Wed, 2020-07-01 at 18:46 +0100, Julien Grall wrote: > Title: s/hypervizor/hypervisor/ > > On 01/07/2020 17:29, Anastasiia Lukianenko wrote: > > From: Oleksandr Andrushchenko > > > > Port hypervizor related code from mini-os. Update essential > > Ditto. > > But I would be quite cautious to import code from mini-OS in order > to > support Arm. The port has always been broken and from a look below > needs > to be refined for Arm. > > > arch code to support required bit operations, memory barriers etc. > > > > Copyright for the bits ported belong to at least the following > > authors, > > please see related files for details: > > > > Copyright (c) 2002-2003, K A Fraser > > Copyright (c) 2005, Grzegorz Milos, gm...@cam.ac.uk,Intel Research > > Cambridge > > Copyright (c) 2014, Karim Allah Ahmed > > > > Signed-off-by: Oleksandr Andrushchenko < > > oleksandr_andrushche...@epam.com> > > Signed-off-by: Anastasiia Lukianenko < > > anastasiia_lukiane...@epam.com> > > --- > > arch/arm/include/asm/xen/system.h | 96 +++ > > common/board_r.c | 11 ++ > > drivers/Makefile | 1 + > > drivers/xen/Makefile | 5 + > > drivers/xen/hypervisor.c | 277 > > ++ > > include/xen.h | 11 ++ > > include/xen/hvm.h | 30 > > 7 files changed, 431 insertions(+) > > create mode 100644 arch/arm/include/asm/xen/system.h > > create mode 100644 drivers/xen/Makefile > > create mode 100644 drivers/xen/hypervisor.c > > create mode 100644 include/xen.h > > create mode 100644 include/xen/hvm.h > > > > diff --git a/arch/arm/include/asm/xen/system.h > > b/arch/arm/include/asm/xen/system.h > > new file mode 100644 > > index 00..81ab90160e > > --- /dev/null > > +++ b/arch/arm/include/asm/xen/system.h > > @@ -0,0 +1,96 @@ > > +/* > > + * SPDX-License-Identifier: GPL-2.0 > > + * > > + * (C) 2014 Karim Allah Ahmed > > + * (C) 2020, EPAM Systems Inc. > > + */ > > +#ifndef _ASM_ARM_XEN_SYSTEM_H > > +#define _ASM_ARM_XEN_SYSTEM_H > > + > > +#include > > +#include > > + > > +/* If *ptr == old, then store new there (and return new). > > + * Otherwise, return the old value. > > + * Atomic. > > + */ > > +#define synch_cmpxchg(ptr, old, new) \ > > +({ __typeof__(*ptr) stored = old; \ > > + __atomic_compare_exchange_n(ptr, &stored, new, 0, > > __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) ? new : old; \ > > +}) > > + > > +/* As test_and_clear_bit, but using __ATOMIC_SEQ_CST */ > > +static inline int synch_test_and_clear_bit(int nr, volatile void > > *addr) > > +{ > > + u8 *byte = ((u8 *)addr) + (nr >> 3); > > + u8 bit = 1 << (nr & 7); > > + u8 orig; > > + > > + orig = __atomic_fetch_and(byte, ~bit, __ATOMIC_SEQ_CST); > > + > > + return (orig & bit) != 0; > > +} > > + > > +/* As test_and_set_bit, but using __ATOMIC_SEQ_CST */ > > +static inline int synch_test_and_set_bit(int nr, volatile void > > *base) > > +{ > > + u8 *byte = ((u8 *)base) + (nr >> 3); > > + u8 bit = 1 << (nr & 7); > > + u8 orig; > > + > > + orig = __atomic_fetch_or(byte, bit, __ATOMIC_SEQ_CST); > > + > > + return (orig & bit) != 0; > > +} > > + > > +/* As set_bit, but using __ATOMIC_SEQ_CST */ > > +static inline void synch_set_bit(int nr, volatile void *addr) > > +{ > > + synch_test_and_set_bit(nr, addr); > > +} > > + > > +/* As clear_bit, but using __ATOMIC_SEQ_CST */ > > +static inline void synch_clear_bit(int nr, volatile void *addr) > > +{ > > + synch_test_and_clear_bit(nr, addr); > > +} > > + > > +/* As test_bit, but with a following memory barrier. */ > > +//static inline int synch_test_bit(int nr, volatile void *addr) > > +static inline int synch_test_bit(int nr, const void *addr) > > +{ > > + int result; > > + > > + result = test_bit(nr, addr); > > + barrier(); > > + return result; > > +} > > I can understand why we implement sync_* helpers as AFAICT the > generic > helpers are not SMP safe. However... > > > + > > +#define xchg(ptr, v) __atomic_exchange_n(ptr, v, > > __ATOMIC_SEQ_CST) > > +#define xchg(ptr, v) __atomic_exchange_n(ptr, v, > > __ATOMIC_SEQ_CST) > > + > > +#define mb() dsb() > > +#define rmb() dsb() > > +#define wmb() dsb() > > +#define __iormb() dmb() > > +#define __iowmb() dmb() > > Why do you need to re-implement the barriers? > > > +#define xen_mb() mb() > > +#define xen_rmb() rmb() > > +#define xen_wmb() wmb() > > + > > +#define smp_processor_id() 0 > > Shouldn't this be common? > > > + > > +#define to_phys(x) ((unsigned long)(x)) > > +#define to_virt(x) ((void *)(x)) > > + > > +#define PFN_UP(x) (unsigned long)(((x) + PAGE_SIZE - 1) > > >> PAGE_SHIFT) > > +#define PFN_DOWN(x)(unsigned long)((x) >> > > PAGE_SHIFT) > > +#define PFN_PHYS(x)((unsigned long)(x) << > > PAGE_SHIFT) > > +#define PHYS_PFN(x)(unsigned lon
Re: [PATCH 05/17] xen: Port Xen hypervizor related code from mini-os
Hi, On Fri, 2020-07-03 at 14:38 +0100, Julien Grall wrote: > Hi, > > On 03/07/2020 13:21, Anastasiia Lukianenko wrote: > > Hi Julien, > > > > On Wed, 2020-07-01 at 18:46 +0100, Julien Grall wrote: > > > Title: s/hypervizor/hypervisor/ > > > > Thank you for pointing :) I will fix it in the next version. > > > > > > > > On 01/07/2020 17:29, Anastasiia Lukianenko wrote: > > > > From: Oleksandr Andrushchenko > > > > > > > > > > > > Port hypervizor related code from mini-os. Update essential > > > > > > Ditto. > > > > > > But I would be quite cautious to import code from mini-OS in > > > order > > > to > > > support Arm. The port has always been broken and from a look > > > below > > > needs > > > to be refined for Arm. > > > > We were referencing the code of Mini-OS from [1] by Huang Shijie > > and > > Volodymyr Babchuk which is for ARM64, so we hope this part should > > be > > ok. > > > > [1] > > https://urldefense.com/v3/__https://github.com/zyzii/mini-os.git__;!!GF_29dbcQIUBPA!i0hVwJuV0iEI89D83SJP8zr1mgHfh5o3IS2vytGwgxyJ0kzSiCLqVdtA3crvFm0GUMTNGQU$ > > > > Well, that's not part of the official port. It would have been nice > to > at least mention that in somewhere in the series. > Sure, will mention. > > > > + return result; > > > > +} > > > > > > I can understand why we implement sync_* helpers as AFAICT the > > > generic > > > helpers are not SMP safe. However... > > > > > > > + > > > > +#define xchg(ptr, v) __atomic_exchange_n(ptr, v, > > > > __ATOMIC_SEQ_CST) > > > > +#define xchg(ptr, v) __atomic_exchange_n(ptr, v, > > > > __ATOMIC_SEQ_CST) > > > > + > > > > +#define mb() dsb() > > > > +#define rmb() dsb() > > > > +#define wmb() dsb() > > > > +#define __iormb() dmb() > > > > +#define __iowmb() dmb() > > > > > > Why do you need to re-implement the barriers? > > > > Indeed, we do not need to do this. > > I will fix it in the next version. > > > > > > > > > +#define xen_mb() mb() > > > > +#define xen_rmb() rmb() > > > > +#define xen_wmb() wmb() > > > > + > > > > +#define smp_processor_id() 0 > > > > > > Shouldn't this be common? > > > > Currently it is only used by Xen and we are not sure if > > any other entity will use it, but we can put that into > > arch/arm/include/asm/io.h > > I looked at the usage in Xen and don't really think it would help in > any > way to get the code SMP ready. Does U-boot will enable Xen features > on > secondary CPUs? If not, then I would recomment to just drop it. > Ok, will drop > [...] > > > > > > > > + > > > > +#endif > > > > diff --git a/common/board_r.c b/common/board_r.c > > > > index fa57fa9b69..fd36edb4e5 100644 > > > > --- a/common/board_r.c > > > > +++ b/common/board_r.c > > > > @@ -56,6 +56,7 @@ > > > >#include > > > >#include > > > >#include > > > > +#include > > > > > > Do we want to include it for other boards? > > > > For now, we do not have a plan and resources to support > > anything other than what we need. Therefore only ARM64. > > I think you misunderstood my comment here. The file seems to be > common > but you include xen.h unconditionnally. Is it really what you want to > do? > > > > > +/* > > > > + * Shared page for communicating with the hypervisor. > > > > + * Events flags go here, for example. > > > > + */ > > > > +struct shared_info *HYPERVISOR_shared_info; > > > > + > > > > +#ifndef CONFIG_PARAVIRT > > > > > > Is there any plan to support this on x86? > > > > For now, we do not have a plan and resources to support > > anything other > > than what we need. Therefore only ARM64. > > Ok. I doubt that one will want to use U-boot on PV x86. So I would > recommend to drop anything related to CONFIG_PARAVIRT. > Ok, will remove > > > > +{ > > > > + struct xen_hvm_param xhv; > > > > + int ret; > > > > > > I don't think there is a guarantee that your cache is going to be > > > clean > > > when writing xhv. So you likely want to add a > > > invalidate_dcache_range() > > > before writing it. > > > > Thank you for advice. > > Ah, so we need something like: > > > > ... > > invalidate_dcache_range((unsigned long)&xhv, > > (unsigned long)&xhv + sizeof(xhv)); > > xhv.domid = DOMID_SELF; > > xhv.index = idx; > > invalidate_dcache_range((unsigned long)&xhv, > > (unsigned long)&xhv + sizeof(xhv)); > > ... > > Right, this would indeed be safer. > > [...] > > > > > +void do_hypervisor_callback(struct pt_regs *regs) > > > > +{ > > > > + unsigned long l1, l2, l1i, l2i; > > > > + unsigned int port; > > > > + int cpu = 0; > > > > + struct shared_info *s = HYPERVISOR_shared_info; > > > > + struct vcpu_info *vcpu_info = &s->vcpu_info[cpu]; > > > > + > > > > + in_callback = 1; > > > > + > > > > + vcpu_info->evtchn_upcall_pending = 0; > > > > + /* NB x86. No need for a barrier here -- XCHG is a > > > > barrier on > > > > x86. */ > > > > +#if
Re: [PATCH 05/17] xen: Port Xen hypervizor related code from mini-os
Hi, On 03/07/2020 13:21, Anastasiia Lukianenko wrote: Hi Julien, On Wed, 2020-07-01 at 18:46 +0100, Julien Grall wrote: Title: s/hypervizor/hypervisor/ Thank you for pointing :) I will fix it in the next version. On 01/07/2020 17:29, Anastasiia Lukianenko wrote: From: Oleksandr Andrushchenko Port hypervizor related code from mini-os. Update essential Ditto. But I would be quite cautious to import code from mini-OS in order to support Arm. The port has always been broken and from a look below needs to be refined for Arm. We were referencing the code of Mini-OS from [1] by Huang Shijie and Volodymyr Babchuk which is for ARM64, so we hope this part should be ok. [1] https://github.com/zyzii/mini-os.git Well, that's not part of the official port. It would have been nice to at least mention that in somewhere in the series. + return result; +} I can understand why we implement sync_* helpers as AFAICT the generic helpers are not SMP safe. However... + +#define xchg(ptr, v) __atomic_exchange_n(ptr, v, __ATOMIC_SEQ_CST) +#define xchg(ptr, v) __atomic_exchange_n(ptr, v, __ATOMIC_SEQ_CST) + +#define mb() dsb() +#define rmb() dsb() +#define wmb() dsb() +#define __iormb() dmb() +#define __iowmb() dmb() Why do you need to re-implement the barriers? Indeed, we do not need to do this. I will fix it in the next version. +#define xen_mb() mb() +#define xen_rmb() rmb() +#define xen_wmb() wmb() + +#define smp_processor_id() 0 Shouldn't this be common? Currently it is only used by Xen and we are not sure if any other entity will use it, but we can put that into arch/arm/include/asm/io.h I looked at the usage in Xen and don't really think it would help in any way to get the code SMP ready. Does U-boot will enable Xen features on secondary CPUs? If not, then I would recomment to just drop it. [...] + +#endif diff --git a/common/board_r.c b/common/board_r.c index fa57fa9b69..fd36edb4e5 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -56,6 +56,7 @@ #include #include #include +#include Do we want to include it for other boards? For now, we do not have a plan and resources to support anything other than what we need. Therefore only ARM64. I think you misunderstood my comment here. The file seems to be common but you include xen.h unconditionnally. Is it really what you want to do? +/* + * Shared page for communicating with the hypervisor. + * Events flags go here, for example. + */ +struct shared_info *HYPERVISOR_shared_info; + +#ifndef CONFIG_PARAVIRT Is there any plan to support this on x86? For now, we do not have a plan and resources to support anything other than what we need. Therefore only ARM64. Ok. I doubt that one will want to use U-boot on PV x86. So I would recommend to drop anything related to CONFIG_PARAVIRT. +{ + struct xen_hvm_param xhv; + int ret; I don't think there is a guarantee that your cache is going to be clean when writing xhv. So you likely want to add a invalidate_dcache_range() before writing it. Thank you for advice. Ah, so we need something like: ... invalidate_dcache_range((unsigned long)&xhv, (unsigned long)&xhv + sizeof(xhv)); xhv.domid = DOMID_SELF; xhv.index = idx; invalidate_dcache_range((unsigned long)&xhv, (unsigned long)&xhv + sizeof(xhv)); ... Right, this would indeed be safer. [...] +void do_hypervisor_callback(struct pt_regs *regs) +{ + unsigned long l1, l2, l1i, l2i; + unsigned int port; + int cpu = 0; + struct shared_info *s = HYPERVISOR_shared_info; + struct vcpu_info *vcpu_info = &s->vcpu_info[cpu]; + + in_callback = 1; + + vcpu_info->evtchn_upcall_pending = 0; + /* NB x86. No need for a barrier here -- XCHG is a barrier on x86. */ +#if !defined(__i386__) && !defined(__x86_64__) + /* Clear master flag /before/ clearing selector flag. */ + wmb(); +#endif + l1 = xchg(&vcpu_info->evtchn_pending_sel, 0); + + while (l1 != 0) { + l1i = __ffs(l1); + l1 &= ~(1UL << l1i); + + while ((l2 = active_evtchns(cpu, s, l1i)) != 0) { + l2i = __ffs(l2); + l2 &= ~(1UL << l2i); + + port = (l1i * (sizeof(unsigned long) * 8)) + l2i; + /* TODO: handle new event: do_event(port, regs); */ + /* Suppress -Wunused-but-set-variable */ + (void)(port); + } + } You likely want a memory barrier here as otherwise in_callback could be written/seen before the loop end. We are not running in a multi-threaded environment, so probably in_callback should be fine as is? It really depends on how you plan to use in_callback. If you want to use it in interrupt context to know whether you are dealing with a callback, then you will want a
Re: [PATCH 05/17] xen: Port Xen hypervizor related code from mini-os
Hi Julien, On Wed, 2020-07-01 at 18:46 +0100, Julien Grall wrote: > Title: s/hypervizor/hypervisor/ Thank you for pointing :) I will fix it in the next version. > > On 01/07/2020 17:29, Anastasiia Lukianenko wrote: > > From: Oleksandr Andrushchenko > > > > Port hypervizor related code from mini-os. Update essential > > Ditto. > > But I would be quite cautious to import code from mini-OS in order > to > support Arm. The port has always been broken and from a look below > needs > to be refined for Arm. We were referencing the code of Mini-OS from [1] by Huang Shijie and Volodymyr Babchuk which is for ARM64, so we hope this part should be ok. [1] https://github.com/zyzii/mini-os.git > > > arch code to support required bit operations, memory barriers etc. > > > > Copyright for the bits ported belong to at least the following > > authors, > > please see related files for details: > > > > Copyright (c) 2002-2003, K A Fraser > > Copyright (c) 2005, Grzegorz Milos, gm...@cam.ac.uk,Intel Research > > Cambridge > > Copyright (c) 2014, Karim Allah Ahmed > > > > Signed-off-by: Oleksandr Andrushchenko < > > oleksandr_andrushche...@epam.com> > > Signed-off-by: Anastasiia Lukianenko < > > anastasiia_lukiane...@epam.com> > > --- > > arch/arm/include/asm/xen/system.h | 96 +++ > > common/board_r.c | 11 ++ > > drivers/Makefile | 1 + > > drivers/xen/Makefile | 5 + > > drivers/xen/hypervisor.c | 277 > > ++ > > include/xen.h | 11 ++ > > include/xen/hvm.h | 30 > > 7 files changed, 431 insertions(+) > > create mode 100644 arch/arm/include/asm/xen/system.h > > create mode 100644 drivers/xen/Makefile > > create mode 100644 drivers/xen/hypervisor.c > > create mode 100644 include/xen.h > > create mode 100644 include/xen/hvm.h > > > > diff --git a/arch/arm/include/asm/xen/system.h > > b/arch/arm/include/asm/xen/system.h > > new file mode 100644 > > index 00..81ab90160e > > --- /dev/null > > +++ b/arch/arm/include/asm/xen/system.h > > @@ -0,0 +1,96 @@ > > +/* > > + * SPDX-License-Identifier: GPL-2.0 > > + * > > + * (C) 2014 Karim Allah Ahmed > > + * (C) 2020, EPAM Systems Inc. > > + */ > > +#ifndef _ASM_ARM_XEN_SYSTEM_H > > +#define _ASM_ARM_XEN_SYSTEM_H > > + > > +#include > > +#include > > + > > +/* If *ptr == old, then store new there (and return new). > > + * Otherwise, return the old value. > > + * Atomic. > > + */ > > +#define synch_cmpxchg(ptr, old, new) \ > > +({ __typeof__(*ptr) stored = old; \ > > + __atomic_compare_exchange_n(ptr, &stored, new, 0, > > __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) ? new : old; \ > > +}) > > + > > +/* As test_and_clear_bit, but using __ATOMIC_SEQ_CST */ > > +static inline int synch_test_and_clear_bit(int nr, volatile void > > *addr) > > +{ > > + u8 *byte = ((u8 *)addr) + (nr >> 3); > > + u8 bit = 1 << (nr & 7); > > + u8 orig; > > + > > + orig = __atomic_fetch_and(byte, ~bit, __ATOMIC_SEQ_CST); > > + > > + return (orig & bit) != 0; > > +} > > + > > +/* As test_and_set_bit, but using __ATOMIC_SEQ_CST */ > > +static inline int synch_test_and_set_bit(int nr, volatile void > > *base) > > +{ > > + u8 *byte = ((u8 *)base) + (nr >> 3); > > + u8 bit = 1 << (nr & 7); > > + u8 orig; > > + > > + orig = __atomic_fetch_or(byte, bit, __ATOMIC_SEQ_CST); > > + > > + return (orig & bit) != 0; > > +} > > + > > +/* As set_bit, but using __ATOMIC_SEQ_CST */ > > +static inline void synch_set_bit(int nr, volatile void *addr) > > +{ > > + synch_test_and_set_bit(nr, addr); > > +} > > + > > +/* As clear_bit, but using __ATOMIC_SEQ_CST */ > > +static inline void synch_clear_bit(int nr, volatile void *addr) > > +{ > > + synch_test_and_clear_bit(nr, addr); > > +} > > + > > +/* As test_bit, but with a following memory barrier. */ > > +//static inline int synch_test_bit(int nr, volatile void *addr) > > +static inline int synch_test_bit(int nr, const void *addr) > > +{ > > + int result; > > + > > + result = test_bit(nr, addr); > > + barrier(); > > + return result; > > +} > > I can understand why we implement sync_* helpers as AFAICT the > generic > helpers are not SMP safe. However... > > > + > > +#define xchg(ptr, v) __atomic_exchange_n(ptr, v, > > __ATOMIC_SEQ_CST) > > +#define xchg(ptr, v) __atomic_exchange_n(ptr, v, > > __ATOMIC_SEQ_CST) > > + > > +#define mb() dsb() > > +#define rmb() dsb() > > +#define wmb() dsb() > > +#define __iormb() dmb() > > +#define __iowmb() dmb() > > Why do you need to re-implement the barriers? Indeed, we do not need to do this. I will fix it in the next version. > > > +#define xen_mb() mb() > > +#define xen_rmb() rmb() > > +#define xen_wmb() wmb() > > + > > +#define smp_processor_id() 0 > > Shouldn't this be common? Currently it is only used by Xen and we are not sure if any other entity will use it, but we ca
Re: [PATCH 05/17] xen: Port Xen hypervizor related code from mini-os
Title: s/hypervizor/hypervisor/ On 01/07/2020 17:29, Anastasiia Lukianenko wrote: From: Oleksandr Andrushchenko Port hypervizor related code from mini-os. Update essential Ditto. But I would be quite cautious to import code from mini-OS in order to support Arm. The port has always been broken and from a look below needs to be refined for Arm. arch code to support required bit operations, memory barriers etc. Copyright for the bits ported belong to at least the following authors, please see related files for details: Copyright (c) 2002-2003, K A Fraser Copyright (c) 2005, Grzegorz Milos, gm...@cam.ac.uk,Intel Research Cambridge Copyright (c) 2014, Karim Allah Ahmed Signed-off-by: Oleksandr Andrushchenko Signed-off-by: Anastasiia Lukianenko --- arch/arm/include/asm/xen/system.h | 96 +++ common/board_r.c | 11 ++ drivers/Makefile | 1 + drivers/xen/Makefile | 5 + drivers/xen/hypervisor.c | 277 ++ include/xen.h | 11 ++ include/xen/hvm.h | 30 7 files changed, 431 insertions(+) create mode 100644 arch/arm/include/asm/xen/system.h create mode 100644 drivers/xen/Makefile create mode 100644 drivers/xen/hypervisor.c create mode 100644 include/xen.h create mode 100644 include/xen/hvm.h diff --git a/arch/arm/include/asm/xen/system.h b/arch/arm/include/asm/xen/system.h new file mode 100644 index 00..81ab90160e --- /dev/null +++ b/arch/arm/include/asm/xen/system.h @@ -0,0 +1,96 @@ +/* + * SPDX-License-Identifier: GPL-2.0 + * + * (C) 2014 Karim Allah Ahmed + * (C) 2020, EPAM Systems Inc. + */ +#ifndef _ASM_ARM_XEN_SYSTEM_H +#define _ASM_ARM_XEN_SYSTEM_H + +#include +#include + +/* If *ptr == old, then store new there (and return new). + * Otherwise, return the old value. + * Atomic. + */ +#define synch_cmpxchg(ptr, old, new) \ +({ __typeof__(*ptr) stored = old; \ + __atomic_compare_exchange_n(ptr, &stored, new, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) ? new : old; \ +}) + +/* As test_and_clear_bit, but using __ATOMIC_SEQ_CST */ +static inline int synch_test_and_clear_bit(int nr, volatile void *addr) +{ + u8 *byte = ((u8 *)addr) + (nr >> 3); + u8 bit = 1 << (nr & 7); + u8 orig; + + orig = __atomic_fetch_and(byte, ~bit, __ATOMIC_SEQ_CST); + + return (orig & bit) != 0; +} + +/* As test_and_set_bit, but using __ATOMIC_SEQ_CST */ +static inline int synch_test_and_set_bit(int nr, volatile void *base) +{ + u8 *byte = ((u8 *)base) + (nr >> 3); + u8 bit = 1 << (nr & 7); + u8 orig; + + orig = __atomic_fetch_or(byte, bit, __ATOMIC_SEQ_CST); + + return (orig & bit) != 0; +} + +/* As set_bit, but using __ATOMIC_SEQ_CST */ +static inline void synch_set_bit(int nr, volatile void *addr) +{ + synch_test_and_set_bit(nr, addr); +} + +/* As clear_bit, but using __ATOMIC_SEQ_CST */ +static inline void synch_clear_bit(int nr, volatile void *addr) +{ + synch_test_and_clear_bit(nr, addr); +} + +/* As test_bit, but with a following memory barrier. */ +//static inline int synch_test_bit(int nr, volatile void *addr) +static inline int synch_test_bit(int nr, const void *addr) +{ + int result; + + result = test_bit(nr, addr); + barrier(); + return result; +} I can understand why we implement sync_* helpers as AFAICT the generic helpers are not SMP safe. However... + +#define xchg(ptr, v) __atomic_exchange_n(ptr, v, __ATOMIC_SEQ_CST) +#define xchg(ptr, v) __atomic_exchange_n(ptr, v, __ATOMIC_SEQ_CST) + +#define mb() dsb() +#define rmb() dsb() +#define wmb() dsb() +#define __iormb() dmb() +#define __iowmb() dmb() Why do you need to re-implement the barriers? +#define xen_mb() mb() +#define xen_rmb() rmb() +#define xen_wmb() wmb() + +#define smp_processor_id() 0 Shouldn't this be common? + +#define to_phys(x) ((unsigned long)(x)) +#define to_virt(x) ((void *)(x)) + +#define PFN_UP(x) (unsigned long)(((x) + PAGE_SIZE - 1) >> PAGE_SHIFT) +#define PFN_DOWN(x)(unsigned long)((x) >> PAGE_SHIFT) +#define PFN_PHYS(x)((unsigned long)(x) << PAGE_SHIFT) +#define PHYS_PFN(x)(unsigned long)((x) >> PAGE_SHIFT) + +#define virt_to_pfn(_virt) (PFN_DOWN(to_phys(_virt))) +#define virt_to_mfn(_virt) (PFN_DOWN(to_phys(_virt))) +#define mfn_to_virt(_mfn) (to_virt(PFN_PHYS(_mfn))) +#define pfn_to_virt(_pfn) (to_virt(PFN_PHYS(_pfn))) There is already generic phys <-> virt helpers (see include/asm-generic/io.h). So why do you need to create a new version? + +#endif diff --git a/common/board_r.c b/common/board_r.c index fa57fa9b69..fd36edb4e5 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -56,6 +56,7 @@ #include #include #include +#include Do we want to include it for other boards? #ifdef C
[PATCH 05/17] xen: Port Xen hypervizor related code from mini-os
From: Oleksandr Andrushchenko Port hypervizor related code from mini-os. Update essential arch code to support required bit operations, memory barriers etc. Copyright for the bits ported belong to at least the following authors, please see related files for details: Copyright (c) 2002-2003, K A Fraser Copyright (c) 2005, Grzegorz Milos, gm...@cam.ac.uk,Intel Research Cambridge Copyright (c) 2014, Karim Allah Ahmed Signed-off-by: Oleksandr Andrushchenko Signed-off-by: Anastasiia Lukianenko --- arch/arm/include/asm/xen/system.h | 96 +++ common/board_r.c | 11 ++ drivers/Makefile | 1 + drivers/xen/Makefile | 5 + drivers/xen/hypervisor.c | 277 ++ include/xen.h | 11 ++ include/xen/hvm.h | 30 7 files changed, 431 insertions(+) create mode 100644 arch/arm/include/asm/xen/system.h create mode 100644 drivers/xen/Makefile create mode 100644 drivers/xen/hypervisor.c create mode 100644 include/xen.h create mode 100644 include/xen/hvm.h diff --git a/arch/arm/include/asm/xen/system.h b/arch/arm/include/asm/xen/system.h new file mode 100644 index 00..81ab90160e --- /dev/null +++ b/arch/arm/include/asm/xen/system.h @@ -0,0 +1,96 @@ +/* + * SPDX-License-Identifier: GPL-2.0 + * + * (C) 2014 Karim Allah Ahmed + * (C) 2020, EPAM Systems Inc. + */ +#ifndef _ASM_ARM_XEN_SYSTEM_H +#define _ASM_ARM_XEN_SYSTEM_H + +#include +#include + +/* If *ptr == old, then store new there (and return new). + * Otherwise, return the old value. + * Atomic. + */ +#define synch_cmpxchg(ptr, old, new) \ +({ __typeof__(*ptr) stored = old; \ + __atomic_compare_exchange_n(ptr, &stored, new, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) ? new : old; \ +}) + +/* As test_and_clear_bit, but using __ATOMIC_SEQ_CST */ +static inline int synch_test_and_clear_bit(int nr, volatile void *addr) +{ + u8 *byte = ((u8 *)addr) + (nr >> 3); + u8 bit = 1 << (nr & 7); + u8 orig; + + orig = __atomic_fetch_and(byte, ~bit, __ATOMIC_SEQ_CST); + + return (orig & bit) != 0; +} + +/* As test_and_set_bit, but using __ATOMIC_SEQ_CST */ +static inline int synch_test_and_set_bit(int nr, volatile void *base) +{ + u8 *byte = ((u8 *)base) + (nr >> 3); + u8 bit = 1 << (nr & 7); + u8 orig; + + orig = __atomic_fetch_or(byte, bit, __ATOMIC_SEQ_CST); + + return (orig & bit) != 0; +} + +/* As set_bit, but using __ATOMIC_SEQ_CST */ +static inline void synch_set_bit(int nr, volatile void *addr) +{ + synch_test_and_set_bit(nr, addr); +} + +/* As clear_bit, but using __ATOMIC_SEQ_CST */ +static inline void synch_clear_bit(int nr, volatile void *addr) +{ + synch_test_and_clear_bit(nr, addr); +} + +/* As test_bit, but with a following memory barrier. */ +//static inline int synch_test_bit(int nr, volatile void *addr) +static inline int synch_test_bit(int nr, const void *addr) +{ + int result; + + result = test_bit(nr, addr); + barrier(); + return result; +} + +#define xchg(ptr, v) __atomic_exchange_n(ptr, v, __ATOMIC_SEQ_CST) +#define xchg(ptr, v) __atomic_exchange_n(ptr, v, __ATOMIC_SEQ_CST) + +#define mb() dsb() +#define rmb() dsb() +#define wmb() dsb() +#define __iormb() dmb() +#define __iowmb() dmb() +#define xen_mb() mb() +#define xen_rmb() rmb() +#define xen_wmb() wmb() + +#define smp_processor_id() 0 + +#define to_phys(x) ((unsigned long)(x)) +#define to_virt(x) ((void *)(x)) + +#define PFN_UP(x) (unsigned long)(((x) + PAGE_SIZE - 1) >> PAGE_SHIFT) +#define PFN_DOWN(x)(unsigned long)((x) >> PAGE_SHIFT) +#define PFN_PHYS(x)((unsigned long)(x) << PAGE_SHIFT) +#define PHYS_PFN(x)(unsigned long)((x) >> PAGE_SHIFT) + +#define virt_to_pfn(_virt) (PFN_DOWN(to_phys(_virt))) +#define virt_to_mfn(_virt) (PFN_DOWN(to_phys(_virt))) +#define mfn_to_virt(_mfn) (to_virt(PFN_PHYS(_mfn))) +#define pfn_to_virt(_pfn) (to_virt(PFN_PHYS(_pfn))) + +#endif diff --git a/common/board_r.c b/common/board_r.c index fa57fa9b69..fd36edb4e5 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -56,6 +56,7 @@ #include #include #include +#include #ifdef CONFIG_ADDR_MAP #include #endif @@ -462,6 +463,13 @@ static int initr_mmc(void) } #endif +#ifdef CONFIG_XEN +static int initr_xen(void) +{ + xen_init(); + return 0; +} +#endif /* * Tell if it's OK to load the environment early in boot. * @@ -769,6 +777,9 @@ static init_fnc_t init_sequence_r[] = { #endif #ifdef CONFIG_MMC initr_mmc, +#endif +#ifdef CONFIG_XEN + initr_xen, #endif initr_env, #ifdef CONFIG_SYS_BOOTPARAMS_LEN diff --git a/drivers/Makefile b/drivers/Makefile index 94e8c5da17..0dd8891e76 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_$(SPL_)REMOTEPRO