mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
x86: limit number of hypercall parameters to 5
Today there is no hypercall with more than 5 parameters, while the ABI allows up to 6 parameters. Especially for the X86 32-bit case using 6 parameters would require to run without frame pointer, which isn't very fortunate. Note that for Arm the limit is 5 parameters already. So limit the maximum number of parameters to 5 for x86, too. Signed-off-by: Juergen Gross <jgross@suse.com> Reviewed-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
1 parent
3c42cc803c
commit
2f531c122e
4 files changed
+20
-34
No files matched your search
@@ -239,10 +239,9 @@ int hvm_hypercall(struct cpu_user_regs *regs)
|
||||
unsigned long rdx = regs->rdx;
|
||||
unsigned long r10 = regs->r10;
|
||||
unsigned long r8 = regs->r8;
|
||||
unsigned long r9 = regs->r9;
|
||||
|
||||
HVM_DBG_LOG(DBG_LEVEL_HCALL, "hcall%lu(%lx, %lx, %lx, %lx, %lx, %lx)",
|
||||
eax, rdi, rsi, rdx, r10, r8, r9);
|
||||
HVM_DBG_LOG(DBG_LEVEL_HCALL, "hcall%lu(%lx, %lx, %lx, %lx, %lx)",
|
||||
eax, rdi, rsi, rdx, r10, r8);
|
||||
|
||||
#ifndef NDEBUG
|
||||
/* Deliberately corrupt parameter regs not used by this hypercall. */
|
||||
@@ -252,13 +251,11 @@ int hvm_hypercall(struct cpu_user_regs *regs)
|
||||
case 1: rsi = 0xdeadbeefdeadf00dUL; fallthrough;
|
||||
case 2: rdx = 0xdeadbeefdeadf00dUL; fallthrough;
|
||||
case 3: r10 = 0xdeadbeefdeadf00dUL; fallthrough;
|
||||
case 4: r8 = 0xdeadbeefdeadf00dUL; fallthrough;
|
||||
case 5: r9 = 0xdeadbeefdeadf00dUL;
|
||||
case 4: r8 = 0xdeadbeefdeadf00dUL;
|
||||
}
|
||||
#endif
|
||||
|
||||
regs->rax = hvm_hypercall_table[eax].native(rdi, rsi, rdx, r10, r8,
|
||||
r9);
|
||||
regs->rax = hvm_hypercall_table[eax].native(rdi, rsi, rdx, r10, r8);
|
||||
|
||||
#ifndef NDEBUG
|
||||
if ( !curr->hcall_preempted )
|
||||
@@ -266,7 +263,6 @@ int hvm_hypercall(struct cpu_user_regs *regs)
|
||||
/* Deliberately corrupt parameter regs used by this hypercall. */
|
||||
switch ( hypercall_args_table[eax].native )
|
||||
{
|
||||
case 6: regs->r9 = 0xdeadbeefdeadf00dUL; fallthrough;
|
||||
case 5: regs->r8 = 0xdeadbeefdeadf00dUL; fallthrough;
|
||||
case 4: regs->r10 = 0xdeadbeefdeadf00dUL; fallthrough;
|
||||
case 3: regs->rdx = 0xdeadbeefdeadf00dUL; fallthrough;
|
||||
@@ -283,10 +279,9 @@ int hvm_hypercall(struct cpu_user_regs *regs)
|
||||
unsigned int edx = regs->edx;
|
||||
unsigned int esi = regs->esi;
|
||||
unsigned int edi = regs->edi;
|
||||
unsigned int ebp = regs->ebp;
|
||||
|
||||
HVM_DBG_LOG(DBG_LEVEL_HCALL, "hcall%lu(%x, %x, %x, %x, %x, %x)", eax,
|
||||
ebx, ecx, edx, esi, edi, ebp);
|
||||
HVM_DBG_LOG(DBG_LEVEL_HCALL, "hcall%lu(%x, %x, %x, %x, %x)", eax,
|
||||
ebx, ecx, edx, esi, edi);
|
||||
|
||||
#ifndef NDEBUG
|
||||
/* Deliberately corrupt parameter regs not used by this hypercall. */
|
||||
@@ -296,14 +291,12 @@ int hvm_hypercall(struct cpu_user_regs *regs)
|
||||
case 1: ecx = 0xdeadf00d; fallthrough;
|
||||
case 2: edx = 0xdeadf00d; fallthrough;
|
||||
case 3: esi = 0xdeadf00d; fallthrough;
|
||||
case 4: edi = 0xdeadf00d; fallthrough;
|
||||
case 5: ebp = 0xdeadf00d;
|
||||
case 4: edi = 0xdeadf00d;
|
||||
}
|
||||
#endif
|
||||
|
||||
curr->hcall_compat = true;
|
||||
regs->rax = hvm_hypercall_table[eax].compat(ebx, ecx, edx, esi, edi,
|
||||
ebp);
|
||||
regs->rax = hvm_hypercall_table[eax].compat(ebx, ecx, edx, esi, edi);
|
||||
curr->hcall_compat = false;
|
||||
|
||||
#ifndef NDEBUG
|
||||
@@ -312,7 +305,6 @@ int hvm_hypercall(struct cpu_user_regs *regs)
|
||||
/* Deliberately corrupt parameter regs used by this hypercall. */
|
||||
switch ( hypercall_args_table[eax].compat )
|
||||
{
|
||||
case 6: regs->rbp = 0xdeadf00d; fallthrough;
|
||||
case 5: regs->rdi = 0xdeadf00d; fallthrough;
|
||||
case 4: regs->rsi = 0xdeadf00d; fallthrough;
|
||||
case 3: regs->rdx = 0xdeadf00d; fallthrough;
|
||||
@@ -349,7 +341,7 @@ enum mc_disposition hvm_do_multicall_call(struct mc_state *state)
|
||||
func = array_access_nospec(hvm_hypercall_table, call->op).native;
|
||||
if ( func )
|
||||
call->result = func(call->args[0], call->args[1], call->args[2],
|
||||
call->args[3], call->args[4], call->args[5]);
|
||||
call->args[3], call->args[4]);
|
||||
else
|
||||
call->result = -ENOSYS;
|
||||
}
|
||||
@@ -361,7 +353,7 @@ enum mc_disposition hvm_do_multicall_call(struct mc_state *state)
|
||||
func = array_access_nospec(hvm_hypercall_table, call->op).compat;
|
||||
if ( func )
|
||||
call->result = func(call->args[0], call->args[1], call->args[2],
|
||||
call->args[3], call->args[4], call->args[5]);
|
||||
call->args[3], call->args[4]);
|
||||
else
|
||||
call->result = -ENOSYS;
|
||||
}
|
||||
|
||||
@@ -145,7 +145,6 @@ _pv_hypercall(struct cpu_user_regs *regs, bool compat)
|
||||
unsigned long rdx = regs->rdx;
|
||||
unsigned long r10 = regs->r10;
|
||||
unsigned long r8 = regs->r8;
|
||||
unsigned long r9 = regs->r9;
|
||||
|
||||
#ifndef NDEBUG
|
||||
/* Deliberately corrupt parameter regs not used by this hypercall. */
|
||||
@@ -155,18 +154,17 @@ _pv_hypercall(struct cpu_user_regs *regs, bool compat)
|
||||
case 1: rsi = 0xdeadbeefdeadf00dUL; fallthrough;
|
||||
case 2: rdx = 0xdeadbeefdeadf00dUL; fallthrough;
|
||||
case 3: r10 = 0xdeadbeefdeadf00dUL; fallthrough;
|
||||
case 4: r8 = 0xdeadbeefdeadf00dUL; fallthrough;
|
||||
case 5: r9 = 0xdeadbeefdeadf00dUL;
|
||||
case 4: r8 = 0xdeadbeefdeadf00dUL;
|
||||
}
|
||||
#endif
|
||||
if ( unlikely(tb_init_done) )
|
||||
{
|
||||
unsigned long args[6] = { rdi, rsi, rdx, r10, r8, r9 };
|
||||
unsigned long args[5] = { rdi, rsi, rdx, r10, r8 };
|
||||
|
||||
__trace_hypercall(TRC_PV_HYPERCALL_V2, eax, args);
|
||||
}
|
||||
|
||||
regs->rax = pv_hypercall_table[eax].native(rdi, rsi, rdx, r10, r8, r9);
|
||||
regs->rax = pv_hypercall_table[eax].native(rdi, rsi, rdx, r10, r8);
|
||||
|
||||
#ifndef NDEBUG
|
||||
if ( !curr->hcall_preempted )
|
||||
@@ -174,7 +172,6 @@ _pv_hypercall(struct cpu_user_regs *regs, bool compat)
|
||||
/* Deliberately corrupt parameter regs used by this hypercall. */
|
||||
switch ( hypercall_args_table[eax].native )
|
||||
{
|
||||
case 6: regs->r9 = 0xdeadbeefdeadf00dUL; fallthrough;
|
||||
case 5: regs->r8 = 0xdeadbeefdeadf00dUL; fallthrough;
|
||||
case 4: regs->r10 = 0xdeadbeefdeadf00dUL; fallthrough;
|
||||
case 3: regs->rdx = 0xdeadbeefdeadf00dUL; fallthrough;
|
||||
@@ -192,7 +189,6 @@ _pv_hypercall(struct cpu_user_regs *regs, bool compat)
|
||||
unsigned int edx = regs->edx;
|
||||
unsigned int esi = regs->esi;
|
||||
unsigned int edi = regs->edi;
|
||||
unsigned int ebp = regs->ebp;
|
||||
|
||||
#ifndef NDEBUG
|
||||
/* Deliberately corrupt parameter regs not used by this hypercall. */
|
||||
@@ -202,20 +198,19 @@ _pv_hypercall(struct cpu_user_regs *regs, bool compat)
|
||||
case 1: ecx = 0xdeadf00d; fallthrough;
|
||||
case 2: edx = 0xdeadf00d; fallthrough;
|
||||
case 3: esi = 0xdeadf00d; fallthrough;
|
||||
case 4: edi = 0xdeadf00d; fallthrough;
|
||||
case 5: ebp = 0xdeadf00d;
|
||||
case 4: edi = 0xdeadf00d;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( unlikely(tb_init_done) )
|
||||
{
|
||||
unsigned long args[6] = { ebx, ecx, edx, esi, edi, ebp };
|
||||
unsigned long args[5] = { ebx, ecx, edx, esi, edi };
|
||||
|
||||
__trace_hypercall(TRC_PV_HYPERCALL_V2, eax, args);
|
||||
}
|
||||
|
||||
curr->hcall_compat = true;
|
||||
regs->eax = pv_hypercall_table[eax].compat(ebx, ecx, edx, esi, edi, ebp);
|
||||
regs->eax = pv_hypercall_table[eax].compat(ebx, ecx, edx, esi, edi);
|
||||
curr->hcall_compat = false;
|
||||
|
||||
#ifndef NDEBUG
|
||||
@@ -224,7 +219,6 @@ _pv_hypercall(struct cpu_user_regs *regs, bool compat)
|
||||
/* Deliberately corrupt parameter regs used by this hypercall. */
|
||||
switch ( hypercall_args_table[eax].compat )
|
||||
{
|
||||
case 6: regs->ebp = 0xdeadf00d; fallthrough;
|
||||
case 5: regs->edi = 0xdeadf00d; fallthrough;
|
||||
case 4: regs->esi = 0xdeadf00d; fallthrough;
|
||||
case 3: regs->edx = 0xdeadf00d; fallthrough;
|
||||
@@ -262,7 +256,7 @@ enum mc_disposition pv_do_multicall_call(struct mc_state *state)
|
||||
pv_hypercall_table[op].compat )
|
||||
call->result = pv_hypercall_table[op].compat(
|
||||
call->args[0], call->args[1], call->args[2],
|
||||
call->args[3], call->args[4], call->args[5]);
|
||||
call->args[3], call->args[4]);
|
||||
else
|
||||
call->result = -ENOSYS;
|
||||
}
|
||||
@@ -276,7 +270,7 @@ enum mc_disposition pv_do_multicall_call(struct mc_state *state)
|
||||
pv_hypercall_table[op].native )
|
||||
call->result = pv_hypercall_table[op].native(
|
||||
call->args[0], call->args[1], call->args[2],
|
||||
call->args[3], call->args[4], call->args[5]);
|
||||
call->args[3], call->args[4]);
|
||||
else
|
||||
call->result = -ENOSYS;
|
||||
}
|
||||
|
||||
+1
-1
@@ -822,7 +822,7 @@ void __trace_hypercall(uint32_t event, unsigned long op,
|
||||
{
|
||||
struct {
|
||||
uint32_t op;
|
||||
uint32_t args[6];
|
||||
uint32_t args[5];
|
||||
} d;
|
||||
uint32_t *a = d.args;
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
typedef unsigned long hypercall_fn_t(
|
||||
unsigned long, unsigned long, unsigned long,
|
||||
unsigned long, unsigned long, unsigned long);
|
||||
unsigned long, unsigned long);
|
||||
|
||||
typedef struct {
|
||||
hypercall_fn_t *native;
|
||||
|
||||