The Pedigree Project  0.1
hosted/ProcessorInformation.cc
1 /*
2  * Copyright (c) 2008-2014, Pedigree Developers
3  *
4  * Please see the CONTRIB file in the root of the source tree for a full
5  * list of contributors.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include "pedigree/kernel/processor/hosted/ProcessorInformation.h"
21 #include "pedigree/kernel/Log.h"
22 #include "pedigree/kernel/processor/Processor.h"
23 #include "pedigree/kernel/processor/types.h"
24 #include <processor/hosted/VirtualAddressSpace.h>
25 
26 namespace __pedigree_hosted
27 {
28 };
29 using namespace __pedigree_hosted;
30 
31 #include <errno.h>
32 #include <signal.h>
33 
34 extern void *safe_stack_top;
35 
37  ProcessorId processorId, uint8_t apicId)
38  : m_ProcessorId(processorId),
39  m_VirtualAddressSpace(&VirtualAddressSpace::getKernelAddressSpace()),
40 #ifdef THREADS
41  m_pCurrentThread(0), m_Scheduler(0),
42 #endif
43  m_KernelStack(0)
44 {
46 }
47 
49 {
50  delete m_Scheduler;
51 }
52 
54 {
56  return *m_VirtualAddressSpace;
57  else
59 }
60 
62  VirtualAddressSpace &virtualAddressSpace)
63 {
64  m_VirtualAddressSpace = &virtualAddressSpace;
65 }
66 
67 #ifdef THREADS
68 Thread *HostedProcessorInformation::getCurrentThread() const
69 {
70  return m_pCurrentThread;
71 }
72 
73 void HostedProcessorInformation::setCurrentThread(Thread *pThread)
74 {
75  m_pCurrentThread = pThread;
76 }
77 
78 PerProcessorScheduler &HostedProcessorInformation::getScheduler()
79 {
80  return *m_Scheduler;
81 }
82 #endif
83 
92 static bool trickSigaltstack(uintptr_t stack, stack_t *p)
93 {
94  if (!stack)
95  {
96  stack = reinterpret_cast<uintptr_t>(&safe_stack_top);
97  }
98 
99  int r = callOnStack(
100  stack, reinterpret_cast<uintptr_t>(sigaltstack),
101  reinterpret_cast<uintptr_t>(p));
102  if (r < 0)
103  {
104  WARNING("sigaltstack failed to set new stack");
105  return false;
106  }
107 
108  return true;
109 }
110 
111 void HostedProcessorInformation::setKernelStack(uintptr_t stack)
112 {
113  if (stack)
114  {
115  void *new_sp = reinterpret_cast<void *>(stack - KERNEL_STACK_SIZE);
116  stack_t s;
117  sigaltstack(0, &s);
118  if (s.ss_sp != new_sp)
119  {
120  ByteSet(&s, 0, sizeof(s));
121  s.ss_sp = new_sp;
122  s.ss_size = KERNEL_STACK_SIZE;
123  int r = sigaltstack(&s, 0);
124  if (r < 0 && errno == EPERM)
125  {
126  trickSigaltstack(stack, &s);
127  }
128  }
129  }
130  else if (!stack)
131  {
132  stack_t s;
133  sigaltstack(0, &s);
134  s.ss_flags |= SS_DISABLE;
135  int r = sigaltstack(&s, 0);
136  if (r < 0 && errno == EPERM)
137  {
138  trickSigaltstack(stack, &s);
139  }
140  }
141 
142  m_KernelStack = stack;
143 }
144 
145 uintptr_t HostedProcessorInformation::getKernelStack() const
146 {
147  return m_KernelStack;
148 }
VirtualAddressSpace * m_VirtualAddressSpace
static EXPORTED_PUBLIC VirtualAddressSpace & getKernelAddressSpace()
VirtualAddressSpace & getVirtualAddressSpace() const
void setVirtualAddressSpace(VirtualAddressSpace &virtualAddressSpace)
#define WARNING(text)
Definition: Log.h:78
size_t ProcessorId
Definition: Thread.h:54