sys_batch_map

This commit is contained in:
Pavel 2025-06-18 00:10:36 +03:00
parent 98892193aa
commit cfafa793cd
11 changed files with 276 additions and 76 deletions

View File

@ -371,7 +371,7 @@ begin
base_dmem_addr:=get_dmem_ptr(ringBaseAddress);
offset:=QWORD(readPtrAddress) and PAGE_MASK;
base :=Pointer(QWORD(readPtrAddress) and (not PAGE_MASK));
base :=Pointer(QWORD(readPtrAddress) and QWORD(not PAGE_MASK));
read_mirr_addr:=mirror_map(base,PAGE_SIZE);
@ -399,7 +399,7 @@ var
begin
hqd^:=Default(t_gc_hqd);
base:=Pointer(QWORD(hqd^.read_mirr_addr) and (not PAGE_MASK));
base:=Pointer(QWORD(hqd^.read_mirr_addr) and QWORD(not PAGE_MASK));
mirror_unmap(base,PAGE_SIZE);

View File

@ -6,6 +6,7 @@ unit dev_sce_zlib;
interface
uses
vmparam,
sys_conf,
sys_event;
@ -170,8 +171,8 @@ begin
if (data^.length=0) or
(data^.buffer=nil) then Exit(EINVAL);
buffer_lo:=QWORD(data^.buffer) and QWORD($ffffffffffffc000);
buffer_hi:=(QWORD(data^.buffer) + data^.length + $3fff) and QWORD($ffffffffffffc000);
buffer_lo:=QWORD(data^.buffer) and QWORD(not PAGE_MASK);
buffer_hi:=(QWORD(data^.buffer) + data^.length + PAGE_MASK) and QWORD(not PAGE_MASK);
map:=p_proc.p_vmspace;

View File

@ -325,9 +325,9 @@ var
base:Pointer;
begin
mask:=QWORD(orig) and PAGE_MASK;
size:=(size+mask+PAGE_MASK) and (not PAGE_MASK);
size:=(size+mask+PAGE_MASK) and QWORD(not PAGE_MASK);
base:=vm_mmap.mirror_map(Pointer(QWORD(orig) and (not PAGE_MASK)),size);
base:=vm_mmap.mirror_map(Pointer(QWORD(orig) and QWORD(not PAGE_MASK)),size);
Result.orig:=orig;
Result.mirr:=base+mask;

View File

