]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/ipc/ipc_pset.c
xnu-4570.20.62.tar.gz
[apple/xnu.git] / osfmk / ipc / ipc_pset.c
index 4dc635a062a1fc1b253a368bc9e260ce0655d49c..2fa71904dab4e769d187209e081a88c84af35ad5 100644 (file)
@@ -76,6 +76,7 @@
 #include <kern/kern_types.h>
 
 #include <vm/vm_map.h>
+#include <libkern/section_keywords.h>
 
 /*
  *     Routine:        ipc_pset_alloc
@@ -349,24 +350,26 @@ ipc_pset_destroy(
 #include <sys/event.h>
 #include <sys/errno.h>
 
-static int      filt_machportattach(struct knote *kn);
+static int      filt_machportattach(struct knote *kn, struct kevent_internal_s *kev);
 static void    filt_machportdetach(struct knote *kn);
 static int     filt_machport(struct knote *kn, long hint);
 static int     filt_machporttouch(struct knote *kn, struct kevent_internal_s *kev);
 static int     filt_machportprocess(struct knote *kn, struct filt_process_s *data, struct kevent_internal_s *kev);
 static unsigned filt_machportpeek(struct knote *kn);
-struct filterops machport_filtops = {
-        .f_attach = filt_machportattach,
-        .f_detach = filt_machportdetach,
-        .f_event = filt_machport,
-        .f_touch = filt_machporttouch,
-        .f_process = filt_machportprocess,
+SECURITY_READ_ONLY_EARLY(struct filterops) machport_filtops = {
+       .f_adjusts_qos = 1,
+       .f_attach = filt_machportattach,
+       .f_detach = filt_machportdetach,
+       .f_event = filt_machport,
+       .f_touch = filt_machporttouch,
+       .f_process = filt_machportprocess,
        .f_peek = filt_machportpeek,
 };
 
 static int
 filt_machportattach(
-        struct knote *kn)
+               struct knote *kn,
+               __unused struct kevent_internal_s *kev)
 {
        mach_port_name_t name = (mach_port_name_t)kn->kn_kevent.ident;
        uint64_t wq_link_id = waitq_link_reserve(NULL);
@@ -388,8 +391,10 @@ filt_machportattach(
 
                        __IGNORE_WCASTALIGN(pset = (ipc_pset_t)entry->ie_object);
                        mqueue = &pset->ips_messages;
+                       ips_reference(pset);
 
                        imq_lock(mqueue);
+                       kn->kn_ptr.p_mqueue = mqueue;
 
                        /*
                         * Bind the portset wait queue directly to knote/kqueue.
@@ -400,11 +405,15 @@ filt_machportattach(
                         */
                        error = knote_link_waitq(kn, &mqueue->imq_wait_queue, &wq_link_id);
                        if (!error) {
-                               ips_reference(pset);
-                               kn->kn_ptr.p_mqueue = mqueue; 
                                KNOTE_ATTACH(&mqueue->imq_klist, kn);
+                               imq_unlock(mqueue);
+
+                       }
+                       else {
+                               kn->kn_ptr.p_mqueue = IMQ_NULL;
+                               imq_unlock(mqueue);
+                               ips_release(pset);
                        }
-                       imq_unlock(mqueue);
 
                        is_read_unlock(space);
 
@@ -432,8 +441,10 @@ filt_machportattach(
                        kn->kn_ptr.p_mqueue = mqueue; 
                        KNOTE_ATTACH(&mqueue->imq_klist, kn);
                        if ((first = ipc_kmsg_queue_first(&mqueue->imq_messages)) != IKM_NULL) {
+                               int sync_qos_override_index = ipc_port_get_max_sync_qos_index(port);
                                if (kn->kn_sfflags & MACH_RCV_MSG)
-                                       knote_adjust_qos(kn, first->ikm_qos, first->ikm_qos_override);
+                                       knote_adjust_qos(kn, first->ikm_qos, first->ikm_qos_override,
+                                               sync_qos_override_index);
                                result = 1;
                        }
                        imq_unlock(mqueue);
@@ -528,8 +539,12 @@ filt_machport(
        } else if (imq_is_valid(mqueue)) {
                assert(!imq_is_set(mqueue));
                if ((first = ipc_kmsg_queue_first(&mqueue->imq_messages)) != IKM_NULL) {
+                       ipc_port_t port = ip_from_mq(mqueue);
+                       int sync_qos_override_index = ipc_port_get_max_sync_qos_index(port);
+
                        if (kn->kn_sfflags & MACH_RCV_MSG)
-                               knote_adjust_qos(kn, first->ikm_qos, first->ikm_qos_override);
+                               knote_adjust_qos(kn, first->ikm_qos, first->ikm_qos_override,
+                                       sync_qos_override_index);
                        result = 1;
                }
        }
@@ -564,13 +579,18 @@ filt_machporttouch(
         */
        if (imq_is_valid(mqueue) && !imq_is_set(mqueue) &&
            (first = ipc_kmsg_queue_first(&mqueue->imq_messages)) != IKM_NULL) {
+               ipc_port_t port = ip_from_mq(mqueue);
+               int sync_qos_override_index = ipc_port_get_max_sync_qos_index(port);
+
                if (kn->kn_sfflags & MACH_RCV_MSG)
-                       knote_adjust_qos(kn, first->ikm_qos, first->ikm_qos_override);
+                       knote_adjust_qos(kn, first->ikm_qos, first->ikm_qos_override,
+                               sync_qos_override_index);
                result = 1;
        } else if (kn->kn_sfflags & MACH_RCV_MSG) {
                knote_adjust_qos(kn,
                                 MACH_MSG_PRIORITY_UNSPECIFIED,
-                                MACH_MSG_PRIORITY_UNSPECIFIED);
+                                MACH_MSG_PRIORITY_UNSPECIFIED,
+                                THREAD_QOS_UNSPECIFIED);
        }
        imq_unlock(mqueue);
 
@@ -655,6 +675,7 @@ filt_machportprocess(
        self->ith_continuation = NULL;
        option |= MACH_RCV_TIMEOUT; // never wait
        self->ith_state = MACH_RCV_IN_PROGRESS;
+       self->ith_knote = kn;
 
        wresult = ipc_mqueue_receive_on_thread(
                        mqueue,