Merge remote-tracking branch 'qmp/queue/qmp' into staging

* qmp/queue/qmp: (29 commits)
  Add 'query-events' command to QMP to query async events
  qapi: convert netdev_del
  qapi: convert netdev_add
  net: net_client_init(): use error_set()
  net: purge the monitor object from all init functions
  qemu-config: introduce qemu_find_opts_err()
  qemu-config: find_list(): use error_set()
  qerror: introduce QERR_INVALID_OPTION_GROUP
  qemu-option: qemu_opts_from_qdict(): use error_set()
  qemu-option: introduce qemu_opt_set_err()
  qemu-option: opt_set(): use error_set()
  qemu-option: qemu_opts_validate(): use error_set()
  qemu-option: qemu_opt_parse(): use error_set()
  qemu-option: parse_option_size(): use error_set()
  qemu-option: parse_option_bool(): use error_set()
  qemu-option: parse_option_number(): use error_set()
  qemu-option: qemu_opts_create(): use error_set()
  introduce a new monitor command 'dump-guest-memory' to dump guest's memory
  make gdb_id() generally avialable and rename it to cpu_index()
  target-i386: Add API to get note's size
  ...
This commit is contained in:
Anthony Liguori
2012-06-06 20:57:56 +08:00
49 changed files with 2693 additions and 255 deletions
+5
View File
@@ -192,6 +192,9 @@ obj-$(CONFIG_KVM) += kvm.o kvm-all.o
obj-$(CONFIG_NO_KVM) += kvm-stub.o
obj-$(CONFIG_VGA) += vga.o
obj-y += memory.o savevm.o cputlb.o
obj-y += memory_mapping.o
obj-$(CONFIG_HAVE_GET_MEMORY_MAPPING) += arch_memory_mapping.o
obj-$(CONFIG_HAVE_CORE_DUMP) += arch_dump.o
LIBS+=-lz
obj-i386-$(CONFIG_KVM) += hyperv.o
@@ -402,6 +405,8 @@ obj-y += $(addprefix ../, $(trace-obj-y))
endif # CONFIG_SOFTMMU
obj-y += dump.o
ifndef CONFIG_LINUX_USER
ifndef CONFIG_BSD_USER
# libcacard needs qemu-thread support, and besides is only needed by devices
+1 -1
View File
@@ -569,7 +569,7 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
break;
case IF_VIRTIO:
/* add virtio block device */
opts = qemu_opts_create(qemu_find_opts("device"), NULL, 0);
opts = qemu_opts_create(qemu_find_opts("device"), NULL, 0, NULL);
if (arch_type == QEMU_ARCH_S390X) {
qemu_opt_set(opts, "driver", "virtio-blk-s390");
} else {
Vendored
+8
View File
@@ -3729,6 +3729,10 @@ case "$target_arch2" in
fi
fi
esac
case "$target_arch2" in
i386|x86_64)
echo "CONFIG_HAVE_GET_MEMORY_MAPPING=y" >> $config_target_mak
esac
if test "$target_arch2" = "ppc64" -a "$fdt" = "yes"; then
echo "CONFIG_PSERIES=y" >> $config_target_mak
fi
@@ -3744,6 +3748,10 @@ if test "$target_softmmu" = "yes" ; then
if test "$smartcard_nss" = "yes" ; then
echo "subdir-$target: subdir-libcacard" >> $config_host_mak
fi
case "$target_arch2" in
i386|x86_64)
echo "CONFIG_HAVE_CORE_DUMP=y" >> $config_target_mak
esac
fi
if test "$target_user_only" = "yes" ; then
echo "CONFIG_USER_ONLY=y" >> $config_target_mak
+70
View File
@@ -22,6 +22,8 @@
#include "qemu-common.h"
#include "qemu-tls.h"
#include "cpu-common.h"
#include "memory_mapping.h"
#include "dump.h"
/* some important defines:
*
@@ -523,4 +525,72 @@ void dump_exec_info(FILE *f, fprintf_function cpu_fprintf);
int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr,
uint8_t *buf, int len, int is_write);
#if defined(CONFIG_HAVE_GET_MEMORY_MAPPING)
int cpu_get_memory_mapping(MemoryMappingList *list, CPUArchState *env);
bool cpu_paging_enabled(CPUArchState *env);
#else
static inline int cpu_get_memory_mapping(MemoryMappingList *list,
CPUArchState *env)
{
return -1;
}
static inline bool cpu_paging_enabled(CPUArchState *env)
{
return true;
}
#endif
typedef int (*write_core_dump_function)(void *buf, size_t size, void *opaque);
#if defined(CONFIG_HAVE_CORE_DUMP)
int cpu_write_elf64_note(write_core_dump_function f, CPUArchState *env,
int cpuid, void *opaque);
int cpu_write_elf32_note(write_core_dump_function f, CPUArchState *env,
int cpuid, void *opaque);
int cpu_write_elf64_qemunote(write_core_dump_function f, CPUArchState *env,
void *opaque);
int cpu_write_elf32_qemunote(write_core_dump_function f, CPUArchState *env,
void *opaque);
int cpu_get_dump_info(ArchDumpInfo *info);
size_t cpu_get_note_size(int class, int machine, int nr_cpus);
#else
static inline int cpu_write_elf64_note(write_core_dump_function f,
CPUArchState *env, int cpuid,
void *opaque)
{
return -1;
}
static inline int cpu_write_elf32_note(write_core_dump_function f,
CPUArchState *env, int cpuid,
void *opaque)
{
return -1;
}
static inline int cpu_write_elf64_qemunote(write_core_dump_function f,
CPUArchState *env,
void *opaque)
{
return -1;
}
static inline int cpu_write_elf32_qemunote(write_core_dump_function f,
CPUArchState *env,
void *opaque)
{
return -1;
}
static inline int cpu_get_dump_info(ArchDumpInfo *info)
{
return -1;
}
static inline int cpu_get_note_size(int class, int machine, int nr_cpus)
{
return -1;
}
#endif
#endif /* CPU_ALL_H */
+4
View File
@@ -71,6 +71,10 @@ void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len,
void *cpu_register_map_client(void *opaque, void (*callback)(void *opaque));
void cpu_unregister_map_client(void *cookie);
#ifndef CONFIG_USER_ONLY
bool cpu_physical_memory_is_io(target_phys_addr_t phys_addr);
#endif
/* Coalesced MMIO regions are areas where write operations can be reordered.
* This usually implies that write operations are side-effect free. This allows
* batching which can make a major impact on performance when using
+883
View File
File diff suppressed because it is too large Load Diff
+23
View File
@@ -0,0 +1,23 @@
/*
* QEMU dump
*
* Copyright Fujitsu, Corp. 2011, 2012
*
* Authors:
* Wen Congyang <wency@cn.fujitsu.com>
*
* This work is licensed under the terms of the GNU GPL, version 2. See
* the COPYING file in the top-level directory.
*
*/
#ifndef DUMP_H
#define DUMP_H
typedef struct ArchDumpInfo {
int d_machine; /* Architecture */
int d_endian; /* ELFDATA2LSB or ELFDATA2MSB */
int d_class; /* ELFCLASS32 or ELFCLASS64 */
} ArchDumpInfo;
#endif
+5
View File
@@ -1037,6 +1037,11 @@ typedef struct elf64_sym {
#define EI_NIDENT 16
/* Special value for e_phnum. This indicates that the real number of
program headers is too large to fit into e_phnum. Instead the real
value is in the field sh_info of section 0. */
#define PN_XNUM 0xffff
typedef struct elf32_hdr{
unsigned char e_ident[EI_NIDENT];
Elf32_Half e_type;
+12
View File
@@ -4336,3 +4336,15 @@ bool virtio_is_big_endian(void)
}
#endif
#ifndef CONFIG_USER_ONLY
bool cpu_physical_memory_is_io(target_phys_addr_t phys_addr)
{
MemoryRegionSection *section;
section = phys_page_find(phys_addr >> TARGET_PAGE_BITS);
return !(memory_region_is_ram(section->mr) ||
memory_region_is_romd(section->mr));
}
#endif
+5 -14
View File
@@ -1937,21 +1937,12 @@ static void gdb_set_cpu_pc(GDBState *s, target_ulong pc)
#endif
}
static inline int gdb_id(CPUArchState *env)
{
#if defined(CONFIG_USER_ONLY) && defined(CONFIG_USE_NPTL)
return env->host_tid;
#else
return env->cpu_index + 1;
#endif
}
static CPUArchState *find_cpu(uint32_t thread_id)
{
CPUArchState *env;
for (env = first_cpu; env != NULL; env = env->next_cpu) {
if (gdb_id(env) == thread_id) {
if (cpu_index(env) == thread_id) {
return env;
}
}
@@ -1979,7 +1970,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
case '?':
/* TODO: Make this return the correct value for user-mode. */
snprintf(buf, sizeof(buf), "T%02xthread:%02x;", GDB_SIGNAL_TRAP,
gdb_id(s->c_cpu));
cpu_index(s->c_cpu));
put_packet(s, buf);
/* Remove all the breakpoints when this query is issued,
* because gdb is doing and initial connect and the state
@@ -2274,7 +2265,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
} else if (strcmp(p,"sThreadInfo") == 0) {
report_cpuinfo:
if (s->query_cpu) {
snprintf(buf, sizeof(buf), "m%x", gdb_id(s->query_cpu));
snprintf(buf, sizeof(buf), "m%x", cpu_index(s->query_cpu));
put_packet(s, buf);
s->query_cpu = s->query_cpu->next_cpu;
} else
@@ -2422,7 +2413,7 @@ static void gdb_vm_state_change(void *opaque, int running, RunState state)
}
snprintf(buf, sizeof(buf),
"T%02xthread:%02x;%swatch:" TARGET_FMT_lx ";",
GDB_SIGNAL_TRAP, gdb_id(env), type,
GDB_SIGNAL_TRAP, cpu_index(env), type,
env->watchpoint_hit->vaddr);
env->watchpoint_hit = NULL;
goto send_packet;
@@ -2455,7 +2446,7 @@ static void gdb_vm_state_change(void *opaque, int running, RunState state)
ret = GDB_SIGNAL_UNKNOWN;
break;
}
snprintf(buf, sizeof(buf), "T%02xthread:%02x;", ret, gdb_id(env));
snprintf(buf, sizeof(buf), "T%02xthread:%02x;", ret, cpu_index(env));
send_packet:
put_packet(s, buf);
+9
View File
@@ -30,6 +30,15 @@ void gdb_register_coprocessor(CPUArchState *env,
gdb_reg_cb get_reg, gdb_reg_cb set_reg,
int num_regs, const char *xml, int g_pos);
static inline int cpu_index(CPUArchState *env)
{
#if defined(CONFIG_USER_ONLY) && defined(CONFIG_USE_NPTL)
return env->host_tid;
#else
return env->cpu_index + 1;
#endif
}
#endif
#ifdef CONFIG_USER_ONLY
+30 -4
View File
@@ -878,6 +878,34 @@ server will ask the spice/vnc client to automatically reconnect using the
new parameters (if specified) once the vm migration finished successfully.
ETEXI
#if defined(CONFIG_HAVE_CORE_DUMP)
{
.name = "dump-guest-memory",
.args_type = "paging:-p,protocol:s,begin:i?,length:i?",
.params = "[-p] protocol [begin] [length]",
.help = "dump guest memory to file"
"\n\t\t\t begin(optional): the starting physical address"
"\n\t\t\t length(optional): the memory size, in bytes",
.user_print = monitor_user_noop,
.mhandler.cmd = hmp_dump_guest_memory,
},
STEXI
@item dump-guest-memory [-p] @var{protocol} @var{begin} @var{length}
@findex dump-guest-memory
Dump guest memory to @var{protocol}. The file can be processed with crash or
gdb.
protocol: destination file(started with "file:") or destination file
descriptor (started with "fd:")
paging: do paging to get guest's memory mapping
begin: the starting physical address. It's optional, and should be
specified with length together.
length: the memory size, in bytes. It's optional, and should be specified
with begin together.
ETEXI
#endif
{
.name = "snapshot_blkdev",
.args_type = "reuse:-n,device:B,snapshot-file:s?,format:s?",
@@ -1009,8 +1037,7 @@ ETEXI
.args_type = "netdev:O",
.params = "[user|tap|socket],id=str[,prop=value][,...]",
.help = "add host network device",
.user_print = monitor_user_noop,
.mhandler.cmd_new = do_netdev_add,
.mhandler.cmd = hmp_netdev_add,
},
STEXI
@@ -1024,8 +1051,7 @@ ETEXI
.args_type = "id:s",
.params = "id",
.help = "remove host network device",
.user_print = monitor_user_noop,
.mhandler.cmd_new = do_netdev_del,
.mhandler.cmd = hmp_netdev_del,
},
STEXI
+52
View File
@@ -14,6 +14,8 @@
*/
#include "hmp.h"
#include "net.h"
#include "qemu-option.h"
#include "qemu-timer.h"
#include "qmp-commands.h"
@@ -947,3 +949,53 @@ void hmp_device_del(Monitor *mon, const QDict *qdict)
qmp_device_del(id, &err);
hmp_handle_error(mon, &err);
}
void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
{
Error *errp = NULL;
int paging = qdict_get_try_bool(qdict, "paging", 0);
const char *file = qdict_get_str(qdict, "protocol");
bool has_begin = qdict_haskey(qdict, "begin");
bool has_length = qdict_haskey(qdict, "length");
int64_t begin = 0;
int64_t length = 0;
if (has_begin) {
begin = qdict_get_int(qdict, "begin");
}
if (has_length) {
length = qdict_get_int(qdict, "length");
}
qmp_dump_guest_memory(paging, file, has_begin, begin, has_length, length,
&errp);
hmp_handle_error(mon, &errp);
}
void hmp_netdev_add(Monitor *mon, const QDict *qdict)
{
Error *err = NULL;
QemuOpts *opts;
opts = qemu_opts_from_qdict(qemu_find_opts("netdev"), qdict, &err);
if (error_is_set(&err)) {
goto out;
}
netdev_add(opts, &err);
if (error_is_set(&err)) {
qemu_opts_del(opts);
}
out:
hmp_handle_error(mon, &err);
}
void hmp_netdev_del(Monitor *mon, const QDict *qdict)
{
const char *id = qdict_get_str(qdict, "id");
Error *err = NULL;
qmp_netdev_del(id, &err);
hmp_handle_error(mon, &err);
}
+3
View File
@@ -61,5 +61,8 @@ void hmp_block_job_set_speed(Monitor *mon, const QDict *qdict);
void hmp_block_job_cancel(Monitor *mon, const QDict *qdict);
void hmp_migrate(Monitor *mon, const QDict *qdict);
void hmp_device_del(Monitor *mon, const QDict *qdict);
void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict);
void hmp_netdev_add(Monitor *mon, const QDict *qdict);
void hmp_netdev_del(Monitor *mon, const QDict *qdict);
#endif
+6 -2
View File
@@ -39,6 +39,7 @@ static PCIDevice *qemu_pci_hot_add_nic(Monitor *mon,
const char *devaddr,
const char *opts_str)
{
Error *local_err = NULL;
QemuOpts *opts;
PCIBus *bus;
int ret, devfn;
@@ -60,9 +61,12 @@ static PCIDevice *qemu_pci_hot_add_nic(Monitor *mon,
qemu_opt_set(opts, "type", "nic");
ret = net_client_init(mon, opts, 0);
if (ret < 0)
ret = net_client_init(opts, 0, &local_err);
if (error_is_set(&local_err)) {
qerror_report_err(local_err);
error_free(local_err);
return NULL;
}
if (nd_table[ret].devaddr) {
monitor_printf(mon, "Parameter addr not supported\n");
return NULL;
+5 -2
View File
@@ -554,10 +554,13 @@ void do_info_qdm(Monitor *mon)
int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
{
Error *local_err = NULL;
QemuOpts *opts;
opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict);
if (!opts) {
opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict, &local_err);
if (error_is_set(&local_err)) {
qerror_report_err(local_err);
error_free(local_err);
return -1;
}
if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
+5 -2
View File
@@ -1356,6 +1356,7 @@ static int usb_net_initfn(USBDevice *dev)
static USBDevice *usb_net_init(USBBus *bus, const char *cmdline)
{
Error *local_err = NULL;
USBDevice *dev;
QemuOpts *opts;
int idx;
@@ -1367,8 +1368,10 @@ static USBDevice *usb_net_init(USBBus *bus, const char *cmdline)
qemu_opt_set(opts, "type", "nic");
qemu_opt_set(opts, "model", "usb");
idx = net_client_init(NULL, opts, 0);
if (idx == -1) {
idx = net_client_init(opts, 0, &local_err);
if (error_is_set(&local_err)) {
qerror_report_err(local_err);
error_free(local_err);
return NULL;
}
+1 -1
View File
@@ -584,7 +584,7 @@ static USBDevice *usb_msd_init(USBBus *bus, const char *filename)
/* parse -usbdevice disk: syntax into drive opts */
snprintf(id, sizeof(id), "usb%d", nr++);
opts = qemu_opts_create(qemu_find_opts("drive"), id, 0);
opts = qemu_opts_create(qemu_find_opts("drive"), id, 0, NULL);
p1 = strchr(filename, ':');
if (p1++) {
+1 -1
View File
@@ -66,7 +66,7 @@ int select_watchdog(const char *p)
QLIST_FOREACH(model, &watchdog_list, entry) {
if (strcasecmp(model->wdt_name, p) == 0) {
/* add the device */
opts = qemu_opts_create(qemu_find_opts("device"), NULL, 0);
opts = qemu_opts_create(qemu_find_opts("device"), NULL, 0, NULL);
qemu_opt_set(opts, "driver", p);
return 0;
}
+249
View File
@@ -0,0 +1,249 @@
/*
* QEMU memory mapping
*
* Copyright Fujitsu, Corp. 2011, 2012
*
* Authors:
* Wen Congyang <wency@cn.fujitsu.com>
*
* This work is licensed under the terms of the GNU GPL, version 2. See
* the COPYING file in the top-level directory.
*
*/
#include "cpu.h"
#include "cpu-all.h"
#include "memory_mapping.h"
static void memory_mapping_list_add_mapping_sorted(MemoryMappingList *list,
MemoryMapping *mapping)
{
MemoryMapping *p;
QTAILQ_FOREACH(p, &list->head, next) {
if (p->phys_addr >= mapping->phys_addr) {
QTAILQ_INSERT_BEFORE(p, mapping, next);
return;
}
}
QTAILQ_INSERT_TAIL(&list->head, mapping, next);
}
static void create_new_memory_mapping(MemoryMappingList *list,
target_phys_addr_t phys_addr,
target_phys_addr_t virt_addr,
ram_addr_t length)
{
MemoryMapping *memory_mapping;
memory_mapping = g_malloc(sizeof(MemoryMapping));
memory_mapping->phys_addr = phys_addr;
memory_mapping->virt_addr = virt_addr;
memory_mapping->length = length;
list->last_mapping = memory_mapping;
list->num++;
memory_mapping_list_add_mapping_sorted(list, memory_mapping);
}
static inline bool mapping_contiguous(MemoryMapping *map,
target_phys_addr_t phys_addr,
target_phys_addr_t virt_addr)
{
return phys_addr == map->phys_addr + map->length &&
virt_addr == map->virt_addr + map->length;
}
/*
* [map->phys_addr, map->phys_addr + map->length) and
* [phys_addr, phys_addr + length) have intersection?
*/
static inline bool mapping_have_same_region(MemoryMapping *map,
target_phys_addr_t phys_addr,
ram_addr_t length)
{
return !(phys_addr + length < map->phys_addr ||
phys_addr >= map->phys_addr + map->length);
}
/*
* [map->phys_addr, map->phys_addr + map->length) and
* [phys_addr, phys_addr + length) have intersection. The virtual address in the
* intersection are the same?
*/
static inline bool mapping_conflict(MemoryMapping *map,
target_phys_addr_t phys_addr,
target_phys_addr_t virt_addr)
{
return virt_addr - map->virt_addr != phys_addr - map->phys_addr;
}
/*
* [map->virt_addr, map->virt_addr + map->length) and
* [virt_addr, virt_addr + length) have intersection. And the physical address
* in the intersection are the same.
*/
static inline void mapping_merge(MemoryMapping *map,
target_phys_addr_t virt_addr,
ram_addr_t length)
{
if (virt_addr < map->virt_addr) {
map->length += map->virt_addr - virt_addr;
map->virt_addr = virt_addr;
}
if ((virt_addr + length) >
(map->virt_addr + map->length)) {
map->length = virt_addr + length - map->virt_addr;
}
}
void memory_mapping_list_add_merge_sorted(MemoryMappingList *list,
target_phys_addr_t phys_addr,
target_phys_addr_t virt_addr,
ram_addr_t length)
{
MemoryMapping *memory_mapping, *last_mapping;
if (QTAILQ_EMPTY(&list->head)) {
create_new_memory_mapping(list, phys_addr, virt_addr, length);
return;
}
last_mapping = list->last_mapping;
if (last_mapping) {
if (mapping_contiguous(last_mapping, phys_addr, virt_addr)) {
last_mapping->length += length;
return;
}
}
QTAILQ_FOREACH(memory_mapping, &list->head, next) {
if (mapping_contiguous(memory_mapping, phys_addr, virt_addr)) {
memory_mapping->length += length;
list->last_mapping = memory_mapping;
return;
}
if (phys_addr + length < memory_mapping->phys_addr) {
/* create a new region before memory_mapping */
break;
}
if (mapping_have_same_region(memory_mapping, phys_addr, length)) {
if (mapping_conflict(memory_mapping, phys_addr, virt_addr)) {
continue;
}
/* merge this region into memory_mapping */
mapping_merge(memory_mapping, virt_addr, length);
list->last_mapping = memory_mapping;
return;
}
}
/* this region can not be merged into any existed memory mapping. */
create_new_memory_mapping(list, phys_addr, virt_addr, length);
}
void memory_mapping_list_free(MemoryMappingList *list)
{
MemoryMapping *p, *q;
QTAILQ_FOREACH_SAFE(p, &list->head, next, q) {
QTAILQ_REMOVE(&list->head, p, next);
g_free(p);
}
list->num = 0;
list->last_mapping = NULL;
}
void memory_mapping_list_init(MemoryMappingList *list)
{
list->num = 0;
list->last_mapping = NULL;
QTAILQ_INIT(&list->head);
}
#if defined(CONFIG_HAVE_GET_MEMORY_MAPPING)
static CPUArchState *find_paging_enabled_cpu(CPUArchState *start_cpu)
{
CPUArchState *env;
for (env = start_cpu; env != NULL; env = env->next_cpu) {
if (cpu_paging_enabled(env)) {
return env;
}
}
return NULL;
}
int qemu_get_guest_memory_mapping(MemoryMappingList *list)
{
CPUArchState *env, *first_paging_enabled_cpu;
RAMBlock *block;
ram_addr_t offset, length;
int ret;
first_paging_enabled_cpu = find_paging_enabled_cpu(first_cpu);
if (first_paging_enabled_cpu) {
for (env = first_paging_enabled_cpu; env != NULL; env = env->next_cpu) {
ret = cpu_get_memory_mapping(list, env);
if (ret < 0) {
return -1;
}
}
return 0;
}
/*
* If the guest doesn't use paging, the virtual address is equal to physical
* address.
*/
QLIST_FOREACH(block, &ram_list.blocks, next) {
offset = block->offset;
length = block->length;
create_new_memory_mapping(list, offset, offset, length);
}
return 0;
}
#endif
void qemu_get_guest_simple_memory_mapping(MemoryMappingList *list)
{
RAMBlock *block;
QLIST_FOREACH(block, &ram_list.blocks, next) {
create_new_memory_mapping(list, block->offset, 0, block->length);
}
}
void memory_mapping_filter(MemoryMappingList *list, int64_t begin,
int64_t length)
{
MemoryMapping *cur, *next;
QTAILQ_FOREACH_SAFE(cur, &list->head, next, next) {
if (cur->phys_addr >= begin + length ||
cur->phys_addr + cur->length <= begin) {
QTAILQ_REMOVE(&list->head, cur, next);
list->num--;
continue;
}
if (cur->phys_addr < begin) {
cur->length -= begin - cur->phys_addr;
if (cur->virt_addr) {
cur->virt_addr += begin - cur->phys_addr;
}
cur->phys_addr = begin;
}
if (cur->phys_addr + cur->length > begin + length) {
cur->length -= cur->phys_addr + cur->length - begin - length;
}
}
}

Some files were not shown because too many files have changed in this diff Show More