@ -2799,7 +2799,7 @@ var
),
(//[548]
sy_narg:5;
sy_call:nil;
sy_call:@sys_batch_map;
sy_name:'sys_batch_map'
),
(//[549]

View File

@ -206,7 +206,7 @@ procedure pick(var ctx:t_jit_context2;preload:Pointer); external name 'kern_jit_
function scan_up_exc(addr:QWORD):QWORD;
begin
addr:=(addr+PAGE_MASK) and (not PAGE_MASK);
addr:=(addr+PAGE_MASK) and QWORD(not PAGE_MASK);
while is_guest_addr(addr) do
begin
@ -224,7 +224,7 @@ end;
function scan_dw_exc(addr:QWORD):QWORD;
begin
addr:=addr and (not PAGE_MASK);
addr:=addr and QWORD(not PAGE_MASK);
while is_guest_addr(addr) do
begin

View File

@ -44,26 +44,6 @@ type
align:array[0..6] of Byte;
end;
const
//SceKernelMapEntryOperation
SCE_KERNEL_MAP_OP_MAP_DIRECT =0;
SCE_KERNEL_MAP_OP_UNMAP =1;
SCE_KERNEL_MAP_OP_PROTECT =2;
SCE_KERNEL_MAP_OP_MAP_FLEXIBLE=3;
SCE_KERNEL_MAP_OP_TYPE_PROTECT=4;
type
pSceKernelBatchMapEntry=^SceKernelBatchMapEntry;
SceKernelBatchMapEntry=packed record
start:Pointer;
offset:QWORD;
length:QWORD;
protection:Byte;
mtype:Byte;
pad1:Word;
operation:Integer;
end;
type
p_dmem_obj=^t_dmem_obj;
t_dmem_obj=record
@ -156,9 +136,6 @@ begin
rmap.tmap:=@vmap^.pmap^.tr_map;
end;
const
default_pool_id=1;
function sys_dmem_container(d_pool_id:Integer):Integer;
var
td:p_kthread;
@ -166,7 +143,7 @@ begin
td:=curkthread;
if (td=nil) then Exit(-1);
td^.td_retval[0]:=default_pool_id;
td^.td_retval[0]:=p_proc.p_pool_id;
Result:=0;
if (d_pool_id<>-1) then
@ -244,7 +221,7 @@ begin
Exit(EACCES);
end;
dmap:=dmem_maps[default_pool_id];
dmap:=dmem_maps[p_proc.p_pool_id];
//entry->eflags = flags & 0x400000 | 0x20000 | 0x80000
//0x400000 -> MAP_ENTRY_NO_COALESCE -> MAP_NO_COALESCE
@ -404,7 +381,7 @@ begin
Exit(Pointer(EPERM));
end;
if (default_pool_id<>1) then
if (p_proc.p_pool_id<>1) then
begin
Exit(Pointer(EOPNOTSUPP));
end;
@ -646,7 +623,7 @@ begin
addr:=start;
end;
ret:=dmem_map_get_mtype(dmem_maps[default_pool_id].dmem,
ret:=dmem_map_get_mtype(dmem_maps[p_proc.p_pool_id].dmem,
obj,
addr + (entry^.offset - start), //send not transformed offset
@d_start2,@d_end2,

View File

@ -23,47 +23,55 @@ type
ar_args :AnsiChar; // Arguments.
end;
var
p_proc:record
p_mtx:mtx;
type
t_proc=object
var
p_mtx:mtx;
p_pid:Integer;
p_pid:Integer;
p_flag :Integer;
p_osrel:Integer;
p_flag :Integer;
p_osrel:Integer;
p_sdk_version:Integer;
p_sdk_version:Integer;
p_sysent:p_sysentvec;
p_sysent:p_sysentvec;
p_libkernel_start_addr:Pointer;
p_libkernel___end_addr:Pointer;
p_libkernel_start_addr:Pointer;
p_libkernel___end_addr:Pointer;
p_ptc:Int64;
p_guest_ptc:PInt64;
p_ptc :Int64;
p_guest_ptc:PInt64;
p_nsignals:Int64;
p_nvcsw :Int64;
p_nivcsw :Int64;
p_nsignals:Int64;
p_nvcsw :Int64;
p_nivcsw :Int64;
p_comm :array[0..MAXCOMLEN] of AnsiChar;
p_prog_name :array[0..1023] of AnsiChar;
p_randomized_path:array[0..7] of AnsiChar;
p_comm :array[0..MAXCOMLEN] of AnsiChar;
p_prog_name :array[0..1023] of AnsiChar;
p_randomized_path:array[0..7] of AnsiChar;
p_sigqueue :sigqueue_t; //Sigs not delivered to a td.
p_pendingcnt :Integer; //how many signals are pending
p_sigqueue :sigqueue_t; //Sigs not delivered to a td.
p_pendingcnt :Integer; //how many signals are pending
p_klist:t_knlist;
p_klist:t_knlist;
p_args:p_pargs;
p_args:p_pargs;
p_vmspace:Pointer;
p_vmspace:Pointer;
p_budget_ptype :Integer;
p_dmem_aliasing:Integer;
p_vm_container :Integer;
const
p_pool_id=1;
p_budget_ptype :Integer;
p_dmem_aliasing:Integer;
p_vm_container :Integer;
end;
var
p_proc:t_proc;
function pargs_alloc(len:Integer):p_pargs;
procedure pargs_free(pa:p_pargs);
procedure pargs_hold(pa:p_pargs);
@ -138,7 +146,7 @@ begin
p_proc.p_randomized_path:='system';
p_proc.p_ptc:=rdtsc();
p_proc.p_ptc :=rdtsc();
p_proc.p_guest_ptc:=nil;
end;

View File

@ -2460,8 +2460,8 @@ begin
end else
if (p_proc.p_sdk_version < $1700000) then
begin
p_start:=Pointer(QWORD(dst) and (not PAGE_MASK));
p___end:=Pointer((QWORD(dst)+size+PAGE_MASK) and (not PAGE_MASK));
p_start:=Pointer(QWORD(dst) and QWORD(not PAGE_MASK));
p___end:=Pointer((QWORD(dst)+size+PAGE_MASK) and QWORD(not PAGE_MASK));
offset:=QWORD(dst) and PAGE_MASK;
p_size:=QWORD(p___end)-QWORD(p_start);

View File

@ -205,6 +205,7 @@ function evf_set(key:Integer;bitPattern:QWORD):Integer;
function evf_clear(key:Integer;bitPattern:QWORD):Integer;
function evf_cancel(key:Integer;setPattern:QWORD;pNumWait:PInteger):Integer;
function query_memory_protection(addr:Pointer;info:Pointer):Integer;
function batch_map(fd:Integer;flags:DWORD;entries:Pointer;numberOfEntries:Integer;numberOfEntriesOut:PInteger):Integer;
function osem_create(name:PChar;attr:DWORD;initCount,maxCount:Integer):Integer;
function osem_delete(key:Integer):Integer;
function __sys_osem_open(name:PChar):Integer;
@ -1657,6 +1658,13 @@ asm
jmp cerror
end;
function batch_map(fd:Integer;flags:DWORD;entries:Pointer;numberOfEntries:Integer;numberOfEntriesOut:PInteger):Integer; assembler; nostackframe;
asm
movq $548,%rax
call fast_syscall
jmp cerror
end;
function osem_create(name:PChar;attr:DWORD;initCount,maxCount:Integer):Integer; assembler; nostackframe;
asm
movq $549,%rax

View File

@ -139,12 +139,12 @@ end;
function round_page(x:QWORD):QWORD; inline;
begin
Result:=(x+PAGE_MASK) and (not PAGE_MASK);
Result:=(x+PAGE_MASK) and QWORD(not PAGE_MASK);
end;
function trunc_page(x:QWORD):QWORD; inline;
begin
Result:=x and (not PAGE_MASK);
Result:=x and QWORD(not PAGE_MASK);
end;
function roundup(addr:QWORD;alignment:QWORD):QWORD; inline;

View File

@ -36,6 +36,13 @@ function sys_mtypeprotect(addr:Pointer;len:QWORD;mtype,prot:Integer):Integer;
function sys_madvise(addr:Pointer;len:QWORD;behav:Integer):Integer;
function sys_mname(addr:Pointer;len:QWORD;name:PChar):Integer;
function sys_query_memory_protection(addr:Pointer;info:Pointer):Integer;
function sys_batch_map(fd :Integer;
flags :DWORD;
entries :Pointer;
numberOfEntries :Integer;
numberOfEntriesOut:PInteger):Integer;
function sys_get_page_table_stats(vm_container,cpu_gpu:Integer;p_total,p_available:PInteger):Integer;
function vm_mmap_to_errno(rv:Integer):Integer; inline;
@ -66,6 +73,7 @@ uses
kern_proc,
vmparam,
vm_pmap,
kern_dmem,
sys_resource,
kern_resource,
kern_mtx,
@ -1098,17 +1106,16 @@ end;
function sys_mtypeprotect(addr:Pointer;len:QWORD;mtype,prot:Integer):Integer;
var
size,pageoff:vm_size_t;
__end_u:QWORD;
__end_a:QWORD;
begin
size:=len;
pageoff:=(vm_size_t(addr) and PAGE_MASK);
addr:=addr-pageoff;
size:=size+pageoff;
size:=round_page(size);
__end_u:=QWORD(addr) + len;
__end_a:=(__end_u + PAGE_MASK) and QWORD(not PAGE_MASK);
if (addr + size < addr) or
(DWORD(mtype) >= 11) or
if (__end_u < QWORD(addr)) or
(__end_a < __end_u) or
(DWORD(mtype) > 10) or
((prot and $c8) <> 0) then
begin
Exit(EINVAL);
@ -1116,7 +1123,7 @@ begin
prot:=((Byte(prot) shr 1) and 1) or Byte(prot);
Result:=vm_map_type_protect(p_proc.p_vmspace, QWORD(addr), QWORD(addr) + size, mtype, prot);
Result:=vm_map_type_protect(p_proc.p_vmspace, QWORD(addr) and QWORD(not PAGE_MASK), __end_a, mtype, prot);
case Result of
KERN_SUCCESS :Result:=0;
@ -1255,6 +1262,205 @@ begin
end;
end;
const
SCE_KERNEL_MAP_OP_MAP_DIRECT =0;
SCE_KERNEL_MAP_OP_UNMAP =1;
SCE_KERNEL_MAP_OP_PROTECT =2;
SCE_KERNEL_MAP_OP_MAP_FLEXIBLE=3;
SCE_KERNEL_MAP_OP_TYPE_PROTECT=4;
type
PSceKernelBatchMapEntry=^SceKernelBatchMapEntry;
SceKernelBatchMapEntry=packed record
start :Pointer;
offset :QWORD;
length :QWORD;
protection:Byte;
mtype :Byte;
pad :WORD;
operation :Integer;
end;
{$IF sizeof(SceKernelBatchMapEntry)<>32}{$STOP sizeof(SceKernelBatchMapEntry)<>32}{$ENDIF}
function sys_batch_map(fd :Integer;
flags :DWORD;
entries :Pointer;
numberOfEntries :Integer;
numberOfEntriesOut:PInteger):Integer;
var
i,num_out:Integer;
node:SceKernelBatchMapEntry;
__end:QWORD;
begin
Result:=0;
if (numberOfEntries <= -1) then
begin
if (numberOfEntriesOut<>nil) then
begin
suword32(PDWORD(numberOfEntriesOut)^,0);
end;
Exit(EINVAL);
end;
if ((flags and $e0bffb6f) <> 0) then
begin
Exit(EINVAL);
end;
if (numberOfEntries < 1) then
begin
Result :=0;
num_out:=0;
end else
begin
num_out:=0;
node:=Default(SceKernelBatchMapEntry);
For i:=0 to numberOfEntries-1 do
begin
Result:=copyin(@PSceKernelBatchMapEntry(entries)[i],@node,SizeOf(node));
if (Result<>0) then Break;
case node.operation of
SCE_KERNEL_MAP_OP_MAP_DIRECT:
begin
if (p_proc.p_pool_id <> 1) or
((g_appinfo.mmap_flags and 2) <> 0) or
((flags and MAP_STACK) <> 0) or
(p_proc.p_sdk_version < $2500000) then
begin
if ((QWORD(node.start) and PAGE_MASK) = 0) and
((node.length and PAGE_MASK) = 0) and
((node.offset and QWORD($8000000000003fff)) = 0) and
((node.protection and $C8) = 0) then
begin
Result:=Integer(sys_mmap(node.start,
node.length,
node.protection,
flags or MAP_SHARED,
fd,
node.offset));
end else
begin
Result:=EINVAL;
Break;
end;
end else
begin
Result:=Integer(sys_mmap_dmem(node.start,
node.length,
DWORD(-1),
node.protection,
flags,
node.offset));
end;
end; //SCE_KERNEL_MAP_OP_MAP_DIRECT
SCE_KERNEL_MAP_OP_UNMAP:
begin
if ((QWORD(node.start) and PAGE_MASK) <> 0) or
((node.length and PAGE_MASK) <> 0) then
begin
Result:=EINVAL;
Break;
end;
Result:=sys_munmap(node.start,node.length);
end; //SCE_KERNEL_MAP_OP_UNMAP
SCE_KERNEL_MAP_OP_PROTECT:
begin
__end:=QWORD(node.start) + ((node.length + PAGE_MASK) and QWORD(not PAGE_MASK));
if ((QWORD(node.start) and PAGE_MASK) <> 0) or
((node.length and PAGE_MASK) <> 0) or
((node.protection and $c8) <> 0) or
(__end < QWORD(node.start)) then
begin
Result:=EINVAL;
Break;
end;
Result:=sys_mprotect(node.start,node.length,node.protection);
end; //SCE_KERNEL_MAP_OP_PROTECT
SCE_KERNEL_MAP_OP_MAP_FLEXIBLE:
begin
if ((QWORD(node.start) and PAGE_MASK) <> 0) or
((node.length and PAGE_MASK) <> 0) or
((node.protection and $c8) <> 0) then
begin
Result:=EINVAL;
Break;
end;
Result:=Integer(sys_mmap(node.start,
node.length,
node.protection,
flags or MAP_ANON,
-1,
0));
end; //SCE_KERNEL_MAP_OP_MAP_FLEXIBLE
SCE_KERNEL_MAP_OP_TYPE_PROTECT:
begin
__end:=QWORD(node.start) + node.length;
if (__end < QWORD(node.start)) or
(((__end + PAGE_MASK) and QWORD(not PAGE_MASK)) < __end) or
(DWORD(node.mtype) > 10) or
((node.protection and $c8) <> 0) then
begin
Result:=EINVAL;
Break;
end;
Result:=sys_mtypeprotect(node.start,node.length,node.mtype,node.protection);
end; //SCE_KERNEL_MAP_OP_TYPE_PROTECT
else
begin
Result:=EINVAL;
Break;
end;
end; //case
if (Result<>0) then Break;
end; //For
end;
if (numberOfEntriesOut<>nil) then
begin
suword32(PDWORD(numberOfEntriesOut)^,num_out);
end;
end;
function sys_get_page_table_stats(vm_container,cpu_gpu:Integer;p_total,p_available:PInteger):Integer;
begin
Exit(ENOENT); //devkit_parameter(0)=0