8000 fault injection: add QMP memread/memwrite commands by ho28 · Pull Request #10 · Wind-River/qemu · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

fault injection: add QMP memread/memwrite commands #10

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions qapi/injection.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# -*- Mode: Python -*-
# vim: filetype=python
#
# Copyright (C) 2024 Wind River Systems
#
# 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.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

##
# @InjectionValue:
#
# A single unsigned 64-bit integer.
#
# @value: single unsigned 64-bit integer.
#
# Since: 9.1
##
{ 'struct': 'InjectionValue',
'data': { 'value': 'uint64'} }

##
# @memwrite:
#
# Write a guest memory location from CPU[cpu_id]
#
# @addr: the virtual address to write to
#
# @size: the number of bytes to write at addr (max is 8)
#
# @val: the unsigned 64-bit integer value to write at addr
#
# @cpuid: the index of the virtual CPU to use for translating the
# virtual address
#
# Since: 9.1
#
##
{ 'command': 'memwrite',
'data': {'addr': 'uint64', 'size': 'int', 'val': 'uint64', 'cpuid': 'int'}
}

##
# @memread:
#
# Read a guest memory location from CPU[cpu_id]
#
# @addr: the virtual address to read from
#
# @size: the number of bytes to read at addr (max is 8)
#
# @cpuid: the index of the virtual CPU to use for translating the
# virtual address
#
# Returns: InjectionValue, a structure with the unsigned 64-bit integer value read
#
# Since: 9.1
#
##
{ 'command': 'memread',
'data': {'addr': 'uint64', 'size': 'int', 'cpuid': 'int'},
'returns' : 'InjectionValue'
}
1 change: 1 addition & 0 deletions qapi/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ qapi_all_modules = [
'dump',
'ebpf',
'error',
'injection',
'introspect',
'job',
'machine-common',
Expand Down
1 change: 1 addition & 0 deletions qapi/qapi-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,4 @@
{ 'include': 'vfio.json' }
{ 'include': 'cryptodev.json' }
{ 'include': 'cxl.json' }
{ 'include': 'injection.json' }
57 changes: 57 additions & 0 deletions system/cpus.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
* 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.
*
* 22 Oct 2024 - Add QMP memread/memwrite APIs
*/

#include "qemu/osdep.h"
Expand All @@ -29,6 +31,8 @@
#include "qapi/qapi-commands-machine.h"
#include "qapi/qapi-commands-misc.h"
#include "qapi/qapi-events-run-state.h"
#include "qapi/qapi-types-injection.h"
#include "qapi/qapi-commands-injection.h"
#include "qapi/qmp/qerror.h"
#include "exec/gdbstub.h"
#include "sysemu/hw_accel.h"
Expand Down Expand Up @@ -871,6 +875,59 @@ void qmp_pmemsave(uint64_t addr, uint64_t size, const char *filename,
fclose(f);
}

void qmp_memwrite(uint64_t addr, int64_t size, uint64_t val,
int64_t cpu_id, Error **errp)
{
CPUState *cpu;

if (size <= 0 || size > sizeof(uint64_t)) {
error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "size",
"out of range");
return;
}

cpu = qemu_get_cpu(cpu_id);
if (cpu == NULL) {
error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "cpu-index",
"a CPU number");
return;
}

if (cpu_memory_rw_debug(cpu, addr, (uint64_t *)&val, size, 1)) {
error_setg(errp, "Invalid addr 0x%016" PRIx64 "/size %" PRIu64
" specified", addr, size);
}
}

InjectionValue *qmp_memread(uint64_t addr, int64_t size,
int64_t cpu_id, Error **errp)
{
InjectionValue *ret = g_new0(InjectionValue, 1);
CPUState *cpu;

ret->value = 0;

if (size <= 0 || size > sizeof(uint64_t)) {
error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "size",
"out of range");
return NULL;
}

cpu = qemu_get_cpu(cpu_id);
if (cpu == NULL) {
error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "cpu-index",
"a CPU number");
return NULL;
}

if (cpu_memory_rw_debug(cpu, addr, &ret->value, size, 0) != 0) {
error_setg(errp, "Invalid addr 0x%016" PRIx64 "/size %" PRIu64
" specified", addr, size);
}

return ret;
}

void qmp_inject_nmi(Error **errp)
{
nmi_monitor_handle(monitor_get_cpu_index(monitor_cur()), errp);
Expand Down
0