Brandon Potter has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/12310

Change subject: syscall_emul: adding pipe2 syscall
......................................................................

syscall_emul: adding pipe2 syscall

pipe2 builds on top of the pipe syscall implementation by
adding some extra flags for the files (to avoid have to
make separate calls to fcntl).

Change-Id: I88cf6f1387b9d14e60b33a32db412da9ed93a3e6
---
M src/arch/x86/linux/process.cc
M src/sim/syscall_emul.cc
M src/sim/syscall_emul.hh
3 files changed, 62 insertions(+), 5 deletions(-)



diff --git a/src/arch/x86/linux/process.cc b/src/arch/x86/linux/process.cc
index ceaa4ba..2928fa7 100644
--- a/src/arch/x86/linux/process.cc
+++ b/src/arch/x86/linux/process.cc
@@ -520,7 +520,7 @@
     /* 290 */ SyscallDesc("eventfd2", eventfdFunc<X86Linux64>),
     /* 291 */ SyscallDesc("epoll_create1", unimplementedFunc),
     /* 292 */ SyscallDesc("dup3", unimplementedFunc),
-    /* 293 */ SyscallDesc("pipe2", unimplementedFunc),
+    /* 293 */ SyscallDesc("pipe2", pipe2Func),
     /* 294 */ SyscallDesc("inotify_init1", unimplementedFunc),
     /* 295 */ SyscallDesc("preadv", unimplementedFunc),
     /* 296 */ SyscallDesc("pwritev", unimplementedFunc),
diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc
index b9fe8e4..6d687ff 100644
--- a/src/sim/syscall_emul.cc
+++ b/src/sim/syscall_emul.cc
@@ -829,13 +829,18 @@
 }

 SyscallReturn
-pipeImpl(SyscallDesc *desc, int callnum, ThreadContext *tc, bool pseudoPipe) +pipeImpl(SyscallDesc *desc, int callnum, ThreadContext *tc, bool pseudo_pipe,
+         bool is_pipe2)
 {
     Addr tgt_addr = 0;
+    int flags = 0;
     auto p = tc->getProcessPtr();
-    if (!pseudoPipe) {
+    if (!pseudo_pipe) {
         int index = 0;
         tgt_addr = p->getSyscallArg(tc, index);
+        if (is_pipe2) {
+            flags = p->getSyscallArg(tc, index);
+        }
     }

     int sim_fds[2], tgt_fds[2];
@@ -847,10 +852,12 @@
     auto rend = PipeFDEntry::EndType::read;
     auto rpfd = std::make_shared<PipeFDEntry>(sim_fds[0], O_WRONLY, rend);
     tgt_fds[0] = p->fds->allocFD(rpfd);
+    int sim_fd_rpfd = rpfd->getSimFD();

     auto wend = PipeFDEntry::EndType::write;
     auto wpfd = std::make_shared<PipeFDEntry>(sim_fds[1], O_RDONLY, wend);
     tgt_fds[1] = p->fds->allocFD(wpfd);
+    int sim_fd_wpfd = wpfd->getSimFD();

     /**
* Now patch the read object to record the target file descriptor chosen
@@ -862,7 +869,7 @@
      * Alpha Linux convention for pipe() is that fd[0] is returned as
      * the return value of the function, and fd[1] is returned in r20.
      */
-    if (pseudoPipe) {
+    if (pseudo_pipe) {
         tc->setIntReg(SyscallPseudoReturnReg, tgt_fds[1]);
         return tgt_fds[0];
     }
@@ -879,6 +886,45 @@
     auto mem_state = p->memState;
     auto &virt_mem = mem_state->getVirtMem();
     tgt_handle.copyOut(virt_mem);
+
+    // pipe2 has additional behavior if flags != 0
+    if (is_pipe2 && flags) {
+ // pipe2 only uses O_NONBLOCK, O_CLOEXEC, and (O_NONBLOCK | O_CLOEXEC)
+        // if flags set to anything else, return EINVAL
+        if ((flags != O_CLOEXEC) && (flags != O_NONBLOCK) &&
+            (flags != (O_CLOEXEC | O_NONBLOCK))) {
+            return -EINVAL;
+        }
+
+        /*
+ If O_NONBLOCK is passed in as a flag to pipe2, set O_NONBLOCK file
+          status flag for two new open file descriptors.
+        */
+        if (flags & O_NONBLOCK) {
+            /*
+ O_NONBLOCK is set when the programmer wants to avoid a separate
+              call(s) to fcntl in their code, so mirror the fcntl
+ implementation for handling file descriptors -- rely on host to
+              maintain file status flags.
+            */
+            if (fcntl(sim_fd_rpfd, F_SETFL, O_NONBLOCK)) {
+                return -errno;
+            }
+            if (fcntl(sim_fd_wpfd, F_SETFL, O_NONBLOCK)) {
+                return -errno;
+            }
+        }
+
+        /*
+          If O_CLOEXEC is passed in as a flag to pipe2, set close-on-exec
+          (FD_CLOEXEC) file status flag for two new open file descriptors.
+        */
+        if (flags & O_CLOEXEC) {
+            rpfd->setCOE(true);
+            wpfd->setCOE(true);
+        }
+    }
+
     return 0;
 }

@@ -895,6 +941,14 @@
 }

 SyscallReturn
+pipe2Func(SyscallDesc *desc, int callnum, ThreadContext *tc)
+{
+    // call pipeImpl since the only difference between pipe and pipe2 is
+    // the flags values and what they do (at the end of pipeImpl)
+    return pipeImpl(desc, callnum, tc, false, true);
+}
+
+SyscallReturn
 setpgidFunc(SyscallDesc *desc, int callnum, ThreadContext *tc)
 {
     int index = 0;
diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh
index fc1b7ca..619cc04 100644
--- a/src/sim/syscall_emul.hh
+++ b/src/sim/syscall_emul.hh
@@ -267,7 +267,10 @@

 /// Internal pipe() handler.
 SyscallReturn pipeImpl(SyscallDesc *desc, int num, ThreadContext *tc,
-                       bool pseudoPipe);
+                       bool pseudo_pipe, bool is_pipe2=false);
+
+/// Target pipe() handler.
+SyscallReturn pipe2Func(SyscallDesc *desc, int num, ThreadContext *tc);

 /// Target getpid() handler.
 SyscallReturn getpidFunc(SyscallDesc *desc, int num, ThreadContext *tc);

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/12310
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: master
Gerrit-Change-Id: I88cf6f1387b9d14e60b33a32db412da9ed93a3e6
Gerrit-Change-Number: 12310
Gerrit-PatchSet: 1
Gerrit-Owner: Brandon Potter <[email protected]>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to