summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2010-04-09 16:35:14 +0200
committerAlexander Larsson <alexl@redhat.com>2010-04-09 16:51:52 +0200
commit34fb3f680618b8735322462bd692fb2923ea3027 (patch)
tree6d548b51eb13370ad0493bcb48a3aae9ef405a94 /server
parenta3700a1bfbb3006b83d8513a5e4c598d6443f2c3 (diff)
downloadspice-34fb3f680618b8735322462bd692fb2923ea3027.tar.gz
spice-34fb3f680618b8735322462bd692fb2923ea3027.tar.xz
spice-34fb3f680618b8735322462bd692fb2923ea3027.zip
Split out the memslot stuff from red_worker.c to its own files
This is required so that we can have code in other files that does address validation.
Diffstat (limited to 'server')
-rw-r--r--server/Makefile.am2
-rw-r--r--server/red_memslots.c210
-rw-r--r--server/red_memslots.h79
-rw-r--r--server/red_worker.c403
4 files changed, 405 insertions, 289 deletions
diff --git a/server/Makefile.am b/server/Makefile.am
index 5c4524a5..f1211689 100644
--- a/server/Makefile.am
+++ b/server/Makefile.am
@@ -74,6 +74,8 @@ libspice_server_la_SOURCES = \
red_common.h \
red_dispatcher.c \
red_dispatcher.h \
+ red_memslots.c \
+ red_memslots.h \
reds.c \
reds.h \
stat.h \
diff --git a/server/red_memslots.c b/server/red_memslots.c
new file mode 100644
index 00000000..71759303
--- /dev/null
+++ b/server/red_memslots.c
@@ -0,0 +1,210 @@
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2009,2010 Red Hat, Inc.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "red_common.h"
+#include "red_memslots.h"
+
+static unsigned long __get_clean_virt(RedMemSlotInfo *info, unsigned long addr)
+{
+ return addr & info->memslot_clean_virt_mask;
+}
+
+static void print_memslots(RedMemSlotInfo *info)
+{
+ int i;
+ int x;
+
+ for (i = 0; i < info->num_memslots_groups; ++i) {
+ for (x = 0; x < info->num_memslots; ++x) {
+ if (!info->mem_slots[i][x].virt_start_addr &&
+ !info->mem_slots[i][x].virt_end_addr) {
+ continue;
+ }
+ printf("id %d, group %d, virt start %lx, virt end %lx, generation %u, delta %lx\n",
+ x, i, info->mem_slots[i][x].virt_start_addr,
+ info->mem_slots[i][x].virt_end_addr, info->mem_slots[i][x].generation,
+ info->mem_slots[i][x].address_delta);
+ }
+ }
+}
+
+unsigned long get_virt_delta(RedMemSlotInfo *info, unsigned long addr, int group_id)
+{
+ MemSlot *slot;
+ int slot_id;
+ int generation;
+
+ if (group_id > info->num_memslots_groups) {
+ PANIC("group_id %d too big", group_id);
+ }
+
+ slot_id = get_memslot_id(info, addr);
+ if (slot_id > info->num_memslots) {
+ PANIC("slod_id %d too big", slot_id);
+ }
+
+ slot = &info->mem_slots[group_id][slot_id];
+
+ generation = get_generation(info, addr);
+ if (generation != slot->generation) {
+ PANIC("address generation is not valid");
+ }
+
+ return (slot->address_delta - (addr - __get_clean_virt(info, addr)));
+}
+
+void validate_virt(RedMemSlotInfo *info, unsigned long virt, int slot_id,
+ uint32_t add_size, uint32_t group_id)
+{
+ MemSlot *slot;
+
+ slot = &info->mem_slots[group_id][slot_id];
+ if ((virt + add_size) < virt) {
+ PANIC("virtual address overlap");
+ }
+
+ if (virt < slot->virt_start_addr || (virt + add_size) > slot->virt_end_addr) {
+ print_memslots(info);
+ PANIC("virtual address out of range 0x%lx 0x%lx %d %d 0x%lx 0x%lx 0x%lx", virt,
+ slot->address_delta, slot_id, group_id, slot->virt_start_addr, slot->virt_end_addr,
+ virt + add_size);
+ }
+}
+
+unsigned long get_virt(RedMemSlotInfo *info, unsigned long addr, uint32_t add_size,
+ int group_id)
+{
+ int slot_id;
+ int generation;
+ unsigned long h_virt;
+
+ MemSlot *slot;
+
+ if (group_id > info->num_memslots_groups) {
+ PANIC("group_id too big");
+ }
+
+ slot_id = get_memslot_id(info, addr);
+ if (slot_id > info->num_memslots) {
+ PANIC("slot_id too big");
+ }
+
+ slot = &info->mem_slots[group_id][slot_id];
+
+ generation = get_generation(info, addr);
+ if (generation != slot->generation) {
+ print_memslots(info);
+ PANIC("address generation is not valid, group_id %d, slot_id %d, gen %d, slot_gen %d\n",
+ group_id, slot_id, generation, slot->generation);
+ }
+
+ h_virt = __get_clean_virt(info, addr);
+ h_virt += slot->address_delta;
+
+ validate_virt(info, h_virt, slot_id, add_size, group_id);
+
+ return h_virt;
+}
+
+void *cb_get_virt(void *opaque, unsigned long addr,
+ uint32_t add_size, uint32_t group_id)
+{
+ return (void *)get_virt((RedMemSlotInfo *)opaque, addr, add_size, group_id);
+}
+
+void cb_validate_virt(void *opaque,
+ unsigned long virt, unsigned long from_addr,
+ uint32_t add_size, uint32_t group_id)
+{
+ int slot_id = get_memslot_id((RedMemSlotInfo *)opaque, from_addr);
+ validate_virt((RedMemSlotInfo *)opaque, virt, slot_id, add_size, group_id);
+}
+
+void *validate_chunk (RedMemSlotInfo *info, QXLPHYSICAL data, uint32_t group_id, uint32_t *data_size_out, QXLPHYSICAL *next_out)
+{
+ QXLDataChunk *chunk;
+ uint32_t data_size;
+
+ chunk = (QXLDataChunk *)get_virt(info, data, sizeof(QXLDataChunk), group_id);
+ data_size = chunk->data_size;
+ validate_virt(info, (unsigned long)chunk->data, get_memslot_id(info, data),
+ data_size, group_id);
+ *next_out = chunk->next_chunk;
+
+ return chunk->data;
+}
+
+void red_memslot_info_init(RedMemSlotInfo *info,
+ uint32_t num_groups, uint32_t num_slots,
+ uint8_t generation_bits,
+ uint8_t id_bits,
+ uint8_t internal_groupslot_id)
+{
+ uint32_t i;
+
+ ASSERT(num_slots > 0);
+ ASSERT(num_groups > 0);
+
+ info->num_memslots_groups = num_groups;
+ info->num_memslots = num_slots;
+ info->generation_bits = generation_bits;
+ info->mem_slot_bits = id_bits;
+ info->internal_groupslot_id = internal_groupslot_id;
+
+ info->mem_slots = spice_new(MemSlot *, num_groups);
+
+ for (i = 0; i < num_groups; ++i) {
+ info->mem_slots[i] = spice_new0(MemSlot, num_slots);
+ }
+
+ info->memslot_id_shift = 64 - info->mem_slot_bits;
+ info->memslot_gen_shift = 64 - (info->mem_slot_bits + info->generation_bits);
+ info->memslot_gen_mask = ~((unsigned long)-1 << info->generation_bits);
+ info->memslot_clean_virt_mask = (((unsigned long)(-1)) >>
+ (info->mem_slot_bits + info->generation_bits));
+}
+
+void red_memslot_info_add_slot(RedMemSlotInfo *info, uint32_t slot_group_id, uint32_t slot_id,
+ uint64_t addr_delta, unsigned long virt_start, unsigned long virt_end,
+ uint32_t generation)
+{
+ ASSERT(info->num_memslots_groups > slot_group_id);
+ ASSERT(info->num_memslots > slot_id);
+
+ info->mem_slots[slot_group_id][slot_id].address_delta = addr_delta;
+ info->mem_slots[slot_group_id][slot_id].virt_start_addr = virt_start;
+ info->mem_slots[slot_group_id][slot_id].virt_end_addr = virt_end;
+ info->mem_slots[slot_group_id][slot_id].generation = generation;
+}
+
+void red_memslot_info_del_slot(RedMemSlotInfo *info, uint32_t slot_group_id, uint32_t slot_id)
+{
+ ASSERT(info->num_memslots_groups > slot_group_id);
+ ASSERT(info->num_memslots > slot_id);
+
+ info->mem_slots[slot_group_id][slot_id].virt_start_addr = 0;
+ info->mem_slots[slot_group_id][slot_id].virt_end_addr = 0;
+}
+
+void red_memslot_info_reset(RedMemSlotInfo *info)
+{
+ uint32_t i;
+ for (i = 0; i < info->num_memslots_groups; ++i) {
+ memset(info->mem_slots[i], 0, sizeof(MemSlot) * info->num_memslots);
+ }
+}
diff --git a/server/red_memslots.h b/server/red_memslots.h
new file mode 100644
index 00000000..229e5cc5
--- /dev/null
+++ b/server/red_memslots.h
@@ -0,0 +1,79 @@
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2009,2010 Red Hat, Inc.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _H_REDMEMSLOTS
+#define _H_REDMEMSLOTS
+
+#include "red_common.h"
+
+#include <spice/qxl_dev.h>
+
+typedef struct MemSlot {
+ int generation;
+ unsigned long virt_start_addr;
+ unsigned long virt_end_addr;
+ long address_delta;
+} MemSlot;
+
+typedef struct RedMemSlotInfo {
+ MemSlot **mem_slots;
+ uint32_t num_memslots_groups;
+ uint32_t num_memslots;
+ uint8_t mem_slot_bits;
+ uint8_t generation_bits;
+ uint8_t memslot_id_shift;
+ uint8_t memslot_gen_shift;
+ uint8_t internal_groupslot_id;
+ unsigned long memslot_gen_mask;
+ unsigned long memslot_clean_virt_mask;
+} RedMemSlotInfo;
+
+static inline int get_memslot_id(RedMemSlotInfo *info, unsigned long addr)
+{
+ return addr >> info->memslot_id_shift;
+}
+
+static inline int get_generation(RedMemSlotInfo *info, unsigned long addr)
+{
+ return (addr >> info->memslot_gen_shift) & info->memslot_gen_mask;
+}
+
+unsigned long get_virt_delta(RedMemSlotInfo *info, unsigned long addr, int group_id);
+void validate_virt(RedMemSlotInfo *info, unsigned long virt, int slot_id,
+ uint32_t add_size, uint32_t group_id);
+unsigned long get_virt(RedMemSlotInfo *info, unsigned long addr, uint32_t add_size,
+ int group_id);
+
+void *validate_chunk (RedMemSlotInfo *info, QXLPHYSICAL data, uint32_t group_id, uint32_t *data_size_out, QXLPHYSICAL *next_out);
+void *cb_get_virt(void *opaque, unsigned long addr,
+ uint32_t add_size, uint32_t group_id);
+void cb_validate_virt(void *opaque,
+ unsigned long virt, unsigned long from_addr,
+ uint32_t add_size, uint32_t group_id);
+void red_memslot_info_init(RedMemSlotInfo *info,
+ uint32_t num_groups, uint32_t num_slots,
+ uint8_t generation_bits,
+ uint8_t id_bits,
+ uint8_t internal_groupslot_id);
+void red_memslot_info_add_slot(RedMemSlotInfo *info, uint32_t slot_group_id, uint32_t slot_id,
+ uint64_t addr_delta, unsigned long virt_start, unsigned long virt_end,
+ uint32_t generation);
+void red_memslot_info_del_slot(RedMemSlotInfo *info, uint32_t slot_group_id, uint32_t slot_id);
+void red_memslot_info_reset(RedMemSlotInfo *info);
+
+#endif
diff --git a/server/red_worker.c b/server/red_worker.c
index 6fdc4fee..40781452 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -47,6 +47,7 @@
#include "reds.h"
#include "ring.h"
#include "mjpeg_encoder.h"
+#include "red_memslots.h"
//#define COMPRESS_STAT
//#define DUMP_BITMAP
@@ -907,13 +908,6 @@ typedef struct ItemTrace {
#endif
-typedef struct MemSlot {
- int generation;
- unsigned long virt_start_addr;
- unsigned long virt_end_addr;
- long address_delta;
-} MemSlot;
-
#define NUM_DRAWABLES 1000
#define NUM_CURSORS 100
@@ -960,16 +954,7 @@ typedef struct RedWorker {
_CursorItem cursor_items[NUM_CURSORS];
_CursorItem *free_cursor_items;
- MemSlot **mem_slots;
- uint32_t num_memslots_groups;
- uint32_t num_memslots;
- uint8_t mem_slot_bits;
- uint8_t generation_bits;
- uint8_t memslot_id_shift;
- uint8_t memslot_gen_shift;
- uint8_t internal_groupslot_id;
- unsigned long memslot_gen_mask;
- unsigned long memslot_clean_virt_mask;
+ RedMemSlotInfo mem_slots;
uint32_t preload_group_id;
@@ -1115,135 +1100,10 @@ static inline void validate_surface(RedWorker *worker, uint32_t surface_id)
PANIC_ON(!worker->surfaces[surface_id].context.canvas);
}
-static inline int get_memslot_id(RedWorker *worker, unsigned long addr)
-{
- return addr >> worker->memslot_id_shift;
-}
-
-static inline int get_generation(RedWorker *worker, unsigned long addr)
-{
-
- return (addr >> worker->memslot_gen_shift) & worker->memslot_gen_mask;
-}
-
-static inline unsigned long __get_clean_virt(RedWorker *worker, unsigned long addr)
-{
- return addr & worker->memslot_clean_virt_mask;
-}
-
-static inline void print_memslots(RedWorker *worker)
-{
- int i;
- int x;
-
- for (i = 0; i < worker->num_memslots_groups; ++i) {
- for (x = 0; x < worker->num_memslots; ++x) {
- if (!worker->mem_slots[i][x].virt_start_addr &&
- !worker->mem_slots[i][x].virt_end_addr) {
- continue;
- }
- printf("id %d, group %d, virt start %lx, virt end %lx, generation %u, delta %lx\n",
- x, i, worker->mem_slots[i][x].virt_start_addr,
- worker->mem_slots[i][x].virt_end_addr, worker->mem_slots[i][x].generation,
- worker->mem_slots[i][x].address_delta);
- }
- }
-}
-
-static inline unsigned long get_virt_delta(RedWorker *worker, unsigned long addr, int group_id)
-{
- MemSlot *slot;
- int slot_id;
- int generation;
-
- if (group_id > worker->num_memslots_groups) {
- PANIC("group_id %d too big", group_id);
- }
-
- slot_id = get_memslot_id(worker, addr);
- if (slot_id > worker->num_memslots) {
- PANIC("slod_id %d too big", slot_id);
- }
-
- slot = &worker->mem_slots[group_id][slot_id];
-
- generation = get_generation(worker, addr);
- if (generation != slot->generation) {
- PANIC("address generation is not valid");
- }
-
- return (slot->address_delta - (addr - __get_clean_virt(worker, addr)));
-}
-
-static inline void validate_virt(RedWorker *worker, unsigned long virt, int slot_id,
- uint32_t add_size, uint32_t group_id)
-{
- MemSlot *slot;
-
- slot = &worker->mem_slots[group_id][slot_id];
- if ((virt + add_size) < virt) {
- PANIC("virtual address overlap");
- }
-
- if (virt < slot->virt_start_addr || (virt + add_size) > slot->virt_end_addr) {
- print_memslots(worker);
- PANIC("virtual address out of range 0x%lx 0x%lx %d %d 0x%lx 0x%lx 0x%lx", virt,
- slot->address_delta, slot_id, group_id, slot->virt_start_addr, slot->virt_end_addr,
- virt + add_size);
- }
-}
-
-static inline unsigned long get_virt(RedWorker *worker, unsigned long addr, uint32_t add_size,
- int group_id)
-{
- int slot_id;
- int generation;
- unsigned long h_virt;
-
- MemSlot *slot;
-
- if (group_id > worker->num_memslots_groups) {
- PANIC("group_id too big");
- }
-
- slot_id = get_memslot_id(worker, addr);
- if (slot_id > worker->num_memslots) {
- PANIC("slot_id too big");
- }
-
- slot = &worker->mem_slots[group_id][slot_id];
-
- generation = get_generation(worker, addr);
- if (generation != slot->generation) {
- print_memslots(worker);
- PANIC("address generation is not valid, group_id %d, slot_id %d, gen %d, slot_gen %d\n",
- group_id, slot_id, generation, slot->generation);
- }
-
- h_virt = __get_clean_virt(worker, addr);
- h_virt += slot->address_delta;
-
- validate_virt(worker, h_virt, slot_id, add_size, group_id);
-
- return h_virt;
-}
-
-static void *cb_get_virt(void *opaque, unsigned long addr, uint32_t add_size, uint32_t group_id)
-{
- return (void *)get_virt((RedWorker *)opaque, addr, add_size, group_id);
-}
-
-static void cb_validate_virt(void *opaque, unsigned long virt, unsigned long from_addr,
- uint32_t add_size, uint32_t group_id)
-{
- int slot_id = get_memslot_id((RedWorker *)opaque, from_addr);
- validate_virt((RedWorker *)opaque, virt, slot_id, add_size, group_id);
-}
-
static void *op_get_virt_preload_group(SpiceVirtMapping *mapping, unsigned long addr, uint32_t add_size)
{
RedWorker *worker = SPICE_CONTAINEROF(mapping, RedWorker, preload_group_virt_mapping);
- return (void *)get_virt(worker, addr, add_size,
+ return (void *)get_virt(&worker->mem_slots, addr, add_size,
worker->preload_group_id);
}
@@ -1251,8 +1111,8 @@ static void op_validate_virt_preload_group(SpiceVirtMapping *mapping, unsigned l
unsigned long from_addr, uint32_t add_size)
{
RedWorker *worker = SPICE_CONTAINEROF(mapping, RedWorker, preload_group_virt_mapping);
- int slot_id = get_memslot_id(worker, from_addr);
- validate_virt(worker, virt, slot_id, add_size,
+ int slot_id = get_memslot_id(&worker->mem_slots, from_addr);
+ validate_virt(&worker->mem_slots, virt, slot_id, add_size,
worker->preload_group_id);
}
@@ -2363,8 +2223,8 @@ static int is_equal_path(RedWorker *worker, SPICE_ADDRESS p1, SPICE_ADDRESS p2,
ASSERT(p1 && p2);
- path1 = (QXLPath *)get_virt(worker, p1, sizeof(QXLPath), group_id1);
- path2 = (QXLPath *)get_virt(worker, p2, sizeof(QXLPath), group_id2);
+ path1 = (QXLPath *)get_virt(&worker->mem_slots, p1, sizeof(QXLPath), group_id1);
+ path2 = (QXLPath *)get_virt(&worker->mem_slots, p2, sizeof(QXLPath), group_id2);
if ((size = path1->data_size) != path2->data_size) {
return FALSE;
@@ -2390,7 +2250,7 @@ static int is_equal_path(RedWorker *worker, SPICE_ADDRESS p1, SPICE_ADDRESS p2,
}
if ((size1 -= now) == 0) {
ASSERT(chunk1->next_chunk)
- chunk1 = (QXLDataChunk *)get_virt(worker, chunk1->next_chunk, sizeof(QXLDataChunk),
+ chunk1 = (QXLDataChunk *)get_virt(&worker->mem_slots, chunk1->next_chunk, sizeof(QXLDataChunk),
group_id1);
size1 = chunk1->data_size;
data1 = chunk1->data;
@@ -2400,7 +2260,7 @@ static int is_equal_path(RedWorker *worker, SPICE_ADDRESS p1, SPICE_ADDRESS p2,
if ((size2 -= now) == 0) {
ASSERT(chunk2->next_chunk)
- chunk2 = (QXLDataChunk *)get_virt(worker, chunk2->next_chunk, sizeof(QXLDataChunk),
+ chunk2 = (QXLDataChunk *)get_virt(&worker->mem_slots, chunk2->next_chunk, sizeof(QXLDataChunk),
group_id2);
size2 = chunk2->data_size;
data2 = chunk2->data;
@@ -2854,7 +2714,7 @@ static void red_create_stream(RedWorker *worker, Drawable *drawable)
#endif
stream->refs = 1;
stream->bit_rate = get_bit_rate(stream_width, stream_height);
- QXLImage *qxl_image = (QXLImage *)get_virt(worker, drawable->qxl_drawable->u.copy.src_bitmap,
+ QXLImage *qxl_image = (QXLImage *)get_virt(&worker->mem_slots, drawable->qxl_drawable->u.copy.src_bitmap,
sizeof(QXLImage), drawable->group_id);
stream->top_down = !!(qxl_image->bitmap.flags & SPICE_BITMAP_FLAGS_TOP_DOWN);
drawable->stream = stream;
@@ -2941,7 +2801,7 @@ static inline int __red_is_next_stream_frame(RedWorker *worker,
}
if (stream) {
- QXLImage *qxl_image = (QXLImage *)get_virt(worker, qxl_drawable->u.copy.src_bitmap,
+ QXLImage *qxl_image = (QXLImage *)get_virt(&worker->mem_slots, qxl_drawable->u.copy.src_bitmap,
sizeof(QXLImage), candidate->group_id);
if (stream->top_down != !!(qxl_image->bitmap.flags & SPICE_BITMAP_FLAGS_TOP_DOWN)) {
return FALSE;
@@ -2996,7 +2856,7 @@ static inline int red_is_next_stream_frame(RedWorker *worker, Drawable *candidat
return FALSE;
}
- qxl_image = (QXLImage *)get_virt(worker, qxl_drawable->u.copy.src_bitmap, sizeof(QXLImage),
+ qxl_image = (QXLImage *)get_virt(&worker->mem_slots, qxl_drawable->u.copy.src_bitmap, sizeof(QXLImage),
candidate->group_id);
if (qxl_image->descriptor.type != SPICE_IMAGE_TYPE_BITMAP) {
@@ -3074,7 +2934,7 @@ static inline void red_update_copy_graduality(RedWorker* worker, Drawable *drawa
return; // already set
}
- qxl_image = (QXLImage *)get_virt(worker, drawable->qxl_drawable->u.copy.src_bitmap,
+ qxl_image = (QXLImage *)get_virt(&worker->mem_slots, drawable->qxl_drawable->u.copy.src_bitmap,
sizeof(QXLImage), drawable->group_id);
if (!BITMAP_FMT_IS_RGB[qxl_image->bitmap.format] || _stride_is_extra(&qxl_image->bitmap) ||
@@ -3513,15 +3373,11 @@ static inline int red_current_add(RedWorker *worker, Ring *ring, Drawable *drawa
static void add_clip_rects(RedWorker *worker, QRegion *rgn, QXLPHYSICAL data, uint32_t group_id)
{
while (data) {
- QXLDataChunk *chunk;
SpiceRect *now;
SpiceRect *end;
uint32_t data_size;
- chunk = (QXLDataChunk *)get_virt(worker, data, sizeof(QXLDataChunk), group_id);
- data_size = chunk->data_size;
- validate_virt(worker, (unsigned long)chunk->data, get_memslot_id(worker, data), data_size,
- group_id);
- now = (SpiceRect *)chunk->data;
+
+ now = (SpiceRect *)validate_chunk(&worker->mem_slots, data, group_id, &data_size, &data);
end = now + data_size / sizeof(SpiceRect);
for (; now < end; now++) {
@@ -3534,7 +3390,6 @@ static void add_clip_rects(RedWorker *worker, QRegion *rgn, QXLPHYSICAL data, ui
#endif
region_add(rgn, r);
}
- data = chunk->next_chunk;
}
}
@@ -3624,7 +3479,7 @@ static inline void red_update_streamable(RedWorker *worker, Drawable *drawable,
return;
}
- qxl_image = (QXLImage *)get_virt(worker, qxl_drawable->u.copy.src_bitmap, sizeof(QXLImage),
+ qxl_image = (QXLImage *)get_virt(&worker->mem_slots, qxl_drawable->u.copy.src_bitmap, sizeof(QXLImage),
drawable->group_id);
if (qxl_image->descriptor.type != SPICE_IMAGE_TYPE_BITMAP) {
return;
@@ -3964,7 +3819,7 @@ static inline void red_process_surface(RedWorker *worker, QXLSurfaceCmd *surface
int32_t stride = surface->u.surface_create.stride;
QXLReleaseInfoExt release_info_ext;
- data = (uint8_t *)get_virt(worker, saved_data, height * abs(stride), group_id);
+ data = (uint8_t *)get_virt(&worker->mem_slots, saved_data, height * abs(stride), group_id);
if (stride < 0) {
data -= (int32_t)(stride * (height - 1));
}
@@ -3995,10 +3850,10 @@ static void localize_path(RedWorker *worker, QXLPHYSICAL *in_path, uint32_t grou
uint8_t *data;
uint32_t data_size;
QXLDataChunk *chunk;
- int memslot_id = get_memslot_id(worker, *in_path);
+ int memslot_id = get_memslot_id(&worker->mem_slots, *in_path);
ASSERT(in_path && *in_path);
- path = (QXLPath *)get_virt(worker, *in_path, sizeof(QXLPath), group_id);
+ path = (QXLPath *)get_virt(&worker->mem_slots, *in_path, sizeof(QXLPath), group_id);
data = spice_malloc_n_m(1, path->data_size, sizeof(uint32_t));
*in_path = (QXLPHYSICAL)data;
*(uint32_t *)data = path->data_size;
@@ -4006,10 +3861,10 @@ static void localize_path(RedWorker *worker, QXLPHYSICAL *in_path, uint32_t grou
chunk = &path->chunk;
do {
data_size = chunk->data_size;
- validate_virt(worker, (unsigned long)chunk->data, memslot_id, data_size, group_id);
+ validate_virt(&worker->mem_slots, (unsigned long)chunk->data, memslot_id, data_size, group_id);
memcpy(data, chunk->data, data_size);
data += data_size;
- chunk = chunk->next_chunk ? (QXLDataChunk *)get_virt(worker, chunk->next_chunk,
+ chunk = chunk->next_chunk ? (QXLDataChunk *)get_virt(&worker->mem_slots, chunk->next_chunk,
sizeof(QXLDataChunk), group_id) : NULL;
} while (chunk);
}
@@ -4023,12 +3878,12 @@ static void unlocalize_path(QXLPHYSICAL *path)
static void localize_str(RedWorker *worker, QXLPHYSICAL *in_str, uint32_t group_id)
{
- QXLString *qxl_str = (QXLString *)get_virt(worker, *in_str, sizeof(QXLString), group_id);
+ QXLString *qxl_str = (QXLString *)get_virt(&worker->mem_slots, *in_str, sizeof(QXLString), group_id);
QXLDataChunk *chunk;
SpiceString *str;
uint8_t *dest;
uint32_t data_size;
- int memslot_id = get_memslot_id(worker, *in_str);
+ int memslot_id = get_memslot_id(&worker->mem_slots, *in_str);
ASSERT(in_str);
str = spice_malloc_n_m(1, qxl_str->data_size, sizeof(uint32_t));
@@ -4041,15 +3896,15 @@ static void localize_str(RedWorker *worker, QXLPHYSICAL *in_str, uint32_t group_
QXLPHYSICAL next_chunk;
data_size = chunk->data_size;
- validate_virt(worker, (unsigned long)chunk->data, memslot_id, data_size, group_id);
+ validate_virt(&worker->mem_slots, (unsigned long)chunk->data, memslot_id, data_size, group_id);
memcpy(dest, chunk->data, data_size);
if (!chunk->next_chunk) {
return;
}
dest += data_size;
next_chunk = chunk->next_chunk;
- memslot_id = get_memslot_id(worker, next_chunk);
- chunk = (QXLDataChunk *)get_virt(worker, next_chunk, sizeof(QXLDataChunk), group_id);
+ memslot_id = get_memslot_id(&worker->mem_slots, next_chunk);
+ chunk = (QXLDataChunk *)get_virt(&worker->mem_slots, next_chunk, sizeof(QXLDataChunk), group_id);
}
}
@@ -4068,10 +3923,10 @@ static void localize_clip(RedWorker *worker, SpiceClip *clip, uint32_t group_id)
case SPICE_CLIP_TYPE_RECTS: {
QXLClipRects *clip_rects;
QXLDataChunk *chunk;
- int memslot_id = get_memslot_id(worker, clip->data);
+ int memslot_id = get_memslot_id(&worker->mem_slots, clip->data);
uint8_t *data;
uint32_t data_size;
- clip_rects = (QXLClipRects *)get_virt(worker, clip->data, sizeof(QXLClipRects), group_id);
+ clip_rects = (QXLClipRects *)get_virt(&worker->mem_slots, clip->data, sizeof(QXLClipRects), group_id);
chunk = &clip_rects->chunk;
ASSERT(clip->data);
data = spice_malloc_n_m(clip_rects->num_rects, sizeof(SpiceRect), sizeof(uint32_t));
@@ -4080,10 +3935,10 @@ static void localize_clip(RedWorker *worker, SpiceClip *clip, uint32_t group_id)
data += sizeof(uint32_t);
do {
data_size = chunk->data_size;
- validate_virt(worker, (unsigned long)chunk->data, memslot_id, data_size, group_id);
+ validate_virt(&worker->mem_slots, (unsigned long)chunk->data, memslot_id, data_size, group_id);
memcpy(data, chunk->data, data_size);
data += data_size;
- chunk = chunk->next_chunk ? (QXLDataChunk *)get_virt(worker, chunk->next_chunk,
+ chunk = chunk->next_chunk ? (QXLDataChunk *)get_virt(&worker->mem_slots, chunk->next_chunk,
sizeof(QXLDataChunk), group_id) :
NULL;
} while (chunk);
@@ -4280,7 +4135,7 @@ static void localize_bitmap(RedWorker *worker, QXLPHYSICAL *in_bitmap, uint32_t
QXLImage *local_image;
ASSERT(in_bitmap && *in_bitmap);
- image = (QXLImage *)get_virt(worker, *in_bitmap, sizeof(QXLImage), group_id);
+ image = (QXLImage *)get_virt(&worker->mem_slots, *in_bitmap, sizeof(QXLImage), group_id);
local_image = (QXLImage *)alloc_local_image(worker);
*local_image = *image;
*in_bitmap = (QXLPHYSICAL)local_image;
@@ -4307,7 +4162,7 @@ static void localize_bitmap(RedWorker *worker, QXLPHYSICAL *in_bitmap, uint32_t
}
case SPICE_IMAGE_TYPE_BITMAP:
if (image->bitmap.flags & QXL_BITMAP_DIRECT) {
- local_image->bitmap.data = (QXLPHYSICAL)get_virt(worker, image->bitmap.data,
+ local_image->bitmap.data = (QXLPHYSICAL)get_virt(&worker->mem_slots, image->bitmap.data,
image->bitmap.stride * image->bitmap.y,
group_id);
} else {
@@ -4323,9 +4178,9 @@ static void localize_bitmap(RedWorker *worker, QXLPHYSICAL *in_bitmap, uint32_t
int cp_size;
ASSERT(src_data);
- chunk = (QXLDataChunk *)get_virt(worker, src_data, sizeof(QXLDataChunk), group_id);
+ chunk = (QXLDataChunk *)get_virt(&worker->mem_slots, src_data, sizeof(QXLDataChunk), group_id);
data_size = chunk->data_size;
- validate_virt(worker, (unsigned long)chunk->data, get_memslot_id(worker, src_data),
+ validate_virt(&worker->mem_slots, (unsigned long)chunk->data, get_memslot_id(&worker->mem_slots, src_data),
data_size, group_id);
cp_size = MIN(data_size, size);
memcpy(data, chunk->data, cp_size);
@@ -4341,14 +4196,14 @@ static void localize_bitmap(RedWorker *worker, QXLPHYSICAL *in_bitmap, uint32_t
SpicePalette *tmp_palette;
SpicePalette *shadow_palette;
- int slot_id = get_memslot_id(worker, local_image->bitmap.palette);
- tmp_palette = (SpicePalette *)get_virt(worker, local_image->bitmap.palette,
+ int slot_id = get_memslot_id(&worker->mem_slots, local_image->bitmap.palette);
+ tmp_palette = (SpicePalette *)get_virt(&worker->mem_slots, local_image->bitmap.palette,
sizeof(SpicePalette), group_id);
num_ents = tmp_palette->num_ents;
ents = tmp_palette->ents;
- validate_virt(worker, (unsigned long)ents, slot_id, (num_ents * sizeof(uint32_t)),
+ validate_virt(&worker->mem_slots, (unsigned long)ents, slot_id, (num_ents * sizeof(uint32_t)),
group_id);
shadow_palette = (SpicePalette *)spice_malloc_n_m(num_ents, sizeof(uint32_t),sizeof(SpicePalette) + sizeof(QXLPHYSICAL));
@@ -4430,7 +4285,7 @@ static void localize_attr(RedWorker *worker, SpiceLineAttr *attr, uint32_t group
uint8_t *data;
ASSERT(attr->style);
- buf = (uint8_t *)get_virt(worker, attr->style, attr->style_nseg * sizeof(uint32_t),
+ buf = (uint8_t *)get_virt(&worker->mem_slots, attr->style, attr->style_nseg * sizeof(uint32_t),
group_id);
data = spice_malloc_n(attr->style_nseg, sizeof(uint32_t));
memcpy(data, buf, attr->style_nseg * sizeof(uint32_t));
@@ -4910,7 +4765,7 @@ static int red_process_cursor(RedWorker *worker, uint32_t max_pipe_size)
worker->repoll_cursor_ring = 0;
switch (ext_cmd.cmd.type) {
case QXL_CMD_CURSOR: {
- QXLCursorCmd *cursor_cmd = (QXLCursorCmd *)get_virt(worker, ext_cmd.cmd.data,
+ QXLCursorCmd *cursor_cmd = (QXLCursorCmd *)get_virt(&worker->mem_slots, ext_cmd.cmd.data,
sizeof(QXLCursorCmd),
ext_cmd.group_id);
qxl_process_cursor(worker, cursor_cmd, ext_cmd.group_id);
@@ -4948,7 +4803,7 @@ static int red_process_commands(RedWorker *worker, uint32_t max_pipe_size)
worker->repoll_cmd_ring = 0;
switch (ext_cmd.cmd.type) {
case QXL_CMD_DRAW: {
- QXLDrawable *drawable = (QXLDrawable *)get_virt(worker, ext_cmd.cmd.data,
+ QXLDrawable *drawable = (QXLDrawable *)get_virt(&worker->mem_slots, ext_cmd.cmd.data,
sizeof(QXLDrawable), ext_cmd.group_id);
red_process_drawable(worker, drawable, ext_cmd.group_id);
break;
@@ -4956,7 +4811,7 @@ static int red_process_commands(RedWorker *worker, uint32_t max_pipe_size)
case QXL_CMD_UPDATE: {
int surface_id;
QXLReleaseInfoExt release_info_ext;
- QXLUpdateCmd *draw_cmd = (QXLUpdateCmd *)get_virt(worker, ext_cmd.cmd.data,
+ QXLUpdateCmd *draw_cmd = (QXLUpdateCmd *)get_virt(&worker->mem_slots, ext_cmd.cmd.data,
sizeof(QXLUpdateCmd),
ext_cmd.group_id);
surface_id = draw_cmd->surface_id;
@@ -4970,7 +4825,7 @@ static int red_process_commands(RedWorker *worker, uint32_t max_pipe_size)
}
case QXL_CMD_MESSAGE: {
QXLReleaseInfoExt release_info_ext;
- QXLMessage *message = (QXLMessage *)get_virt(worker, ext_cmd.cmd.data,
+ QXLMessage *message = (QXLMessage *)get_virt(&worker->mem_slots, ext_cmd.cmd.data,
sizeof(QXLMessage), ext_cmd.group_id);
red_printf("MESSAGE: %s", message->data);
release_info_ext.group_id = ext_cmd.group_id;
@@ -4979,7 +4834,7 @@ static int red_process_commands(RedWorker *worker, uint32_t max_pipe_size)
break;
}
case QXL_CMD_SURFACE: {
- QXLSurfaceCmd *surface = (QXLSurfaceCmd *)get_virt(worker, ext_cmd.cmd.data,
+ QXLSurfaceCmd *surface = (QXLSurfaceCmd *)get_virt(&worker->mem_slots, ext_cmd.cmd.data,
sizeof(QXLSurfaceCmd), ext_cmd.group_id);
red_process_surface(worker, surface, ext_cmd.group_id);
break;
@@ -5088,8 +4943,8 @@ static void fill_path(DisplayChannel *display_channel, QXLPHYSICAL *in_path, uin
int memslot_id;
worker = channel->worker;
ASSERT(in_path && *in_path);
- memslot_id = get_memslot_id(worker, *in_path);
- QXLPath *path = (QXLPath *)get_virt(worker, *in_path, sizeof(QXLPath), group_id);
+ memslot_id = get_memslot_id(&worker->mem_slots, *in_path);
+ QXLPath *path = (QXLPath *)get_virt(&worker->mem_slots, *in_path, sizeof(QXLPath), group_id);
*in_path = channel->send_data.header.size;
add_buf(channel, BUF_TYPE_RAW, &path->data_size, sizeof(uint32_t), 0, 0);
add_buf(channel, BUF_TYPE_CHUNK, &path->chunk, path->data_size, memslot_id, group_id);
@@ -5102,8 +4957,8 @@ static void fill_str(DisplayChannel *display_channel, QXLPHYSICAL *in_str, uint3
int memslot_id;
worker = channel->worker;
ASSERT(in_str && *in_str);
- memslot_id = get_memslot_id(worker, *in_str);
- QXLString *str = (QXLString *)get_virt(worker, *in_str, sizeof(QXLString), group_id);
+ memslot_id = get_memslot_id(&worker->mem_slots, *in_str);
+ QXLString *str = (QXLString *)get_virt(&worker->mem_slots, *in_str, sizeof(QXLString), group_id);
*in_str = channel->send_data.header.size;
add_buf(channel, BUF_TYPE_RAW, &str->length, sizeof(uint32_t), 0, 0);
add_buf(channel, BUF_TYPE_CHUNK, &str->chunk, str->data_size, memslot_id, group_id);
@@ -5113,10 +4968,10 @@ static inline void fill_rects_clip(RedChannel *channel, QXLPHYSICAL *in_clip, ui
{
RedWorker *worker = channel->worker;
QXLClipRects *clip;
- int memslot_id = get_memslot_id(worker, *in_clip);
+ int memslot_id = get_memslot_id(&worker->mem_slots, *in_clip);
ASSERT(in_clip && *in_clip);
- clip = (QXLClipRects *)get_virt(worker, *in_clip, sizeof(QXLClipRects), group_id);
+ clip = (QXLClipRects *)get_virt(&worker->mem_slots, *in_clip, sizeof(QXLClipRects), group_id);
*in_clip = channel->send_data.header.size;
add_buf(channel, BUF_TYPE_RAW, &clip->num_rects, sizeof(uint32_t), 0, 0);
add_buf(channel, BUF_TYPE_CHUNK, &clip->chunk, clip->num_rects * sizeof(SpiceRect), memslot_id,
@@ -5156,7 +5011,7 @@ static inline void fill_palette(DisplayChannel *display_channel, SPICE_ADDRESS *
if (!(*io_palette)) {
return;
}
- palette = (SpicePalette *)get_virt(worker, *io_palette, sizeof(SpicePalette), group_id);
+ palette = (SpicePalette *)get_virt(&worker->mem_slots, *io_palette, sizeof(SpicePalette), group_id);
if (palette->unique) {
if (red_palette_cache_find(display_channel, palette->unique)) {
*flags |= SPICE_BITMAP_FLAGS_PAL_FROM_CACHE;
@@ -5794,20 +5649,20 @@ static BitmapGradualType _get_bitmap_graduality_level(RedWorker *worker, SpiceBi
y = bitmap->y;
switch (bitmap->format) {
case SPICE_BITMAP_FMT_16BIT: {
- uint8_t *lines = (uint8_t*)get_virt(worker, bitmap->data, x * y *
+ uint8_t *lines = (uint8_t*)get_virt(&worker->mem_slots, bitmap->data, x * y *
sizeof(rgb16_pixel_t), group_id);
compute_lines_gradual_score_rgb16((rgb16_pixel_t*)lines, x, y, &score, &num_samples);
break;
}
case SPICE_BITMAP_FMT_24BIT: {
- uint8_t *lines = (uint8_t*)get_virt(worker, bitmap->data, x * y *
+ uint8_t *lines = (uint8_t*)get_virt(&worker->mem_slots, bitmap->data, x * y *
sizeof(rgb24_pixel_t), group_id);
compute_lines_gradual_score_rgb24((rgb24_pixel_t*)lines, x, y, &score, &num_samples);
break;
}
case SPICE_BITMAP_FMT_32BIT:
case SPICE_BITMAP_FMT_RGBA: {
- uint8_t *lines = (uint8_t*)get_virt(worker, bitmap->data, x * y *
+ uint8_t *lines = (uint8_t*)get_virt(&worker->mem_slots, bitmap->data, x * y *
sizeof(rgb32_pixel_t), group_id);
compute_lines_gradual_score_rgb32((rgb32_pixel_t*)lines, x, y, &score, &num_samples);
break;
@@ -5824,29 +5679,29 @@ static BitmapGradualType _get_bitmap_graduality_level(RedWorker *worker, SpiceBi
SPICE_ADDRESS relative_address = bitmap->data;
while (relative_address) {
- chunk = (QXLDataChunk *)get_virt(worker, relative_address, sizeof(QXLDataChunk),
+ chunk = (QXLDataChunk *)get_virt(&worker->mem_slots, relative_address, sizeof(QXLDataChunk),
group_id);
num_lines = chunk->data_size / bitmap->stride;
x = bitmap->x;
switch (bitmap->format) {
case SPICE_BITMAP_FMT_16BIT:
- validate_virt(worker, (unsigned long)chunk->data,
- get_memslot_id(worker, relative_address),
+ validate_virt(&worker->mem_slots, (unsigned long)chunk->data,
+ get_memslot_id(&worker->mem_slots, relative_address),
sizeof(rgb16_pixel_t) * x * num_lines, group_id);
compute_lines_gradual_score_rgb16((rgb16_pixel_t*)chunk->data, x, num_lines,
&chunk_score, &chunk_num_samples);
break;
case SPICE_BITMAP_FMT_24BIT:
- validate_virt(worker, (unsigned long)chunk->data,
- get_memslot_id(worker, relative_address),
+ validate_virt(&worker->mem_slots, (unsigned long)chunk->data,
+ get_memslot_id(&worker->mem_slots, relative_address),
sizeof(rgb24_pixel_t) * x * num_lines, group_id);
compute_lines_gradual_score_rgb24((rgb24_pixel_t*)chunk->data, x, num_lines,
&chunk_score, &chunk_num_samples);
break;
case SPICE_BITMAP_FMT_32BIT:
case SPICE_BITMAP_FMT_RGBA:
- validate_virt(worker, (unsigned long)chunk->data,
- get_memslot_id(worker, relative_address),
+ validate_virt(&worker->mem_slots, (unsigned long)chunk->data,
+ get_memslot_id(&worker->mem_slots, relative_address),
sizeof(rgb32_pixel_t) * x * num_lines, group_id);
compute_lines_gradual_score_rgb32((rgb32_pixel_t*)chunk->data, x, num_lines,
&chunk_score, &chunk_num_samples);
@@ -5961,13 +5816,13 @@ static inline int red_glz_compress_image(DisplayChannel *display_channel,
if ((src->flags & QXL_BITMAP_DIRECT)) {
glz_data->usr.more_lines = glz_usr_no_more_lines;
- lines = (uint8_t*)get_virt(worker, src->data, src->stride * src->y, drawable->group_id);
+ lines = (uint8_t*)get_virt(&worker->mem_slots, src->data, src->stride * src->y, drawable->group_id);
num_lines = src->y;
} else {
glz_data->data.u.lines_data.enc_get_virt = cb_get_virt;
- glz_data->data.u.lines_data.enc_get_virt_opaque = worker;
+ glz_data->data.u.lines_data.enc_get_virt_opaque = &worker->mem_slots;
glz_data->data.u.lines_data.enc_validate_virt = cb_validate_virt;
- glz_data->data.u.lines_data.enc_validate_virt_opaque = worker;
+ glz_data->data.u.lines_data.enc_validate_virt_opaque = &worker->mem_slots;
glz_data->data.u.lines_data.stride = src->stride;
glz_data->data.u.lines_data.next = src->data;
glz_data->data.u.lines_data.group_id = drawable->group_id;
@@ -6033,14 +5888,14 @@ static inline int red_lz_compress_image(DisplayChannel *display_channel,
if ((src->flags & QXL_BITMAP_DIRECT)) {
lz_data->usr.more_lines = lz_usr_no_more_lines;
size = lz_encode(lz, type, src->x, src->y, (src->flags & QXL_BITMAP_TOP_DOWN),
- (uint8_t*)get_virt(worker, src->data, src->stride * src->y, group_id),
+ (uint8_t*)get_virt(&worker->mem_slots, src->data, src->stride * src->y, group_id),
src->y, src->stride, (uint8_t*)lz_data->data.bufs_head->buf,
sizeof(lz_data->data.bufs_head->buf));
} else {
lz_data->data.u.lines_data.enc_get_virt = cb_get_virt;
- lz_data->data.u.lines_data.enc_get_virt_opaque = worker;
+ lz_data->data.u.lines_data.enc_get_virt_opaque = &worker->mem_slots;
lz_data->data.u.lines_data.enc_validate_virt = cb_validate_virt;
- lz_data->data.u.lines_data.enc_validate_virt_opaque = worker;
+ lz_data->data.u.lines_data.enc_validate_virt_opaque = &worker->mem_slots;
lz_data->data.u.lines_data.stride = src->stride;
lz_data->data.u.lines_data.next = src->data;
lz_data->data.u.lines_data.group_id = group_id;
@@ -6138,11 +5993,11 @@ static inline int red_quic_compress_image(DisplayChannel *display_channel, RedIm
uint8_t *data;
if (!(src->flags & QXL_BITMAP_TOP_DOWN)) {
- data = (uint8_t*)get_virt(worker, src->data, src->stride * src->y, group_id) +
+ data = (uint8_t*)get_virt(&worker->mem_slots, src->data, src->stride * src->y, group_id) +
src->stride * (src->y - 1);
stride = -src->stride;
} else {
- data = (uint8_t*)get_virt(worker, src->data, src->stride * src->y, group_id);
+ data = (uint8_t*)get_virt(&worker->mem_slots, src->data, src->stride * src->y, group_id);
stride = src->stride;
}
@@ -6179,9 +6034,9 @@ static inline int red_quic_compress_image(DisplayChannel *display_channel, RedIm
return FALSE;
}
quic_data->data.u.lines_data.enc_get_virt = cb_get_virt;
- quic_data->data.u.lines_data.enc_get_virt_opaque = worker;
+ quic_data->data.u.lines_data.enc_get_virt_opaque = &worker->mem_slots;
quic_data->data.u.lines_data.enc_validate_virt = cb_validate_virt;
- quic_data->data.u.lines_data.enc_validate_virt_opaque = worker;
+ quic_data->data.u.lines_data.enc_validate_virt_opaque = &worker->mem_slots;
quic_data->data.u.lines_data.stride = src->stride;
quic_data->data.u.lines_data.group_id = group_id;
@@ -6191,17 +6046,17 @@ static inline int red_quic_compress_image(DisplayChannel *display_channel, RedIm
stride = src->stride;
} else {
SPICE_ADDRESS prev_addr = src->data;
- QXLDataChunk *chunk = (QXLDataChunk *)get_virt(worker, src->data,
+ QXLDataChunk *chunk = (QXLDataChunk *)get_virt(&worker->mem_slots, src->data,
sizeof(QXLDataChunk), group_id);
while (chunk->next_chunk) {
prev_addr = chunk->next_chunk;
- chunk = (QXLDataChunk *)get_virt(worker, chunk->next_chunk, sizeof(QXLDataChunk),
+ chunk = (QXLDataChunk *)get_virt(&worker->mem_slots, chunk->next_chunk, sizeof(QXLDataChunk),
group_id);
ASSERT(chunk->prev_chunk);
}
quic_data->data.u.lines_data.next = (SPICE_ADDRESS)prev_addr -
- get_virt_delta(worker,
- get_memslot_id(worker, src->data),
+ get_virt_delta(&worker->mem_slots,
+ get_memslot_id(&worker->mem_slots, src->data),
group_id);
quic_data->usr.more_lines = quic_usr_more_lines_revers;
stride = -src->stride;
@@ -6364,7 +6219,7 @@ static void fill_bits(DisplayChannel *display_channel, QXLPHYSICAL *in_bitmap, D
ASSERT(drawable->self_bitmap);
qxl_image = (QXLImage *)drawable->self_bitmap;
} else {
- qxl_image = (QXLImage *)get_virt(worker, *in_bitmap, sizeof(QXLImage),
+ qxl_image = (QXLImage *)get_virt(&worker->mem_slots, *in_bitmap, sizeof(QXLImage),
drawable->group_id);
}
@@ -6376,7 +6231,7 @@ static void fill_bits(DisplayChannel *display_channel, QXLPHYSICAL *in_bitmap, D
image->descriptor.width = qxl_image->descriptor.width;
image->descriptor.height = qxl_image->descriptor.height;
- memslot_id = get_memslot_id(worker, *in_bitmap);
+ memslot_id = get_memslot_id(&worker->mem_slots, *in_bitmap);
*in_bitmap = channel->send_data.header.size;
if ((qxl_image->descriptor.flags & QXL_IMAGE_CACHE)) {
if (pixmap_cache_hit(display_channel->pixmap_cache, image->descriptor.id,
@@ -6432,10 +6287,10 @@ static void fill_bits(DisplayChannel *display_channel, QXLPHYSICAL *in_bitmap, D
drawable->group_id);
image->bitmap.data = channel->send_data.header.size;
if (qxl_image->bitmap.flags & QXL_BITMAP_DIRECT) {
- data = (uint8_t *)get_virt(worker, image_data, stride * y, drawable->group_id);
+ data = (uint8_t *)get_virt(&worker->mem_slots, image_data, stride * y, drawable->group_id);
add_buf(channel, BUF_TYPE_RAW, data, y * stride, 0, 0);
} else {
- data = (uint8_t *)get_virt(worker, image_data, sizeof(QXLDataChunk),
+ data = (uint8_t *)get_virt(&worker->mem_slots, image_data, sizeof(QXLDataChunk),
drawable->group_id);
add_buf(channel, BUF_TYPE_CHUNK, data, y * stride, memslot_id, drawable->group_id);
}
@@ -6491,7 +6346,7 @@ static void fill_attr(DisplayChannel *display_channel, SpiceLineAttr *attr, uint
{
if (attr->style_nseg) {
RedChannel *channel = &display_channel->base;
- uint8_t *buf = (uint8_t *)get_virt(channel->worker, attr->style,
+ uint8_t *buf = (uint8_t *)get_virt(&channel->worker->mem_slots, attr->style,
attr->style_nseg * sizeof(uint32_t), group_id);
ASSERT(attr->style);
attr->style = channel->send_data.header.size;
@@ -6513,7 +6368,7 @@ static void fill_cursor(CursorChannel *cursor_channel, SpiceCursor *red_cursor,
QXLCursor *qxl_cursor;
cursor_cmd = cursor->qxl_cursor;
- qxl_cursor = (QXLCursor *)get_virt(channel->worker, cursor_cmd->u.set.shape,
+ qxl_cursor = (QXLCursor *)get_virt(&channel->worker->mem_slots, cursor_cmd->u.set.shape,
sizeof(QXLCursor), cursor->group_id);
red_cursor->flags = 0;
red_cursor->header = qxl_cursor->header;
@@ -6530,7 +6385,7 @@ static void fill_cursor(CursorChannel *cursor_channel, SpiceCursor *red_cursor,
if (qxl_cursor->data_size) {
add_buf(channel, BUF_TYPE_CHUNK, &qxl_cursor->chunk, qxl_cursor->data_size,
- get_memslot_id(channel->worker, cursor_cmd->u.set.shape), cursor->group_id);
+ get_memslot_id(&channel->worker->mem_slots, cursor_cmd->u.set.shape), cursor->group_id);
}
} else {
LocalCursor *local_cursor;
@@ -6734,7 +6589,7 @@ static inline uint32_t __fill_iovec(RedWorker *worker, BufDescriptor *buf, int s
data_size -= skip_now;
if (data_size) {
- validate_virt(worker, (unsigned long)chunk->data, buf->slot_id, data_size,
+ validate_virt(&worker->mem_slots, (unsigned long)chunk->data, buf->slot_id, data_size,
buf->group_id);
size += data_size;
vec[*vec_index].iov_base = chunk->data + skip_now;
@@ -6742,7 +6597,7 @@ static inline uint32_t __fill_iovec(RedWorker *worker, BufDescriptor *buf, int s
(*vec_index)++;
}
chunk = chunk->next_chunk ?
- (QXLDataChunk *)get_virt(worker, chunk->next_chunk, sizeof(QXLDataChunk),
+ (QXLDataChunk *)get_virt(&worker->mem_slots, chunk->next_chunk, sizeof(QXLDataChunk),
buf->group_id) :
NULL;
} while (chunk && *vec_index < MAX_SEND_VEC);
@@ -6930,10 +6785,10 @@ static inline uint8_t *red_get_image_line(RedWorker *worker, QXLDataChunk **chun
uint8_t *ret;
uint32_t data_size;
- validate_virt(worker, (unsigned long)*chunk, memslot_id, sizeof(QXLDataChunk),
+ validate_virt(&worker->mem_slots, (unsigned long)*chunk, memslot_id, sizeof(QXLDataChunk),
group_id);
data_size = (*chunk)->data_size;
- validate_virt(worker, (unsigned long)(*chunk)->data, memslot_id, data_size, group_id);
+ validate_virt(&worker->mem_slots, (unsigned long)(*chunk)->data, memslot_id, data_size, group_id);
if (data_size == *offset) {
if ((*chunk)->next_chunk == 0) {
@@ -7119,7 +6974,7 @@ static inline int red_send_stream_data(DisplayChannel *display_channel, Drawable
channel = &display_channel->base;
worker = channel->worker;
- qxl_image = (QXLImage *)get_virt(worker, drawable->qxl_drawable->u.copy.src_bitmap,
+ qxl_image = (QXLImage *)get_virt(&worker->mem_slots, drawable->qxl_drawable->u.copy.src_bitmap,
sizeof(QXLImage), drawable->group_id);
if (qxl_image->descriptor.type != SPICE_IMAGE_TYPE_BITMAP ||
@@ -7142,8 +6997,8 @@ static inline int red_send_stream_data(DisplayChannel *display_channel, Drawable
case SPICE_BITMAP_FMT_32BIT:
if (!red_rgb32bpp_to_24(worker, &drawable->qxl_drawable->u.copy.src_area,
&qxl_image->bitmap, frame, frame_stride,
- get_virt_delta(worker, data, drawable->group_id),
- get_memslot_id(worker, data),
+ get_virt_delta(&worker->mem_slots, data, drawable->group_id),
+ get_memslot_id(&worker->mem_slots, data),
stream - worker->streams_buf, stream, drawable->group_id)) {
return FALSE;
}
@@ -7151,8 +7006,8 @@ static inline int red_send_stream_data(DisplayChannel *display_channel, Drawable
case SPICE_BITMAP_FMT_16BIT:
if (!red_rgb16bpp_to_24(worker, &drawable->qxl_drawable->u.copy.src_area,
&qxl_image->bitmap, frame, frame_stride,
- get_virt_delta(worker, data, drawable->group_id),
- get_memslot_id(worker, data),
+ get_virt_delta(&worker->mem_slots, data, drawable->group_id),
+ get_memslot_id(&worker->mem_slots, data),
stream - worker->streams_buf, stream, drawable->group_id)) {
return FALSE;
}
@@ -7160,8 +7015,8 @@ static inline int red_send_stream_data(DisplayChannel *display_channel, Drawable
case SPICE_BITMAP_FMT_24BIT:
if (!red_rgb24bpp_to_24(worker, &drawable->qxl_drawable->u.copy.src_area,
&qxl_image->bitmap, frame, frame_stride,
- get_virt_delta(worker, data, drawable->group_id),
- get_memslot_id(worker, data),
+ get_virt_delta(&worker->mem_slots, data, drawable->group_id),
+ get_memslot_id(&worker->mem_slots, data),
stream - worker->streams_buf, stream, drawable->group_id)) {
return FALSE;
}
@@ -7395,7 +7250,7 @@ static void red_send_image(DisplayChannel *display_channel, ImageItem *item)
compress_send_data_t comp_send_data;
if (red_quic_compress_image(display_channel, red_image, &bitmap, &comp_send_data,
- worker->internal_groupslot_id)) {
+ worker->mem_slots.internal_groupslot_id)) {
add_buf(channel, BUF_TYPE_RAW, red_image, comp_send_data.raw_size, 0, 0);
add_buf(channel, BUF_TYPE_COMPRESS_BUF, comp_send_data.comp_buf,
comp_send_data.comp_buf_size, 0, 0);
@@ -8950,7 +8805,7 @@ static void red_cursor_flush(RedWorker *worker)
cursor_cmd = worker->cursor->qxl_cursor;
ASSERT(cursor_cmd->type == QXL_CURSOR_SET);
- qxl_cursor = (QXLCursor *)get_virt(worker, cursor_cmd->u.set.shape, sizeof(QXLCursor),
+ qxl_cursor = (QXLCursor *)get_virt(&worker->mem_slots, cursor_cmd->u.set.shape, sizeof(QXLCursor),
worker->cursor->group_id);
local = _new_local_cursor(&qxl_cursor->header, qxl_cursor->data_size,
@@ -8967,8 +8822,8 @@ static void red_cursor_flush(RedWorker *worker)
data_size -= chunk->data_size;
dest += chunk->data_size;
chunk = chunk->next_chunk ?
- (QXLDataChunk *)get_virt(worker, chunk->next_chunk, sizeof(QXLDataChunk),
- worker->internal_groupslot_id) : NULL;
+ (QXLDataChunk *)get_virt(&worker->mem_slots, chunk->next_chunk, sizeof(QXLDataChunk),
+ worker->mem_slots.internal_groupslot_id) : NULL;
}
red_set_cursor(worker, &local->base);
red_release_cursor(worker, &local->base);
@@ -9057,13 +8912,9 @@ static inline void handle_dev_add_memslot(RedWorker *worker)
receive_data(worker->channel, &dev_slot, sizeof(QXLDevMemSlot));
- ASSERT(worker->num_memslots_groups > dev_slot.slot_group_id);
- ASSERT(worker->num_memslots > dev_slot.slot_id);
- worker->mem_slots[dev_slot.slot_group_id][dev_slot.slot_id].address_delta = dev_slot.addr_delta;
- worker->mem_slots[dev_slot.slot_group_id][dev_slot.slot_id].virt_start_addr =
- dev_slot.virt_start;
- worker->mem_slots[dev_slot.slot_group_id][dev_slot.slot_id].virt_end_addr = dev_slot.virt_end;
- worker->mem_slots[dev_slot.slot_group_id][dev_slot.slot_id].generation = dev_slot.generation;
+ red_memslot_info_add_slot(&worker->mem_slots, dev_slot.slot_group_id, dev_slot.slot_id,
+ dev_slot.addr_delta, dev_slot.virt_start, dev_slot.virt_end,
+ dev_slot.generation);
message = RED_WORKER_MESSAGE_READY;
write_message(worker->channel, &message);
@@ -9077,11 +8928,7 @@ static inline void handle_dev_del_memslot(RedWorker *worker)
receive_data(worker->channel, &slot_group_id, sizeof(uint32_t));
receive_data(worker->channel, &slot_id, sizeof(uint32_t));
- ASSERT(worker->num_memslots_groups > slot_group_id);
- ASSERT(worker->num_memslots > slot_id);
-
- worker->mem_slots[slot_group_id][slot_id].virt_start_addr = 0;
- worker->mem_slots[slot_group_id][slot_id].virt_end_addr = 0;
+ red_memslot_info_del_slot(&worker->mem_slots, slot_group_id, slot_id);
}
static inline void destroy_surface_wait(RedWorker *worker, int surface_id)
@@ -9182,7 +9029,7 @@ static inline void handle_dev_create_primary_surface(RedWorker *worker)
PANIC_ON(((uint64_t)abs(surface.stride) * (uint64_t)surface.height) !=
abs(surface.stride) * surface.height);
- line_0 = (uint8_t*)get_virt(worker, surface.mem, surface.height * abs(surface.stride),
+ line_0 = (uint8_t*)get_virt(&worker->mem_slots, surface.mem, surface.height * abs(surface.stride),
surface.group_id);
if (surface.stride < 0) {
line_0 -= (int32_t)(surface.stride * (surface.height -1));
@@ -9243,25 +9090,6 @@ static inline void handle_dev_destroy_primary_surface(RedWorker *worker)
write_message(worker->channel, &message);
}
-static void inline red_create_mem_slots(RedWorker *worker)
-{
- uint32_t i;
-
- ASSERT(worker->num_memslots > 0);
- ASSERT(worker->num_memslots_groups > 0);
- worker->mem_slots = spice_new(MemSlot *, worker->num_memslots_groups);
-
- for (i = 0; i < worker->num_memslots_groups; ++i) {
- worker->mem_slots[i] = spice_new0(MemSlot, worker->num_memslots);
- }
-
- worker->memslot_id_shift = 64 - worker->mem_slot_bits;
- worker->memslot_gen_shift = 64 - (worker->mem_slot_bits + worker->generation_bits);
- worker->memslot_gen_mask = ~((unsigned long)-1 << worker->generation_bits);
- worker->memslot_clean_virt_mask = (((unsigned long)(-1)) >>
- (worker->mem_slot_bits + worker->generation_bits));
-}
-
static void handle_dev_input(EventListener *listener, uint32_t events)
{
RedWorker *worker = SPICE_CONTAINEROF(listener, RedWorker, dev_listener);
@@ -9470,13 +9298,9 @@ static void handle_dev_input(EventListener *listener, uint32_t events)
case RED_WORKER_MESSAGE_DEL_MEMSLOT:
handle_dev_del_memslot(worker);
break;
- case RED_WORKER_MESSAGE_RESET_MEMSLOTS: {
- uint32_t i;
- for (i = 0; i < worker->num_memslots_groups; ++i) {
- memset(worker->mem_slots[i], 0, sizeof(MemSlot) * worker->num_memslots);
- }
+ case RED_WORKER_MESSAGE_RESET_MEMSLOTS:
+ red_memslot_info_reset(&worker->mem_slots);
break;
- }
default:
red_error("message error");
}
@@ -9537,14 +9361,15 @@ static void red_init(RedWorker *worker, WorkerInitData *init_data)
red_error("add channel failed, %s", strerror(errno));
}
- worker->num_memslots_groups = init_data->num_memslots_groups;
- worker->num_memslots = init_data->num_memslots;
- worker->generation_bits = init_data->memslot_gen_bits;
- worker->mem_slot_bits = init_data->memslot_id_bits;
- worker->internal_groupslot_id = init_data->internal_groupslot_id;
+ red_memslot_info_init(&worker->mem_slots,
+ init_data->num_memslots_groups,
+ init_data->num_memslots,
+ init_data->memslot_gen_bits,
+ init_data->memslot_id_bits,
+ init_data->internal_groupslot_id);
+
PANIC_ON(init_data->n_surfaces > NUM_SURFACES);
worker->n_surfaces = init_data->n_surfaces;
- red_create_mem_slots(worker);
worker->preload_group_virt_mapping.ops = &preload_group_virt_mapping_ops;
@@ -9704,7 +9529,7 @@ static void dump_bitmap(RedWorker *worker, SpiceBitmap *bitmap, uint32_t group_i
if (!bitmap->palette) {
return; // dont dump masks.
}
- plt = (SpicePalette *)get_virt(worker, bitmap->palette, sizeof(SpicePalette), group_id);
+ plt = (SpicePalette *)get_virt(&worker->mem_slots, bitmap->palette, sizeof(SpicePalette), group_id);
}
row_size = (((bitmap->x * n_pixel_bits) + 31) / 32) * 4;
bitmap_data_offset = header_size;
@@ -9760,7 +9585,7 @@ static void dump_bitmap(RedWorker *worker, SpiceBitmap *bitmap, uint32_t group_i
}
/* writing the data */
if ((bitmap->flags & QXL_BITMAP_DIRECT)) {
- uint8_t *lines = (uint8_t*)get_virt(worker, bitmap->data, bitmap->stride * bitmap->y,
+ uint8_t *lines = (uint8_t*)get_virt(&worker->mem_slots, bitmap->data, bitmap->stride * bitmap->y,
group_id);
int i;
for (i = 0; i < bitmap->y; i++) {
@@ -9773,9 +9598,9 @@ static void dump_bitmap(RedWorker *worker, SpiceBitmap *bitmap, uint32_t group_i
while (relative_address) {
int i;
- chunk = (QXLDataChunk *)get_virt(worker, relative_address, sizeof(QXLDataChunk),
+ chunk = (QXLDataChunk *)get_virt(&worker->mem_slots, relative_address, sizeof(QXLDataChunk),
group_id);
- validate_virt(worker, chunk->data, get_memslot_id(worker, relative_address),
+ validate_virt(&worker->mem_slots, chunk->data, get_memslot_id(&worker->mem_slots, relative_address),
chunk->data_size, group_id);
num_lines = chunk->data_size / bitmap->stride;
for (i = 0; i < num_lines; i++) {