int memcpy_to_user(struct proc *p, void *dest, const void *src, size_t len) { uintptr_t prev = switch_to(p); int error = copy_to_user(dest, src, len); switch_back(p, prev); return error; }
int strcpy_to_user(struct proc *p, char *dst, const char *src) { uintptr_t prev = switch_to(p); int error = string_copy_to_user(dst, src); switch_back(p, prev); return error; }
static void bfin_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) { struct async_state *state = (struct async_state *)map->map_priv_1; switch_to_flash(state); memcpy(to, map->virt + from, len); switch_back(state); }
/* Writes the msg to the vcpd mbox of the vcore. If you want the private mbox, * send in the ev_flag EVENT_VCORE_PRIVATE. If not, the message could * be received by other vcores if the given vcore is offline/preempted/etc. * Whatever other flags you pass in will get sent to post_ev_msg. Currently, * the only one that will get looked at is NO_MSG (set a bit). * * This needs to load current (switch_to), but doesn't need to care about what * the process wants. Note this isn't commonly used - just the monitor and * sys_self_notify(). */ void post_vcore_event(struct proc *p, struct event_msg *msg, uint32_t vcoreid, int ev_flags) { /* Need to set p as current to post the event */ struct per_cpu_info *pcpui = &per_cpu_info[core_id()]; struct proc *old_proc = switch_to(p); /* *ev_mbox is the user address of the vcpd mbox */ post_vc_msg(p, vcoreid, get_vcpd_mbox(vcoreid, ev_flags), msg, ev_flags); switch_back(p, old_proc); }
static void bfin_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) { struct async_state *state = (struct async_state *)map->map_priv_1; switch_to_flash(state); memcpy(map->virt + to, from, len); SSYNC(); switch_back(state); }
static void bfin_write(struct map_info *map, map_word d1, unsigned long ofs) { struct async_state *state = (struct async_state *)map->map_priv_1; uint16_t d; d = d1.x[0]; switch_to_flash(state); writew(d, map->virt + ofs); SSYNC(); switch_back(state); }
static map_word bfin_read(struct map_info *map, unsigned long ofs) { struct async_state *state = (struct async_state *)map->map_priv_1; uint16_t word; map_word test; switch_to_flash(state); word = readw(map->virt + ofs); switch_back(state); test.x[0] = word; return test; }
/* Send an event to ev_q, based on the parameters in ev_q's flag. We don't * accept null ev_qs, since the caller ought to be checking before bothering to * make a msg and send it to the event_q. Vcoreid is who the kernel thinks the * message ought to go to (for IPIs). Appropriate for things like * EV_PREEMPT_PENDING, where we tell the affected vcore. To have the message go * where the kernel suggests, set EVENT_VCORE_APPRO(priate). */ void send_event(struct proc *p, struct event_queue *ev_q, struct event_msg *msg, uint32_t vcoreid) { struct proc *old_proc; struct event_mbox *ev_mbox = 0; assert(p); printd("[kernel] sending msg to proc %p, ev_q %p\n", p, ev_q); if (!ev_q) { warn("[kernel] Null ev_q - kernel code should check before sending!"); return; } if (!is_user_rwaddr(ev_q, sizeof(struct event_queue))) { /* Ought to kill them, just warn for now */ printk("[kernel] Illegal addr for ev_q\n"); return; } /* This should be caught by "future technology" that can tell when the * kernel PFs on the user's behalf. For now, we catch common userspace bugs * (had this happen a few times). */ if (!PTE_ADDR(ev_q)) { printk("[kernel] Bad addr %p for ev_q\n", ev_q); return; } /* ev_q is a user pointer, so we need to make sure we're in the right * address space */ old_proc = switch_to(p); /* If we're an _S, just spam vcore0, and wake up if necessary. */ if (!__proc_is_mcp(p)) { spam_vcore(p, 0, msg, ev_q->ev_flags); wrmb(); /* don't let the notif_pending write pass the state read */ /* using the same pattern as in spam_public (which can have multiple * unblock callbacks */ if (p->state == PROC_WAITING) proc_wakeup(p); goto out; } /* Get the vcoreid that we'll message (if appropriate). For INDIR and * SPAMMING, this is the first choice of a vcore, but other vcores might get * it. Common case is !APPRO and !ROUNDROBIN. Note we are clobbering the * vcoreid parameter. */ if (!(ev_q->ev_flags & EVENT_VCORE_APPRO)) vcoreid = ev_q->ev_vcore; /* use the ev_q's vcoreid */ /* Note that RR overwrites APPRO */ if (ev_q->ev_flags & EVENT_ROUNDROBIN) { /* Pick a vcore, round-robin style. Assuming ev_vcore was the previous * one used. Note that round-robin overrides the passed-in vcoreid. * Also note this may be 'wrong' if num_vcores changes. */ vcoreid = (ev_q->ev_vcore + 1) % p->procinfo->num_vcores; ev_q->ev_vcore = vcoreid; } if (!vcoreid_is_safe(vcoreid)) { /* Ought to kill them, just warn for now */ printk("[kernel] Vcoreid %d unsafe! (too big?)\n", vcoreid); goto out; } /* If we're a SPAM_PUBLIC, they just want us to spam the message. Note we * don't care about the mbox, since it'll go to VCPD public mboxes, and * we'll prefer to send it to whatever vcoreid we determined at this point * (via APPRO or whatever). */ if (ev_q->ev_flags & EVENT_SPAM_PUBLIC) { spam_public_msg(p, msg, vcoreid, ev_q->ev_flags & EVENT_SPAM_FLAGS); goto out; } /* We aren't spamming and we know the default vcore, and now we need to * figure out which mbox to use. If they provided an mbox, we'll use it. * If not, we'll use a VCPD mbox (public or private, depending on the * flags). */ ev_mbox = ev_q->ev_mbox; if (!ev_mbox) ev_mbox = get_vcpd_mbox(vcoreid, ev_q->ev_flags); /* At this point, we ought to have the right mbox to send the msg to, and * which vcore to alert (IPI/INDIR) (if applicable). The mbox could be the * vcore's vcpd ev_mbox. */ if (!ev_mbox) { /* This shouldn't happen any more, this is more for sanity's sake */ warn("[kernel] ought to have an mbox by now!"); goto out; } /* Even if we're using an mbox in procdata (VCPD), we want a user pointer */ if (!is_user_rwaddr(ev_mbox, sizeof(struct event_mbox))) { /* Ought to kill them, just warn for now */ printk("[kernel] Illegal addr for ev_mbox\n"); goto out; } /* We used to support no msgs, but quit being lazy and send a 'msg'. If the * ev_q is a NOMSG, we won't actually memcpy or anything, it'll just be a * vehicle for sending the ev_type. */ assert(msg); post_ev_msg(p, ev_mbox, msg, ev_q->ev_flags); wmb(); /* ensure ev_msg write is before alerting the vcore */ /* Prod/alert a vcore with an IPI or INDIR, if desired. INDIR will also * call try_notify (IPI) later */ if (ev_q->ev_flags & EVENT_INDIR) { send_indir(p, ev_q, vcoreid); } else { /* they may want an IPI despite not wanting an INDIR */ try_notify(p, vcoreid, ev_q->ev_flags); } /* Fall through */ out: /* Return to the old address space. */ switch_back(p, old_proc); }