changeset 215:37900976db8e

copyout
author tobaru
date Fri, 24 Jan 2020 18:57:05 +0900
parents 90b65036d9a2
children 408ea2236abc
files src/impl/vm_impl.cbc src/impl/vm_impl_private.cbc
diffstat 2 files changed, 28 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/impl/vm_impl.cbc	Fri Jan 24 18:33:52 2020 +0900
+++ b/src/impl/vm_impl.cbc	Fri Jan 24 18:57:05 2020 +0900
@@ -135,7 +135,7 @@
 
     vm->buf = (char*) pp;    
 
-    goto copyout_loopvm_impl(vm, pgdir, va, pp, len, next(...));
+    goto copyout_loopvm_impl(vm, pgdir, va, pp, len, va0, pa0, next(...));
 }
 
 __code paging_intvm_impl(struct vm_impl* vm, uint phy_low, uint phy_hi, __code next(...)) {
--- a/src/impl/vm_impl_private.cbc	Fri Jan 24 18:33:52 2020 +0900
+++ b/src/impl/vm_impl_private.cbc	Fri Jan 24 18:57:05 2020 +0900
@@ -330,9 +330,34 @@
     goto next(...);
 }
 
-__code copyout_loopvm_impl(struct vm_impl* vm_impl, pde_t* pgdir, uint va, void* pp, uint len, __code next(...)) {
+__code copyout_loopvm_impl(struct vm_impl* vm_impl, pde_t* pgdir, uint va, void* pp, uint len, uint va0, char* pa0,  __code next(int ret, ...)) {
+    if (len > 0) {
+        va0 = align_dn(va, PTE_SZ);
+        pa0 = uva2ka(pgdir, (char*) va0);
+        goto copyout_loop_check_pa0(vm_impl, pgdir, va, pp, len, va0, pa0, n, next(...));
+    }
+    ret = 0;
+    goto next(ret, ...);
 
-    goto next(...);
 }
 
+__code copyout_loop_check_pa0(struct vm_impl* vm_impl, pde_t* pgdir, uint va, void* pp, uint len, uint va0, char* pa0, uint n, __code next(int ret, ...)) {
+    if (pa0 == 0) {
+        ret = -1;
+        goto next(ret, ...);
+    }
+    goto copyout_loop_check_n(vm_impl, pgdir, va, pp, len, va0, pa0, n, buf, next(...));
+}
+__code copyout_loop_check_n(struct vm_impl* vm_impl, pde_t* pgdir, uint va, void* pp, uint len, uint va0, char* pa0, uint n, char* buf, __code next(...)) {
+    n = PTE_SZ - (va - va0);
 
+    if (n > len) {
+        n = len;
+    }
+
+    len -= n;
+    buf += n;
+    va = va0 + PTE_SZ;
+    goto copyout_loopvm_impl(vm_impl, pgdir, va, pp, len, va0, pa0, next(...));
+}
+