summary refs log tree commit diff stats
path: root/results/classifier/gemma3:12b/device/1628
blob: 6dbe1f98a382e1e01d20c09d71e7c9386dbd6f33 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
windows 10 display scale will cause an exception
Description of problem:
windows dispaly sacle 150% or higher,  windows system will exception
Steps to reproduce:
1.  windows dispaly sacle 150%
Additional information:
- code in: qemu/hw/display/qxl-render.c

static void qxl_unpack_chunks(void *dest, size_t size, PCIQXLDevice *qxl,
                              QXLDataChunk *chunk, uint32_t group_id)
{
    uint32_t max_chunks = 32;
    size_t offset = 0;
    size_t bytes;
    for (;;) {
        bytes = MIN(size - offset, chunk->data_size);
        memcpy(dest + offset, chunk->data, bytes);
        offset += bytes;
        if (offset == size) {
            return;
        }
        chunk = qxl_phys2virt(qxl, chunk->next_chunk, group_id,
                              sizeof(QXLDataChunk) + chunk->data_size);
         **// get next chunk, but the chunk size use current chunk's data size, not next chunk's data size!!!!**
         **// if next chunk alloc size < current chunk's data size, there will be exception **
         
        if (!chunk) {
            return;
        }
        max_chunks--;
        if (max_chunks == 0) {
            return;
        }
    }
}



- code in: qxl_wddm_dod/QXLDod.cpp exist next chunk alloc size < current chunk's data size 

NTSTATUS  QxlDevice::SetPointerShape(_In_ CONST DXGKARG_SETPOINTERSHAPE* pSetPointerShape)
{
.....
    res = (Resource *)AllocMem(MSPACE_TYPE_VRAM, CURSOR_ALLOC_SIZE, TRUE);  // here we all the first QXLDataChunk , and alloc_size = (CURSOR_ALLOC_SIZE - sizeof(Resource) - sizeof(InternalCursor)) = 8118

.....
     for (; src != src_end; src += pSetPointerShape->Pitch) {
        if (!PutBytesAlign(&chunk, &now, &end, src, line_size, PAGE_SIZE - PAGE_SIZE % line_size, NULL)) { // in this function ,we will alloc next QXLDataChunk 
            ..........
            break;
        }
    }
}

BOOLEAN QxlDevice::PutBytesAlign(QXLDataChunk **chunk_ptr, UINT8 **now_ptr,
                            UINT8 **end_ptr, UINT8 *src, int size,
                            size_t alloc_size, PLIST_ENTRY pDelayed)
{
    .....
    size_t maxAllocSize = BITS_BUF_MAX - BITS_BUF_MAX % size;
    alloc_size = MIN(alloc_size, maxAllocSize);
    void *ptr = AllocMem(MSPACE_TYPE_VRAM, alloc_size + sizeof(QXLDataChunk), bForced);  *** //here will  alloc  next  QXLDataChunk  and  alloc_size  = (PAGE_SIZE - PAGE_SIZE % line_size) = 3876 ****
}


eg:
dispaly sacle 150% ,mouse size will bu change to  57* 55  ,rgba data size = 12540,   we  need three QXLDataChunk  

QXLDataChunk* first;
first->data_size = 8118;
first->prev_chunk = 0;
first->next_chunk=second;
first->data = [alloc_size(8118), data_size(8118)]

QXLDataChunk* second;
second->data_size = 3876;
second->prev_chunk = first;
second->next_chunk=third;
second->data = [alloc_size(3876), data_size(3876)]

QXLDataChunk* third;
third->data_size = 546;
third->prev_chunk =second;
third->next_chunk=0;
third->data = [alloc_size(3876), data_size(546)]


chunk = first;
qxl_phys2virt(qxl, second, group_id, sizeof(QXLDataChunk) + 8118)


this size [sizeof(QXLDataChunk) + 8118]  > second  QXLDataChunk's  alloc  size  , will  cause  qxl_get_check_slot_offset check fail


for second QXLDataChunk, we actual alloc size  is (sizeof(QXLDataChunk) + 3876),  but we assign (8118 + sizeof(QXLDataChunk))  will cause an exception


suggest code :

static void qxl_unpack_chunks(void *dest, size_t size, PCIQXLDevice *qxl,
                              QXLDataChunk *chunk, uint32_t group_id)
{
    uint32_t max_chunks = 32;
    size_t offset = 0;
    size_t bytes;
    QXLPHYSICAL next_chunk_phys = 0; 
    for (;;) {
        bytes = MIN(size - offset, chunk->data_size);
        memcpy(dest + offset, chunk->data, bytes);
        offset += bytes;
        if (offset == size) {
            return;
        }
        next_chunk_phys = chunk->next_chunk;
        chunk = qxl_phys2virt(qxl, next_chunk_phys, group_id,
                              sizeof(QXLDataChunk));  // fist time, only get the next chunk's data size;
        if (!chunk) {
            return;
        }
        chunk = qxl_phys2virt(qxl, next_chunk_phys, group_id,
                              sizeof(QXLDataChunk) + chunk->data_size); // second time, check data size and get data;
        if (!chunk) {
            return;
        }
        max_chunks--;
        if (max_chunks == 0) {
            return;
        }
    }
}