Message ID | 1503347275-13039-7-git-send-email-volodymyr_babchuk@epam.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Hi Volodymyr, On 21/08/17 21:27, Volodymyr Babchuk wrote: > SMCCC (SMC Call Convention) describes how to handle both HVCs and SMCs. > SMCCC states that both HVC and SMC are valid conduits to call to different > firmware functions. Thus, for example, PSCI calls can be made both by > SMC or HVC. Also SMCCC defines function number coding for such calls. > Besides functional calls there are query calls, which allows underling > OS determine version, UUID and number of functions provided by service > provider. > > This patch adds new file `vsmc.c`, which handles both generic SMCs > and HVC according to SMCCC. At this moment it implements only one > service: Standard Hypervisor Service. > > At this time Standard Hypervisor Service only supports query calls, > so caller can ask about hypervisor UID and determine that it is XEN running. > > This change allows more generic handling for SMCs and HVCs and it can > be easily extended to support new services and functions. > > But, before SMC is forwarded to standard SMCCC handler, it can be routed > to a domain monitor, if one is installed. > > Signed-off-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com> > Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com> > Reviewed-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com> > --- > > * Reworked UUID handling (due to new UUID type definition) > * Renamed vsmc_handle_call() to vsmccc_handle_call() to emphasis > that it handles both SMC and HVC > * Added comment for inject_undef_exception() usage > * Used HSR_XXC_IMM_MASK insted of 0xFF > * Added full stops to comments > > --- > > xen/arch/arm/Makefile | 1 + > xen/arch/arm/traps.c | 18 +---- > xen/arch/arm/vsmc.c | 160 ++++++++++++++++++++++++++++++++++++++ > xen/include/asm-arm/vsmc.h | 30 +++++++ > xen/include/public/arch-arm/smc.h | 58 ++++++++++++++ > 5 files changed, 250 insertions(+), 17 deletions(-) > create mode 100644 xen/arch/arm/vsmc.c > create mode 100644 xen/include/asm-arm/vsmc.h > create mode 100644 xen/include/public/arch-arm/smc.h > > diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile > index de00c5e..3d7dde9 100644 > --- a/xen/arch/arm/Makefile > +++ b/xen/arch/arm/Makefile > @@ -51,6 +51,7 @@ obj-$(CONFIG_HAS_GICV3) += vgic-v3.o > obj-$(CONFIG_HAS_ITS) += vgic-v3-its.o > obj-y += vm_event.o > obj-y += vtimer.o > +obj-y += vsmc.o > obj-y += vpsci.o > obj-y += vuart.o > > diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c > index 82cd2b1..4141a89 100644 > --- a/xen/arch/arm/traps.c > +++ b/xen/arch/arm/traps.c > @@ -50,6 +50,7 @@ > #include <asm/regs.h> > #include <asm/traps.h> > #include <asm/vgic.h> > +#include <asm/vsmc.h> > #include <asm/vtimer.h> > > #include "decode.h" > @@ -2155,23 +2156,6 @@ static void do_trap_data_abort_guest(struct cpu_user_regs *regs, > inject_dabt_exception(regs, info.gva, hsr.len); > } > > -static void do_trap_smc(struct cpu_user_regs *regs, const union hsr hsr) > -{ > - int rc = 0; > - > - if ( !check_conditional_instr(regs, hsr) ) > - { > - advance_pc(regs, hsr); > - return; > - } > - > - if ( current->domain->arch.monitor.privileged_call_enabled ) > - rc = monitor_smc(); > - > - if ( rc != 1 ) > - inject_undef_exception(regs, hsr); > -} > - In general we try to avoid code movement in the same patch as new code. I am ok with that one, but please avoid this in the future. > static void enter_hypervisor_head(struct cpu_user_regs *regs) > { > if ( guest_mode(regs) ) > diff --git a/xen/arch/arm/vsmc.c b/xen/arch/arm/vsmc.c > new file mode 100644 > index 0000000..0a81294 > --- /dev/null > +++ b/xen/arch/arm/vsmc.c > @@ -0,0 +1,160 @@ > +/* > + * xen/arch/arm/vsmc.c > + * > + * Generic handler for SMC and HVC calls according to > + * ARM SMC calling convention > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 as > + * published by the Free Software Foundation. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + */ > + > + > +#include <xen/lib.h> > +#include <xen/types.h> > +#include <public/arch-arm/smc.h> > +#include <asm/monitor.h> > +#include <asm/regs.h> > +#include <asm/smccc.h> > +#include <asm/traps.h> > +#include <asm/vsmc.h> > + > +/* Number of functions currently supported by Hypervisor Service. */ > +#define XEN_SMCCC_FUNCTION_COUNT 3 > + > +static void fill_uuid(struct cpu_user_regs *regs, const xen_uuid_t u) > +{ > +#define FILL_UUID(n) \ > + set_user_reg(regs, n, (register_t) u[n * 4 + 0] << 24 | \ > + u[n * 4 + 1] << 16 | \ > + u[n * 4 + 2] << 8 | \ > + u[n * 4 + 3] << 0 ) This does not seem to match the spec: "Bytes 0...3 with byte 0 in the low-order bits". Which I understand as byte 0 should be in [0...7], byte 1 [8..15]... > + > + FILL_UUID(0); > + FILL_UUID(1); > + FILL_UUID(2); > + FILL_UUID(3); > +#undef FILL_UUID This function is really hard to parse and I don't think the macro is worth it. I would do something like: for (i = 0; i < 4) { uint8_t *bytes = &u[n * 4]; uint32_t r; r = bytes[0]; r |= bytes[1] << 8; r |= bytes[2] << 16; r |= bytes[3] << 24; set_user_reg(...); } Plus some comment on top explaining the layout. Yes, it takes more line, but at least it is easier to read it. > +} > + > +/* SMCCC interface for hypervisor. Tell about itself. */ > +static bool handle_hypervisor(struct cpu_user_regs *regs) > +{ > + static const xen_uuid_t xen_uuid = XEN_SMCCC_UID; Missing newline here. > + switch ( ARM_SMCCC_FUNC_NUM(get_user_reg(regs, 0)) ) > + { > + case ARM_SMCCC_FUNC_CALL_COUNT: > + set_user_reg(regs, 0, XEN_SMCCC_FUNCTION_COUNT); > + return true; > + case ARM_SMCCC_FUNC_CALL_UID: > + fill_uuid(regs, xen_uuid); > + return true; > + case ARM_SMCCC_FUNC_CALL_REVISION: > + set_user_reg(regs, 0, XEN_SMCCC_MAJOR_REVISION); > + set_user_reg(regs, 1, XEN_SMCCC_MINOR_REVISION); > + return true; default: return false; > + } > + return false; And drop that one. > +} > + > +/* > + * vsmccc_handle_call() - handle SMC/HVC call according to ARM SMCCC. > + * returns true if that was valid SMCCC call (even if function number > + * was unkown). s/unkown/unknown/ > + */ > +static bool vsmccc_handle_call(struct cpu_user_regs *regs) > +{ > + bool handled = false; > + const union hsr hsr = { .bits = regs->hsr }; > + > + /* > + * Check immediate value for HVC32, HVC64 and SMC64. > + * It is not so easy to check immediate value for SMC32, > + * because it is not stored in HSR.ISS field. To get immediate > + * value we need to disassemble instruction at current pc, which > + * is expensive. So we will assume that it is 0x0. > + */ > + switch ( hsr.ec ) > + { > + case HSR_EC_HVC32: > + case HSR_EC_HVC64: > + case HSR_EC_SMC64: > + if ( (hsr.iss & HSR_XXC_IMM_MASK) != 0) > + return false; > + break; > + case HSR_EC_SMC32: > + break; > + default: > + return false; > + } > + > + /* 64 bit calls are allowed only from 64 bit domains. */ > + if ( ARM_SMCCC_IS_64(get_user_reg(regs, 0)) && > + is_32bit_domain(current->domain) ) > + { > + set_user_reg(regs, 0, ARM_SMCCC_ERR_UNKNOWN_FUNCTION); > + return true; > + } > + > + switch ( ARM_SMCCC_OWNER_NUM(get_user_reg(regs, 0)) ) > + { > + case ARM_SMCCC_OWNER_HYPERVISOR: > + handled = handle_hypervisor(regs); > + break; > + } > + > + if ( !handled ) > + { > + gprintk(XENLOG_INFO, "Unhandled SMC/HVC: %08"PRIregister"\n", > + get_user_reg(regs, 0)); > + /* Inform caller that function is not supported. */ > + set_user_reg(regs, 0, ARM_SMCCC_ERR_UNKNOWN_FUNCTION); > + } > + > + return true; > +} > + > +/* This function will be called from traps.c. */ I don't think this is comment is necessary. > +void do_trap_smc(struct cpu_user_regs *regs, const union hsr hsr) > +{ > + int rc = 0; > + > + if ( !check_conditional_instr(regs, hsr) ) > + { > + advance_pc(regs, hsr); > + return; > + } > + > + /* If monitor is enabled, let it handle the call. */ > + if ( current->domain->arch.monitor.privileged_call_enabled ) > + rc = monitor_smc(); > + > + if ( rc == 1 ) > + return; > + > + /* > + * Use standard routines to handle the call. > + * vsmccc_handle_call() will return false if this call is not > + * SMCCC compatbile (i.e. immediate value != 0). As it is not > + * compatible, we can't be sure that guest will understand > + * ARM_SMCCC_ERR_UNKNOWN_FUNCTION. > + */ > + if ( vsmccc_handle_call(regs) ) > + advance_pc(regs, hsr); > + else > + inject_undef_exception(regs, hsr); > +} > + > +/* > + * Local variables: > + * mode: C > + * c-file-style: "BSD" > + * c-basic-offset: 4 > + * indent-tabs-mode: nil > + * End: > + */ > diff --git a/xen/include/asm-arm/vsmc.h b/xen/include/asm-arm/vsmc.h > new file mode 100644 > index 0000000..31aaa55 > --- /dev/null > +++ b/xen/include/asm-arm/vsmc.h > @@ -0,0 +1,30 @@ > +/* > + * Copyright (c) 2017, EPAM Systems > + * > + * This software is licensed under the terms of the GNU General Public > + * License version 2, as published by the Free Software Foundation, and > + * may be copied, distributed, and modified under those terms. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + */ > +#ifndef __ASM_ARM_VSMC_H__ > +#define __ASM_ARM_VSMC_H__ > + > +#include <xen/types.h> > + > +void do_trap_smc(struct cpu_user_regs *regs, const union hsr hsr); I don't see any benefits of having a new header with just two prototype. It would make sense to move them in traps.h. > + > +#endif /* __ASM_ARM_VSMC_H__ */ > + > +/* > + * Local variables: > + * mode: C > + * c-file-style: "BSD" > + * c-basic-offset: 4 > + * indent-tabs-mode: nil > + * End:b > + */ > diff --git a/xen/include/public/arch-arm/smc.h b/xen/include/public/arch-arm/smc.h > new file mode 100644 > index 0000000..3d3cd90 > --- /dev/null > +++ b/xen/include/public/arch-arm/smc.h Likely, this should be called smccc.h. > @@ -0,0 +1,58 @@ > +/* > + * smc.h > + * > + * SMC/HVC interface in accordance with SMC Calling Convention. > + * > + * Permission is hereby granted, free of charge, to any person obtaining a copy > + * of this software and associated documentation files (the "Software"), to > + * deal in the Software without restriction, including without limitation the > + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or > + * sell copies of the Software, and to permit persons to whom the Software is > + * furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice shall be included in > + * all copies or substantial portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE > + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER > + * DEALINGS IN THE SOFTWARE. > + * > + * Copyright 2017 (C) EPAM Systems > + */ > + > +#ifndef __XEN_PUBLIC_ARCH_ARM_SMC_H__ > +#define __XEN_PUBLIC_ARCH_ARM_SMC_H__ > + > +#include "public/xen.h" > + > +/* > + * Hypervisor Service version. > + * > + * We can't use XEN version here, because of SMCCC requirements: > + * Major revision should change every time SMC/HVC function is removed. > + * Minor revision should change every time SMC/HVC function is added. > + * So, it is SMCCC protocol revision code, not XEN version. > + * > + * Those values are subjected to change, when interface will be extended. > + */ > +#define XEN_SMCCC_MAJOR_REVISION 0 > +#define XEN_SMCCC_MINOR_REVISION 1 > + > +/* Hypervisor Service UID. Randomly generated with uuidgen. */ > +#define XEN_SMCCC_UID XEN_DEFINE_UUID(0xa71812dc, 0xc698, 0x4369, 0x9acf, \ > + 0x79, 0xd1, 0x8d, 0xde, 0xe6, 0x67) > + > +#endif /* __XEN_PUBLIC_ARCH_ARM_SMC_H__ */ > + > +/* > + * Local variables: > + * mode: C > + * c-file-style: "BSD" > + * c-basic-offset: 4 > + * indent-tabs-mode: nil > + * End:b > + */ > Cheers,
diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile index de00c5e..3d7dde9 100644 --- a/xen/arch/arm/Makefile +++ b/xen/arch/arm/Makefile @@ -51,6 +51,7 @@ obj-$(CONFIG_HAS_GICV3) += vgic-v3.o obj-$(CONFIG_HAS_ITS) += vgic-v3-its.o obj-y += vm_event.o obj-y += vtimer.o +obj-y += vsmc.o obj-y += vpsci.o obj-y += vuart.o diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c index 82cd2b1..4141a89 100644 --- a/xen/arch/arm/traps.c +++ b/xen/arch/arm/traps.c @@ -50,6 +50,7 @@ #include <asm/regs.h> #include <asm/traps.h> #include <asm/vgic.h> +#include <asm/vsmc.h> #include <asm/vtimer.h> #include "decode.h" @@ -2155,23 +2156,6 @@ static void do_trap_data_abort_guest(struct cpu_user_regs *regs, inject_dabt_exception(regs, info.gva, hsr.len); } -static void do_trap_smc(struct cpu_user_regs *regs, const union hsr hsr) -{ - int rc = 0; - - if ( !check_conditional_instr(regs, hsr) ) - { - advance_pc(regs, hsr); - return; - } - - if ( current->domain->arch.monitor.privileged_call_enabled ) - rc = monitor_smc(); - - if ( rc != 1 ) - inject_undef_exception(regs, hsr); -} - static void enter_hypervisor_head(struct cpu_user_regs *regs) { if ( guest_mode(regs) ) diff --git a/xen/arch/arm/vsmc.c b/xen/arch/arm/vsmc.c new file mode 100644 index 0000000..0a81294 --- /dev/null +++ b/xen/arch/arm/vsmc.c @@ -0,0 +1,160 @@ +/* + * xen/arch/arm/vsmc.c + * + * Generic handler for SMC and HVC calls according to + * ARM SMC calling convention + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +#include <xen/lib.h> +#include <xen/types.h> +#include <public/arch-arm/smc.h> +#include <asm/monitor.h> +#include <asm/regs.h> +#include <asm/smccc.h> +#include <asm/traps.h> +#include <asm/vsmc.h> + +/* Number of functions currently supported by Hypervisor Service. */ +#define XEN_SMCCC_FUNCTION_COUNT 3 + +static void fill_uuid(struct cpu_user_regs *regs, const xen_uuid_t u) +{ +#define FILL_UUID(n) \ + set_user_reg(regs, n, (register_t) u[n * 4 + 0] << 24 | \ + u[n * 4 + 1] << 16 | \ + u[n * 4 + 2] << 8 | \ + u[n * 4 + 3] << 0 ) + + FILL_UUID(0); + FILL_UUID(1); + FILL_UUID(2); + FILL_UUID(3); +#undef FILL_UUID +} + +/* SMCCC interface for hypervisor. Tell about itself. */ +static bool handle_hypervisor(struct cpu_user_regs *regs) +{ + static const xen_uuid_t xen_uuid = XEN_SMCCC_UID; + switch ( ARM_SMCCC_FUNC_NUM(get_user_reg(regs, 0)) ) + { + case ARM_SMCCC_FUNC_CALL_COUNT: + set_user_reg(regs, 0, XEN_SMCCC_FUNCTION_COUNT); + return true; + case ARM_SMCCC_FUNC_CALL_UID: + fill_uuid(regs, xen_uuid); + return true; + case ARM_SMCCC_FUNC_CALL_REVISION: + set_user_reg(regs, 0, XEN_SMCCC_MAJOR_REVISION); + set_user_reg(regs, 1, XEN_SMCCC_MINOR_REVISION); + return true; + } + return false; +} + +/* + * vsmccc_handle_call() - handle SMC/HVC call according to ARM SMCCC. + * returns true if that was valid SMCCC call (even if function number + * was unkown). + */ +static bool vsmccc_handle_call(struct cpu_user_regs *regs) +{ + bool handled = false; + const union hsr hsr = { .bits = regs->hsr }; + + /* + * Check immediate value for HVC32, HVC64 and SMC64. + * It is not so easy to check immediate value for SMC32, + * because it is not stored in HSR.ISS field. To get immediate + * value we need to disassemble instruction at current pc, which + * is expensive. So we will assume that it is 0x0. + */ + switch ( hsr.ec ) + { + case HSR_EC_HVC32: + case HSR_EC_HVC64: + case HSR_EC_SMC64: + if ( (hsr.iss & HSR_XXC_IMM_MASK) != 0) + return false; + break; + case HSR_EC_SMC32: + break; + default: + return false; + } + + /* 64 bit calls are allowed only from 64 bit domains. */ + if ( ARM_SMCCC_IS_64(get_user_reg(regs, 0)) && + is_32bit_domain(current->domain) ) + { + set_user_reg(regs, 0, ARM_SMCCC_ERR_UNKNOWN_FUNCTION); + return true; + } + + switch ( ARM_SMCCC_OWNER_NUM(get_user_reg(regs, 0)) ) + { + case ARM_SMCCC_OWNER_HYPERVISOR: + handled = handle_hypervisor(regs); + break; + } + + if ( !handled ) + { + gprintk(XENLOG_INFO, "Unhandled SMC/HVC: %08"PRIregister"\n", + get_user_reg(regs, 0)); + /* Inform caller that function is not supported. */ + set_user_reg(regs, 0, ARM_SMCCC_ERR_UNKNOWN_FUNCTION); + } + + return true; +} + +/* This function will be called from traps.c. */ +void do_trap_smc(struct cpu_user_regs *regs, const union hsr hsr) +{ + int rc = 0; + + if ( !check_conditional_instr(regs, hsr) ) + { + advance_pc(regs, hsr); + return; + } + + /* If monitor is enabled, let it handle the call. */ + if ( current->domain->arch.monitor.privileged_call_enabled ) + rc = monitor_smc(); + + if ( rc == 1 ) + return; + + /* + * Use standard routines to handle the call. + * vsmccc_handle_call() will return false if this call is not + * SMCCC compatbile (i.e. immediate value != 0). As it is not + * compatible, we can't be sure that guest will understand + * ARM_SMCCC_ERR_UNKNOWN_FUNCTION. + */ + if ( vsmccc_handle_call(regs) ) + advance_pc(regs, hsr); + else + inject_undef_exception(regs, hsr); +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/asm-arm/vsmc.h b/xen/include/asm-arm/vsmc.h new file mode 100644 index 0000000..31aaa55 --- /dev/null +++ b/xen/include/asm-arm/vsmc.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2017, EPAM Systems + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef __ASM_ARM_VSMC_H__ +#define __ASM_ARM_VSMC_H__ + +#include <xen/types.h> + +void do_trap_smc(struct cpu_user_regs *regs, const union hsr hsr); + +#endif /* __ASM_ARM_VSMC_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End:b + */ diff --git a/xen/include/public/arch-arm/smc.h b/xen/include/public/arch-arm/smc.h new file mode 100644 index 0000000..3d3cd90 --- /dev/null +++ b/xen/include/public/arch-arm/smc.h @@ -0,0 +1,58 @@ +/* + * smc.h + * + * SMC/HVC interface in accordance with SMC Calling Convention. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright 2017 (C) EPAM Systems + */ + +#ifndef __XEN_PUBLIC_ARCH_ARM_SMC_H__ +#define __XEN_PUBLIC_ARCH_ARM_SMC_H__ + +#include "public/xen.h" + +/* + * Hypervisor Service version. + * + * We can't use XEN version here, because of SMCCC requirements: + * Major revision should change every time SMC/HVC function is removed. + * Minor revision should change every time SMC/HVC function is added. + * So, it is SMCCC protocol revision code, not XEN version. + * + * Those values are subjected to change, when interface will be extended. + */ +#define XEN_SMCCC_MAJOR_REVISION 0 +#define XEN_SMCCC_MINOR_REVISION 1 + +/* Hypervisor Service UID. Randomly generated with uuidgen. */ +#define XEN_SMCCC_UID XEN_DEFINE_UUID(0xa71812dc, 0xc698, 0x4369, 0x9acf, \ + 0x79, 0xd1, 0x8d, 0xde, 0xe6, 0x67) + +#endif /* __XEN_PUBLIC_ARCH_ARM_SMC_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End:b + */