mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 20:07:46 +09:00
Revert "ANDROID: BACKPORT: KVM: arm64: Block unsafe FF-A calls from the host"
This reverts commit c63757defd.
Bug: 233587962
Signed-off-by: Will Deacon <willdeacon@google.com>
Change-Id: I6ab696c6ec7f60828061e0bbf2a2466a1b641340
This commit is contained in:
@@ -1,16 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (C) 2022 - Google LLC
|
||||
* Author: Andrew Walbran <qwandor@google.com>
|
||||
*/
|
||||
#ifndef __KVM_HYP_FFA_H
|
||||
#define __KVM_HYP_FFA_H
|
||||
|
||||
#include <asm/kvm_host.h>
|
||||
|
||||
#define FFA_MIN_FUNC_NUM 0x60
|
||||
#define FFA_MAX_FUNC_NUM 0x7F
|
||||
|
||||
bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt);
|
||||
|
||||
#endif /* __KVM_HYP_FFA_H */
|
||||
@@ -19,7 +19,7 @@ lib-objs := $(addprefix ../../../lib/, $(lib-objs))
|
||||
|
||||
obj-y := timer-sr.o sysreg-sr.o debug-sr.o switch.o tlb.o hyp-init.o host.o \
|
||||
hyp-main.o hyp-smp.o psci-relay.o early_alloc.o stub.o page_alloc.o \
|
||||
cache.o ffa.o setup.o mm.o mem_protect.o sys_regs.o pkvm.o
|
||||
cache.o setup.o mm.o mem_protect.o sys_regs.o pkvm.o
|
||||
obj-y += ../vgic-v3-sr.o ../aarch32.o ../vgic-v2-cpuif-proxy.o ../entry.o \
|
||||
../fpsimd.o ../hyp-entry.o ../exception.o ../pgtable.o
|
||||
obj-y += $(lib-objs)
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* FF-A v1.0 proxy to filter out invalid memory-sharing SMC calls issued by
|
||||
* the host. FF-A is a slightly more palatable abbreviation of "Arm Firmware
|
||||
* Framework for Arm A-profile", which is specified by Arm in document
|
||||
* number DEN0077.
|
||||
*
|
||||
* Copyright (C) 2022 - Google LLC
|
||||
* Author: Andrew Walbran <qwandor@google.com>
|
||||
*
|
||||
* This driver hooks into the SMC trapping logic for the host and intercepts
|
||||
* all calls falling within the FF-A range. Each call is either:
|
||||
*
|
||||
* - Forwarded on unmodified to the SPMD at EL3
|
||||
* - Rejected as "unsupported"
|
||||
* - Accompanied by a host stage-2 page-table check/update and reissued
|
||||
*
|
||||
* Consequently, any attempts by the host to make guest memory pages
|
||||
* accessible to the secure world using FF-A will be detected either here
|
||||
* (in the case that the memory is already owned by the guest) or during
|
||||
* donation to the guest (in the case that the memory was previously shared
|
||||
* with the secure world).
|
||||
*
|
||||
* To allow the rolling-back of page-table updates and FF-A calls in the
|
||||
* event of failure, operations involving the RXTX buffers are locked for
|
||||
* the duration and are therefore serialised.
|
||||
*/
|
||||
|
||||
#include <linux/arm-smccc.h>
|
||||
#include <linux/arm_ffa.h>
|
||||
#include <nvhe/ffa.h>
|
||||
#include <nvhe/trap_handler.h>
|
||||
|
||||
static void ffa_to_smccc_error(struct arm_smccc_res *res, u64 ffa_errno)
|
||||
{
|
||||
*res = (struct arm_smccc_res) {
|
||||
.a0 = FFA_ERROR,
|
||||
.a2 = ffa_errno,
|
||||
};
|
||||
}
|
||||
|
||||
static void ffa_set_retval(struct kvm_cpu_context *ctxt,
|
||||
struct arm_smccc_res *res)
|
||||
{
|
||||
cpu_reg(ctxt, 0) = res->a0;
|
||||
cpu_reg(ctxt, 1) = res->a1;
|
||||
cpu_reg(ctxt, 2) = res->a2;
|
||||
cpu_reg(ctxt, 3) = res->a3;
|
||||
}
|
||||
|
||||
static bool is_ffa_call(u64 func_id)
|
||||
{
|
||||
return ARM_SMCCC_IS_FAST_CALL(func_id) &&
|
||||
ARM_SMCCC_OWNER_NUM(func_id) == ARM_SMCCC_OWNER_STANDARD &&
|
||||
ARM_SMCCC_FUNC_NUM(func_id) >= FFA_MIN_FUNC_NUM &&
|
||||
ARM_SMCCC_FUNC_NUM(func_id) <= FFA_MAX_FUNC_NUM;
|
||||
}
|
||||
|
||||
static bool ffa_call_unsupported(u64 func_id)
|
||||
{
|
||||
switch (func_id) {
|
||||
/* Unsupported memory management calls */
|
||||
case FFA_FN64_MEM_RETRIEVE_REQ:
|
||||
case FFA_MEM_RETRIEVE_RESP:
|
||||
case FFA_MEM_RELINQUISH:
|
||||
case FFA_MEM_OP_PAUSE:
|
||||
case FFA_MEM_OP_RESUME:
|
||||
case FFA_MEM_FRAG_RX:
|
||||
case FFA_FN64_MEM_DONATE:
|
||||
/* Indirect message passing via RX/TX buffers */
|
||||
case FFA_MSG_SEND:
|
||||
case FFA_MSG_POLL:
|
||||
case FFA_MSG_WAIT:
|
||||
/* 32-bit variants of 64-bit calls */
|
||||
case FFA_MSG_SEND_DIRECT_REQ:
|
||||
case FFA_MSG_SEND_DIRECT_RESP:
|
||||
case FFA_RXTX_MAP:
|
||||
case FFA_MEM_DONATE:
|
||||
case FFA_MEM_RETRIEVE_REQ:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt)
|
||||
{
|
||||
DECLARE_REG(u64, func_id, host_ctxt, 0);
|
||||
struct arm_smccc_res res;
|
||||
|
||||
if (!is_ffa_call(func_id))
|
||||
return false;
|
||||
|
||||
switch (func_id) {
|
||||
/* Memory management */
|
||||
case FFA_FN64_RXTX_MAP:
|
||||
case FFA_RXTX_UNMAP:
|
||||
case FFA_MEM_SHARE:
|
||||
case FFA_FN64_MEM_SHARE:
|
||||
case FFA_MEM_LEND:
|
||||
case FFA_FN64_MEM_LEND:
|
||||
case FFA_MEM_RECLAIM:
|
||||
case FFA_MEM_FRAG_TX:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ffa_call_unsupported(func_id))
|
||||
return false; /* Pass through */
|
||||
|
||||
ffa_to_smccc_error(&res, FFA_RET_NOT_SUPPORTED);
|
||||
ffa_set_retval(host_ctxt, &res);
|
||||
return true;
|
||||
}
|
||||
@@ -15,7 +15,6 @@
|
||||
#include <asm/kvm_hyp.h>
|
||||
#include <asm/kvm_mmu.h>
|
||||
|
||||
#include <nvhe/ffa.h>
|
||||
#include <nvhe/iommu.h>
|
||||
#include <nvhe/mem_protect.h>
|
||||
#include <nvhe/mm.h>
|
||||
@@ -1053,8 +1052,6 @@ static void handle_host_smc(struct kvm_cpu_context *host_ctxt)
|
||||
handled = kvm_host_psci_handler(host_ctxt);
|
||||
if (!handled && kvm_iommu_ops.host_smc_handler)
|
||||
handled = kvm_iommu_ops.host_smc_handler(host_ctxt);
|
||||
if (!handled)
|
||||
handled = kvm_host_ffa_handler(host_ctxt);
|
||||
if (!handled)
|
||||
default_host_smc_handler(host_ctxt);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user