xref: /openbmc/linux/arch/arm/xen/hypercall.S (revision ee1f9d19)
1aa2466d2SStefano Stabellini/******************************************************************************
2aa2466d2SStefano Stabellini * hypercall.S
3aa2466d2SStefano Stabellini *
4aa2466d2SStefano Stabellini * Xen hypercall wrappers
5aa2466d2SStefano Stabellini *
6aa2466d2SStefano Stabellini * Stefano Stabellini <stefano.stabellini@eu.citrix.com>, Citrix, 2012
7aa2466d2SStefano Stabellini *
8aa2466d2SStefano Stabellini * This program is free software; you can redistribute it and/or
9aa2466d2SStefano Stabellini * modify it under the terms of the GNU General Public License version 2
10aa2466d2SStefano Stabellini * as published by the Free Software Foundation; or, when distributed
11aa2466d2SStefano Stabellini * separately from the Linux kernel or incorporated into other
12aa2466d2SStefano Stabellini * software packages, subject to the following license:
13aa2466d2SStefano Stabellini *
14aa2466d2SStefano Stabellini * Permission is hereby granted, free of charge, to any person obtaining a copy
15aa2466d2SStefano Stabellini * of this source file (the "Software"), to deal in the Software without
16aa2466d2SStefano Stabellini * restriction, including without limitation the rights to use, copy, modify,
17aa2466d2SStefano Stabellini * merge, publish, distribute, sublicense, and/or sell copies of the Software,
18aa2466d2SStefano Stabellini * and to permit persons to whom the Software is furnished to do so, subject to
19aa2466d2SStefano Stabellini * the following conditions:
20aa2466d2SStefano Stabellini *
21aa2466d2SStefano Stabellini * The above copyright notice and this permission notice shall be included in
22aa2466d2SStefano Stabellini * all copies or substantial portions of the Software.
23aa2466d2SStefano Stabellini *
24aa2466d2SStefano Stabellini * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25aa2466d2SStefano Stabellini * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26aa2466d2SStefano Stabellini * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27aa2466d2SStefano Stabellini * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28aa2466d2SStefano Stabellini * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29aa2466d2SStefano Stabellini * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
30aa2466d2SStefano Stabellini * IN THE SOFTWARE.
31aa2466d2SStefano Stabellini */
32aa2466d2SStefano Stabellini
33aa2466d2SStefano Stabellini/*
34aa2466d2SStefano Stabellini * The Xen hypercall calling convention is very similar to the ARM
35aa2466d2SStefano Stabellini * procedure calling convention: the first paramter is passed in r0, the
36aa2466d2SStefano Stabellini * second in r1, the third in r2 and the fourth in r3. Considering that
37aa2466d2SStefano Stabellini * Xen hypercalls have 5 arguments at most, the fifth paramter is passed
38aa2466d2SStefano Stabellini * in r4, differently from the procedure calling convention of using the
39aa2466d2SStefano Stabellini * stack for that case.
40aa2466d2SStefano Stabellini *
41aa2466d2SStefano Stabellini * The hypercall number is passed in r12.
42aa2466d2SStefano Stabellini *
43aa2466d2SStefano Stabellini * The return value is in r0.
44aa2466d2SStefano Stabellini *
45aa2466d2SStefano Stabellini * The hvc ISS is required to be 0xEA1, that is the Xen specific ARM
46aa2466d2SStefano Stabellini * hypercall tag.
47aa2466d2SStefano Stabellini */
48aa2466d2SStefano Stabellini
49aa2466d2SStefano Stabellini#include <linux/linkage.h>
50aa2466d2SStefano Stabellini#include <asm/assembler.h>
51c8d258a7SStefano Stabellini#include <asm/opcodes-virt.h>
52aa2466d2SStefano Stabellini#include <xen/interface/xen.h>
53aa2466d2SStefano Stabellini
54aa2466d2SStefano Stabellini
55c8d258a7SStefano Stabellini#define XEN_IMM 0xEA1
56aa2466d2SStefano Stabellini
57aa2466d2SStefano Stabellini#define HYPERCALL_SIMPLE(hypercall)		\
58aa2466d2SStefano StabelliniENTRY(HYPERVISOR_##hypercall)			\
59aa2466d2SStefano Stabellini	mov r12, #__HYPERVISOR_##hypercall;	\
60c8d258a7SStefano Stabellini	__HVC(XEN_IMM);						\
616ebbf2ceSRussell King	ret lr;					\
62aa2466d2SStefano StabelliniENDPROC(HYPERVISOR_##hypercall)
63aa2466d2SStefano Stabellini
64aa2466d2SStefano Stabellini#define HYPERCALL0 HYPERCALL_SIMPLE
65aa2466d2SStefano Stabellini#define HYPERCALL1 HYPERCALL_SIMPLE
66aa2466d2SStefano Stabellini#define HYPERCALL2 HYPERCALL_SIMPLE
67aa2466d2SStefano Stabellini#define HYPERCALL3 HYPERCALL_SIMPLE
68aa2466d2SStefano Stabellini#define HYPERCALL4 HYPERCALL_SIMPLE
69aa2466d2SStefano Stabellini
70aa2466d2SStefano Stabellini#define HYPERCALL5(hypercall)			\
71aa2466d2SStefano StabelliniENTRY(HYPERVISOR_##hypercall)			\
72aa2466d2SStefano Stabellini	stmdb sp!, {r4}						\
73aa2466d2SStefano Stabellini	ldr r4, [sp, #4]					\
74aa2466d2SStefano Stabellini	mov r12, #__HYPERVISOR_##hypercall;	\
75c8d258a7SStefano Stabellini	__HVC(XEN_IMM);						\
76aa2466d2SStefano Stabellini	ldm sp!, {r4}						\
776ebbf2ceSRussell King	ret lr					\
78aa2466d2SStefano StabelliniENDPROC(HYPERVISOR_##hypercall)
79aa2466d2SStefano Stabellini
80aa2466d2SStefano Stabellini                .text
81aa2466d2SStefano Stabellini
82aa2466d2SStefano StabelliniHYPERCALL2(xen_version);
83aa2466d2SStefano StabelliniHYPERCALL3(console_io);
84aa2466d2SStefano StabelliniHYPERCALL3(grant_table_op);
85aa2466d2SStefano StabelliniHYPERCALL2(sched_op);
86aa2466d2SStefano StabelliniHYPERCALL2(event_channel_op);
87aa2466d2SStefano StabelliniHYPERCALL2(hvm_op);
88aa2466d2SStefano StabelliniHYPERCALL2(memory_op);
89aa2466d2SStefano StabelliniHYPERCALL2(physdev_op);
90ea0af613SStefano StabelliniHYPERCALL3(vcpu_op);
9172d39c69SStefano StabelliniHYPERCALL1(platform_op_raw);
925e40704eSIan CampbellHYPERCALL2(multicall);
934b5ae015SJuergen GrossHYPERCALL2(vm_assist);
94ab520be8SPaul DurrantHYPERCALL3(dm_op);
95aa2466d2SStefano Stabellini
96aa2466d2SStefano StabelliniENTRY(privcmd_call)
97aa2466d2SStefano Stabellini	stmdb sp!, {r4}
98aa2466d2SStefano Stabellini	mov r12, r0
99aa2466d2SStefano Stabellini	mov r0, r1
100aa2466d2SStefano Stabellini	mov r1, r2
101aa2466d2SStefano Stabellini	mov r2, r3
102aa2466d2SStefano Stabellini	ldr r3, [sp, #8]
1030b61f2c0SJulien Grall	/*
1040b61f2c0SJulien Grall	 * Privcmd calls are issued by the userspace. We need to allow the
1050b61f2c0SJulien Grall	 * kernel to access the userspace memory before issuing the hypercall.
1060b61f2c0SJulien Grall	 */
1070b61f2c0SJulien Grall	uaccess_enable r4
1080b61f2c0SJulien Grall
1090b61f2c0SJulien Grall	/* r4 is loaded now as we use it as scratch register before */
110aa2466d2SStefano Stabellini	ldr r4, [sp, #4]
111c8d258a7SStefano Stabellini	__HVC(XEN_IMM)
1120b61f2c0SJulien Grall
1130b61f2c0SJulien Grall	/*
1140b61f2c0SJulien Grall	 * Disable userspace access from kernel. This is fine to do it
115736706beSLinus Torvalds	 * unconditionally as no set_fs(KERNEL_DS) is called before.
1160b61f2c0SJulien Grall	 */
1170b61f2c0SJulien Grall	uaccess_disable r4
1180b61f2c0SJulien Grall
119aa2466d2SStefano Stabellini	ldm sp!, {r4}
1206ebbf2ceSRussell King	ret lr
121aa2466d2SStefano StabelliniENDPROC(privcmd_call);
122